美文网首页算法和数据结构
机试常用算法和题型-大数专题

机试常用算法和题型-大数专题

作者: DecadeHeart | 来源:发表于2020-04-25 16:41 被阅读0次

    大数专题

    字符加减关系,实现任意长度整数相加

    #include <iostream>
    #include <string>
    using namespace std;
    string Addition(string one, string two);
    int main()
    {
        int n, i;
        string first, second;
        cout << "Please enter two numbers: ";
        cin >> first >> second;
        cout << "The result is: " << Addition(first, second) << endl;
        //return 0;
        system("pause");
    }
    string Addition(string one, string two)
    {
        int j, max;
        //分别表示第一,二个字符串的长度
        int flen, slen;
        string sum;
        flen = one.size();
        slen = two.size();
        if(flen >= slen)
        {
            sum = one;
            for(j=0;j<slen;j++)
                sum[flen-j-1] = sum[flen-j-1] + two[slen-j-1] - '0';
            max = flen;
        }
        else
        {
            sum = two;
            for(j=0;j<flen;j++)
                sum[slen-j-1] = sum[slen-j-1] + one[flen-j-1] - '0';
            max = slen;
        }
        //如果第j位的数大于9,则将其减10,并向上一位进一
        for(j=max-1;j>=1;j--)
        {
            if(sum[j] > '9')
            {
                sum[j] -= 10;
                sum[j-1]++;
            }
        }
        if(sum[0] > '9')
        {
            sum[0] -= 10;
            sum = "1" + sum;
        }
        return sum;
    }
    

    大数加法,进阶转换版

    #include <iostream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    struct bign{
        int d[1000];
        int len;
        bign()
        {
            memset(d,0,sizeof(d));
            len=0;
        }
    };
    
    bign change(string s)
    {
        bign a;
        a.len=s.size();
        for(int i=0;i<a.len;i++)
        //将字符换成整型
        {
            a.d[i]=s[a.len-i-1]-'0';
        }
    
        return a;
    }
    
    bign add(bign a,bign b){
        bign c;
        int carry=0;
        //这里漏掉了i导致循环出错
        for(int i=0;i<a.len||i<b.len;i++){
            //还是转换成整数来计算更保险
            int temp=a.d[i]+b.d[i]+carry;
            c.d[c.len++]=temp%10;
            carry=temp/10;
        }
        //对于最后一个carry的处理!!我的分情况处理太low了
        if(carry!=0)
            c.d[c.len++]=carry;
        return c;
    }
    int main()
    {
        string str1,str2;
        while(cin>>str1>>str2){
            bign a=change(str1);
            bign b=change(str2);
            bign c=add(a,b);
            for(int i=c.len-1;i>=0;i--){
                cout<<c.d[i];
            }
            cout<<endl;
        }
        return 0;
    }
    

    大数浮点数加法

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct bign
    {
        int d[110];
        int len;
        bign()
        {
            memset(d,0,sizeof(d));
            len=0;
        }
    }big[110];
    void change(char s[],bign &a,bign &b)
    {
        int len=strlen(s),len1=0;
        for(int i=0;i<len;i++)
        {
            if(s[i]=='.')
                break;
            else
                len1++;
        }
        a.len=len1;
        for(int i=len1-1;i>=0;i--)
            a.d[len1-1-i]=s[i]-'0';
        b.len=len-len1-1;
        for(int i=len1+1;i<len;i++)
            b.d[i-len1-1]=s[i]-'0';
    }
    void trans(bign &a)
    {
        int s[110];
        for(int i=0;i<a.len;i++)
            s[i]=a.d[a.len-1-i];
        for(int i=0;i<a.len;i++)
            a.d[i]=s[i];
    }
    int add1(bign a,bign b,bign &c)
    {
        int carry=0,temp;
        for(int i=((a.len-1)>(b.len-1)?(a.len-1):(b.len-1));i>=0;i--)
        {
            temp=a.d[i]+b.d[i]+carry;
            c.d[c.len++]=temp%10;
            carry=temp/10;
        }
        trans(c);
        while(c.d[c.len-1]==0&&c.len>=2)
            c.len--;
        return carry;
    }
    void add2(bign a,bign b,bign &c,int carry)
    {
        int temp;
        for(int i=0;i<a.len||i<b.len;i++)
        {
            temp=a.d[i]+b.d[i]+carry;
            c.d[c.len++]=temp%10;
            carry=temp/10;
        }
        if(carry!=0)
            c.d[c.len++]=carry;
        while(c.d[c.len-1]==0&&c.len>=2)
            c.len--;
    }
    int main()
    {
        char a[110],b[110];
        int n;
        while(~scanf("%d",&n))
        {
            for(int i=0;i<n;i++)
            {
                bign a1,b1,c1,d1,e,f;
                scanf("%s",a);
                change(a,a1,b1);
                scanf("%s",b);
                change(b,c1,d1);
                int carry=add1(b1,d1,f);
                add2(a1,c1,e,carry);
                for(int j=e.len-1;j>=0;j--)
                    printf("%d",e.d[j]);
                printf(".");
                for(int j=0;j<f.len;j++)
                    printf("%d",f.d[j]);
                printf("\n");
                getchar();
            }
        }
        return 0;
    }
    

    大数运算之阶乘

    /*
    题目描述
    输入一个正整数N,输出N的阶乘。
    输入描述:
    正整数N(0<=N<=1000)
    输出描述:
    输入可能包括多组数据,对于每一组输入数据,输出N的阶乘
    示例1
    输入
    n的阶乘简单写法,王道机试写得太复杂
    */
    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxx = 5000;
    int str[maxx];
    void Cal(int n)
    {
        for (int i = 0; i<maxx; i++)str[i] = 0;
        //阶乘的初值赋值1,c是进位,由于改成数组装,所以进位加到下一位
        str[1] = 1; int j;
        int len = 1, c = 0;
        //用len来确定结果有几位
        for (int i = 2; i <= n; i++)
        {
            for (j = 1; j <= len; j++)
            {
                //终于懂了!!,没问题24*23可以拆成20*23+4*23而这个20的0可以去掉,因为用位置来表示了10进制
                str[j] = str[j] * i + c;
                c = str[j] / 10;
                str[j] = str[j] % 10;
    
            }
            while (c>0)
            {   //此时的j已经到len+1了。新开辟的一个点,要不停的往前放
                str[j] = c % 10;
                j++;
                c /= 10;
            }
            //j就是当前最远的一位的位置
            len = j - 1;
        }
        //然后从逆开始输出!!,终于看懂了
        for (int j = len; j >= 1; j--)
            cout << str[j];
        cout << "\n";
    }
    int main()
    {
        int n;
        while (cin >> n)
        {
            if (n == 0)printf("1\n");
            else Cal(n);
    
        }
    }
    //阶乘新写法
    #include <iostream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    int main()
    {
        int n;
        while(cin>>n){
            int cnt[1001];
            int len=1;
            cnt[0]=1;
            for(int i=1;i<=n;i++){
                int carry=0;
                for(int j=0;j<len;j++){
                    cnt[j]=cnt[j]*i+carry;
                    //终于知道问题了!!顺序不大对,cnt[j]先变了!!
                    carry=cnt[j]/10;
                    cnt[j]=cnt[j]%10;
    
                }
                if(carry!=0){
                 while(carry!=0){
                    cnt[len]=carry%10;
                    carry=carry/10;
                    len++;
                    }
                }
    
            }
            for(int i=len-1;i>=0;i--){
                cout<<cnt[i];
            }
            cout<<endl;
        }
    
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:机试常用算法和题型-大数专题

        本文链接:https://www.haomeiwen.com/subject/sbykwhtx.html