常考题型 大整数运算

最近刷题发现机试很喜欢考大整数运算,于是我自己写了几个大整数运算的函数。

可能写的不是很好,主要帮助自己理解原理。

代码:

#include <iostream>
#include <vector>

using namespace std;

vector<int> ToBigInt(string str){
    //将字符转换串转换成int向量
    vector<int> num;
    for(int i=0;i<str.size();i++)
        num.push_back(str[i]-'0');
    return num;
}

int compare(vector<int> num1,vector<int> num2){
    //比较大小,小于输出1,大于输出-1,等于输出0
    if(num1.size()<num2.size()) return 1;
    else if(num1.size()>num2.size()) return -1;
    else{
        for(int i=0;i<num1.size();i++){
            if(num1[i]<num2[i]) return 1;
            else if(num1[i]>num2[i]) return -1;
        }
        return 0;
    }
}

vector<int> Add(vector<int> num1,vector<int> num2){
    //加法运算

    //补零使得两数对齐
    if(num1.size()>num2.size())
        num2.insert(num2.begin(),num1.size()-num2.size(),0);
    else if(num1.size()<num2.size())
        num1.insert(num1.begin(),num2.size()-num1.size(),0);

    vector<int> num3;
    int ci=0;//进位
    for(int i=num1.size()-1;i>=0;i--){
        num3.insert(num3.begin(),(num1[i]+num2[i]+ci)%10);
        ci=(num1[i]+num2[i]+ci)/10;
    }
    if(ci!=0) num3.insert(num3.begin(),ci);//如果还有进位,插入结果头部
    return num3;
}

vector<int> Sub(vector<int> num1,vector<int> num2){
    //减法运算
    int sign=0;//标记结果符号
    if(compare(num1,num2)==1){//num1<num2则交换两数,同时标记结果为负
        swap(num1,num2);
        sign=1;
    }
    //补零使两数对齐
    if(num1.size()>num2.size())
        num2.insert(num2.begin(),num1.size()-num2.size(),0);
    else if(num1.size()<num2.size())
        num1.insert(num1.begin(),num2.size()-num1.size(),0);

    vector<int> num3;
    int carry=0;//借位
    for(int i=num1.size()-1;i>=0;i--){
        num3.insert(num3.begin(),(num1[i]+10-num2[i]-carry)%10);
        if(num1[i]-num2[i]-carry<0) carry=1;
        else carry=0;
    }
    //去掉前缀0
    int pos=0;
    while(num3[pos]==0)
        pos++;
    num3.erase(num3.begin(),num3.begin()+pos);
    //如果是负数加上负号
    if(sign==1) num3[0]=-num3[0];
    return num3;
}

vector<int> Mul(vector<int> num1,vector<int> num2){
    //乘法运算
    vector<int> num3(num1.size()+num2.size(),0);
    for(int i=num1.size()-1;i>=0;i--)//记录每位结果
        for(int j=num2.size()-1;j>=0;j--)
            num3[num3.size()-1-(num1.size()-1-i+num2.size()-1-j)]+=num1[i]*num2[j];
    for(int i=num3.size()-1;i>0;i--){//修改进位
        if(num3[i]>=10){
            num3[i-1]+=num3[i]/10;
            num3[i]=num3[i]%10;
        }
    }
    //去掉前缀0
    int pos=0;
    while(num3[pos]==0)
        pos++;
    num3.erase(num3.begin(),num3.begin()+pos);
    if(num3.size()==0) num3.push_back(0);
    return num3;
}

vector<int> Div(vector<int> num1,int num2,int &r){
    //除法运算,r表示余数,引用返回
    if((num1.size()==1 && num1[0]==0)){
        vector<int> zero;
        zero.push_back(0);
        return zero;
    }

    vector<int> num3;
    for(int i=0;i<num1.size();i++){
        r=r*10+num1[i];
        num3.push_back(r/num2);
        r=r%num2;
    }
    //去掉前缀0
    int pos=0;
    while(num3[pos]==0)
        pos++;
    num3.erase(num3.begin(),num3.begin()+pos);
    if(num3.size()==0) num3.push_back(0);
    return num3;
}

