大数问题

 一:大数加法

1)

模板:

string sum(string s1,string s2) 
{ 
  if(s1.length()<s2.length()) 
  { 
    string temp=s1; 
    s1=s2; 
    s2=temp; 
  } 
  int i,j; 
  for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--) 
  { 
    s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节 
    if(s1[i]-'0'>=10) 
    { 
      s1[i]=char((s1[i]-'0')%10+'0'); 
      if(i) s1[i-1]++; 
      else s1='1'+s1; 
    } 
} 
  return s1; 
}

test:

#include <iostream> 
#include <string> 
#include <cstdio> 
using namespace std; 
string sum(string s1,string s2) 
{ 
  f(s1.length()<s2.length()) 
  { 
    string temp=s1; 
    s1=s2; 
    s2=temp; 
  } 
  int i,j; 
  for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--) 
  { 
    s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节 
    if(s1[i]-'0'>=10) 
    { 
      s1[i]=char((s1[i]-'0')%10+'0'); 
      if(i)

        s1[i-1]++; 
      else

        s1='1'+s1; 
    }      
  } 
  return s1;    
} 
int main() 
{ 
  int n,T; 
  scanf("%d",&T); 
  while(T--) 
  { 
    string s;cin>>s; 
    if(s.size()==1)

    { 
      printf("1
");continue; 
    } 
    else if(s.size()==2) 
    { 
      printf("2
");continue; 
    } 
    string ans,a="1",b="2"; 
    for(int i=3;i<=s.size();i++) 
    { 
      ans=sum(a,b); 
      a=b; 
      b=ans; 
    } 
    cout<<b<<endl; 
  }    
  return 0; 
}

2)大数加减执行完毕后再对储存结果的result数组进行一次性进位(因为每位中两个十一上的数相加最多只进行一位累计结果不会造成数据范围溢出)

eg:

             8 1 3 5 7 3 8 7 2 5 8 9 7 1
+        3 2 9 4 8 1 3 0 9 1 8 9 0 4 9 5 0 1 8

= 3 2 9 4 8 9 4 3 (14) 8(11)(17)7 6(14)(13) 9 8 9
最后进位,得:
      3 2 9 4 8 9 4 4 4 9 2 7 7 7 5 3 9 8 9

 code:

#include <iostream>
using namespace std;

int a[1000],b[1000],result[1000];
int main()
{
  int t,i=1;
  while(cin>>t)
  a[i++]=t;  cin.clear();

  cin.sync();

  int j=1;
  while(cin>>t)
  b[j++]=t;
  
  int k,flag;
  if(i>j)
  {

     int len=i-j; 
     for(flag=k=i-1;k>=0;--k)
      result[k]=a[k]+b[k-len];

  } 
  else if(i<j)
  {

    int len=j-i; 
    for(flag=k=j-1;k>=0;--k)
      result[k]=b[k]+a[k-len];

  }
  else
  {
    for(flag=k=j-1;k>=0;--k)
      result[k]=b[k]+a[k];
  }

  for(int s=flag;s>=1;--s)
  {
    if(result[s]>9)
    {
      int t=result[s]%10;
      if(s-1)
        result[s-1]+=result[s]/10; 
      else
        result[s-1]=result[s]/10;
      result[s]=t;
    }
  }

  for(int s=0;s<=flag;++s)
    cout<<result[s];
  cout<<endl;
  return 0;
}

3)

#include <stdio.h>
int main()
{
  char a[1001],b[1001],c[1002];
  int i,j,k,l;
  while(scanf("%s%s",a,b))
  {
    for(i=0;a[i];i++);
    for(j=0;b[j];j++); //把指针调整到加数、被加数最后一位,从个位数开始加

    for(k=c[1001]=0,l=1000;i||j||k;l--) //把相加结果从c[1000]--c[0]存储
    {
      c[l]=(i?a[i-1]:'0')+(j?b[j-1]:'0')+k-'0'; //做加法:A+b+进位
      k=0;
      if(c[l]>'9')
      {
        k=1;
        c[l]-=10; //处理进位
      }
      if(i)
        i--;
      if(j)
        j--;
    }
    printf("%s
",&c[l+1]);
  }
   return 0;
}

 4)一个简单的进位模板

int digit=0,num[1000][1000];

for(int i=1;i<n;++i)//第几个数 
{
  int temp,rem;//rem代表余数,每次计算余数初始化为0 
  rem=0;
  for(int j=0;j<digit;++j)
  {
    temp=num[i-1][j]+num[i-2][j]+rem;
    num[i][j]=temp%10;
    rem=temp/10;
  }
   while(rem)//如果j>digit且rem余数不为0,就代表向高位有进位, 
    {
      num[i][digit]=rem%10;//可能进位的数字较大不止一次进位,尝试多次处理 
      rem/=10;
      digit++;
    }
}

二:大数乘法

如果两个大数为le1000,则乘机最大位数是le(1000+1000);,也就是长度两千的说数组。Max=2000即可。

在大数乘法的过程中定义一个中间过程的2维数组,执行完毕后对每一列进行求和,得到结果,最后再对

存储结果的result数组进行一次进位。

code:

#include <iostream>
#include <algorithm>
using namespace std;

class Solution
{
public:
    string multiply(string num1, string num2)
    {
        if(num1.empty()||num2.empty())
            return "";
        if(num1=="0"||num2=="0")
            return "0";

        vector<int> res(num1.size()+num2.size());
        for(int i=0,ii=num1.size()-1;i<num1.size(),ii>=0;++i,--ii)
        {
            for(int j=0,jj=num2.size()-1;j<num2.size(),jj>=0;++j,--jj)
            {
                int sum_ij=i+j;
                int tmp=(num1.at(ii)-'0')*(num2.at(jj)-'0')+res.at(sum_ij);
                res.at(sum_ij)=tmp%10;
                res.at(sum_ij+1)+=tmp/10;
            }
        }

        string result;
        for(auto i:res)
            result=to_string(i).append(result);
        if(result.at(0)=='0')
            return result.substr(1);
        return result;
    }
};
int main()
{
    Solution s;
    string res(s.multiply("123","456"));
    cout<<res<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/tianzeng/p/9020822.html