int main() {
    cout<<"输入两个大整数:";
    string str1, str2;
    cin >> str1 >> str2;

    vector<int> num1= ToBigInt(str1),num2= ToBigInt(str2);

    int CompareRes= compare(num1,num2);
    if(CompareRes==1) cout<<"num1<num2";
    else if(CompareRes==0) cout<<"num1=num2";
    else cout<<"num1>num2";
    cout<<endl;

    vector<int> AddRes= Add(num1,num2);
    cout<<"num1+num2=";
    for(int i=0;i<AddRes.size();i++) cout<<AddRes[i];
    cout<<endl;

    vector<int> SubRes= Sub(num1,num2);
    cout<<"num1-num2=";
    for(int i=0;i<SubRes.size();i++) cout<<SubRes[i];
    cout<<endl;

    vector<int> MulRes= Mul(num1,num2);
    cout<<"num1*num2=";
    for(int i=0;i<MulRes.size();i++) cout<<MulRes[i];
    cout<<endl;
    cout<<endl;

    cout<<"输入一个大整数被除数和一个小整数除数:";
    string str;
    cin>>str;
    getchar();
    int x;
    cin>>x;
    int r=0;
    vector<int> num= ToBigInt(str);
    vector<int> DivRes=Div(num,x,r);
    cout<<"num1/num2=";
    for(int i=0;i<DivRes.size();i++)
        cout<<DivRes[i];
    cout<<endl;
    cout<<"余数r="<<r<<endl;

}

运行结果:

全部评论
大整数运算真的很受机试欢迎。
点赞 回复 分享
发布于 2023-03-31 22:27 陕西
看不懂,果然是我太菜了
点赞 回复 分享
发布于 2023-03-31 21:57 山西

相关推荐

09-17 10:53
四川大学 C++
牛客91242815...:会写标书没有任何卵用,鉴定为横向垃圾导师的受害者
点赞 评论 收藏
分享
头像
10-13 18:10
已编辑
东南大学 C++
。收拾收拾心情下一家吧————————————————10.12更新上面不知道怎么的,每次在手机上编辑都会只有最后一行才会显示。原本不想写凉经的,太伤感情了,但过了一天想了想,凉经的拿起来好好整理,就像象棋一样,你进步最快的时候不是你赢棋的时候,而是在输棋的时候。那废话不多说,就做个复盘吧。一面:1,经典自我介绍2,项目盘问,没啥好说的,感觉问的不是很多3,八股问的比较奇怪,他会深挖性地问一些,比如,我知道MMU,那你知不知道QMMU(记得是这个,总之就是MMU前面加一个字母)4,知不知道slab内存分配器-&gt;这个我清楚5,知不知道排序算法,排序算法一般怎么用6,写一道力扣的,最长回文子串反问:1,工作内容2,工作强度3,关于友商的问题-&gt;后面这个问题问HR去了,和中兴有关,数通这个行业和友商相关的不要提,这个行业和别的行业不同,别的行业干同一行的都是竞争关系,数通这个行业的不同企业的关系比较微妙。特别细节的问题我确实不知道,但一面没挂我。接下来是我被挂的二面,先说说我挂在哪里,技术性问题我应该没啥问题,主要是一些解决问题思路上的回答,一方面是这方面我准备的不多,另一方面是这个面试写的是“专业面试二面”,但是感觉问的问题都是一些主管面/综合面才会问的问题,就是不问技术问方法论。我以前形成的思维定式就是专业面会就是会,不会就直说不会,但事实上如果问到方法论性质的问题的话得扯一下皮,不能按照上面这个模式。刚到位置上就看到面试官叹了一口气,有一些不详的预感。我是下午1点45左右面的。1,经典自我介绍2,你是怎么完成这个项目的,分成几个步骤。我大致说了一下。你有没有觉得你的步骤里面缺了一些什么,(这里已经在引导我往他想的那个方向走了),比如你一个人的能力永远是不够的,,,我们平时会有一些组内的会议来沟通我们的所思所想。。。。3,你在项目中遇到的最困难的地方在什么方面4,说一下你知道的TCP/IP协议网络模型中的网络层有关的协议......5,接着4问,你觉得现在的socket有什么样的缺点,有什么样的优化方向?6,中间手撕了一道很简单的快慢指针的问题。大概是在链表的倒数第N个位置插入一个节点。————————————————————————————————————10.13晚更新补充一下一面说的一些奇怪的概念:1,提到了RPC2,提到了fu(第四声)拷贝,我当时说我只知道零拷贝,知道mmap,然后他说mmap是其中的一种方式,然后他问我知不知道DPDK,我说不知道,他说这个是一个高性能的拷贝方式3,MMU这个前面加了一个什么字母我这里没记,别问我了4,后面还提到了LTU,VFIO,孩子真的不会。
走呀走:华子二面可能会有场景题的,是有些开放性的问题了
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务