博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[算法系列之八]大数问题(高精度运算)
阅读量:7102 次
发布时间:2019-06-28

本文共 11170 字,大约阅读时间需要 37 分钟。

【大数相加】

【代码一】
/**********************************   日期:2015-01-28*   作者:SJF0115*   题目: 大数加法(高精度加法)*   博客:**********************************/#include 
using namespace std;string AddString(string num1,string num2){ int len1 = num1.length(); int len2 = num2.length(); // 容错处理 if(len1 <= 0){ return num2; }//if if(len2 <= 0){ return num1; } string result; int i = len1-1,j = len2-1; int a,b,sum,carry = 0; // 倒序相加 while(i >= 0 || j >= 0 || carry > 0){ a = i >= 0 ? num1[i] - '0' : 0; b = j >= 0 ? num2[j] - '0' : 0; // 按位相加并加上进位 sum = a + b + carry; // 进位 carry = sum / 10; result.insert(result.begin(),sum % 10 + '0'); --i; --j; }//while return result;}int main(){ string num1("72"); string num2("874"); string result = AddString(num1,num2); // 输出 cout<
<
【代码二】
/**********************************   日期:2015-01-28*   作者:SJF0115*   题目: 大数加法(高精度加法)*   博客:**********************************/#include 
using namespace std;string AddString(string num1,string num2){ int len1 = num1.length(); int len2 = num2.length(); int max = len1 > len2 ? (len1 + 2) : (len2 + 2); char* result = new char[max]; int index = 0; int i = len1 - 1,j = len2 - 1; int numA,numB,carry = 0,sum = 0; //加法 while(i >= 0 || j >= 0 || carry > 0){ numA = i >= 0 ? (num1[i] - '0') : 0; numB = j >= 0 ? (num2[j] - '0') : 0; sum = numA + numB + carry; carry = sum / 10; result[index++] = sum % 10 + '0'; --i; --j; }//while result[index] = '\0'; //反转 for(i = 0,j = index - 1;i < j;++i,--j){ char temp = result[i]; result[i] = result[j]; result[j] = temp; }//for return string(result);}int main(){ string num1("872"); string num2("874"); string result = AddString(num1,num2); // 输出 cout<
<
【代码三】

[cpp] 
  1. #include<stdio.h>  
  2. #include<string.h>  
  3.   
  4. char a[10001],b[10001],sum[10002];  
  5.   
  6. int BigIntegerAdd(){  
  7.     //两个数的长度  
  8.     int lena = strlen(a);  
  9.     int lenb = strlen(b);  
  10.     //进位标记  
  11.     int c = 0;  
  12.     int i,j,k;  
  13.     //初始化数组sum  
  14.     memset(sum,0,10001);  
  15.     //倒序相加  
  16.     k = 0;  
  17.     for(i = lena-1,j = lenb-1;i >= 0 && j >= 0;i--,j--){  
  18.         sum[k] = a[i] + b[j] - '0' + c;  
  19.         c = 0;  
  20.         //如果相加大于等于10  
  21.         if(sum[k] > '9'){  
  22.             sum[k] -= 10;  
  23.             c = 1;  
  24.         }  
  25.         k++;  
  26.     }  
  27.     //a > b  
  28.     while(i >= 0){  
  29.         sum[k] = a[i] + c;  
  30.         c = 0;  
  31.         //如果相加大于等于10  
  32.         if(sum[k] > '9'){  
  33.             sum[k] -= 10;  
  34.             c = 1;  
  35.         }  
  36.         k++;  
  37.         i--;  
  38.     }  
  39.     //b > a  
  40.     while(j >= 0){  
  41.         sum[k] = b[j] + c;  
  42.         c = 0;  
  43.         //如果相加大于等于10  
  44.         if(sum[k] > '9'){  
  45.             sum[k] -= 10;  
  46.             c = 1;  
  47.         }  
  48.         k++;  
  49.         j--;  
  50.     }  
  51.     //如果最后两个数相加有进位的情况  
  52.     //例如:67 + 51:5+6有进位  
  53.     if(c == 1){  
  54.         sum[k++] = '1';  
  55.     }  
  56.     //翻转  
  57.     char temp;  
  58.     for(i = 0,j = k-1;i < j;i++,j--){  
  59.         temp = sum[i];  
  60.         sum[i] = sum[j];  
  61.         sum[j] = temp;  
  62.     }  
  63.     return 0;  
  64. }  
  65.   
  66. int main(){  
  67.     while(scanf("%s %s",a,b) != EOF){  
  68.         BigIntegerAdd();  
  69.         puts(sum);  
  70.     }  
  71. }  

【大数相减】

【代码一】
string MinusString(string num1, string num2) {    int len1 = num1.length();    int len2 = num2.length();    // 相等    if(num1 == num2){        return "0";    }//if    // 正负    bool positive = true;    if(len1 < len2 || (len1 == len2 && num1 < num2)){        positive = false;        // 交换使之num1 > num2        string tmp = num1;        num1 = num2;        num2 = tmp;        int temp = len1;        len1 = len2;        len2 = temp;    }//if    string result;    int i = len1 - 1,j = len2 - 1;    int a,b,sum,carray = 0;    // 从低位到高位对位做减法    while(i >= 0 || j >= 0){        a = i >= 0 ? num1[i] - '0' : 0;        b = j >= 0 ? num2[j] - '0' : 0;        sum = a - b + carray;        carray = 0;        // 不够减        if(sum < 0){            sum += 10;            carray = -1;        }//if        result.insert(result.begin(),sum + '0');        --i;        --j;    }//while    // 删除前导0    string::iterator it = result.begin();    while(it != result.end() && *it == '0'){        ++it;    }//while    result.erase(result.begin(),it);    return positive ? result : "-"+result;}
【代码二】

[cpp] 
  1. /* 
  2. 1.比较减数与被减数的长度,确定正负号 
  3. 2.模拟减法运算 
  4.     (1)a[i] == b[j]  
  5.     (2)a[i] < b[j] //借位 
  6.     (3)a[i] > b[j]  
  7.  */  
  8. #include<stdio.h>  
  9. #include<string.h>  
  10.   
  11. char a[10001],b[10001],sum[10001],temp[10001];  
  12.   
  13. int BigIntegerMinus(){  
  14.     //两个数的长度  
  15.     int lena = strlen(a);  
  16.     int lenb = strlen(b);  
  17.     //借位标记  
  18.     int c = 0;  
  19.     int i,j,k,positive = 1;  
  20.     //判断正负号  
  21.     if(lena < lenb || (lena == lenb && strcmp(a,b) < 0) ){  
  22.         strcpy(temp,a);  
  23.         strcpy(a,b);  
  24.         strcpy(b,temp);  
  25.         positive = -1;//负号  
  26.         lena = strlen(a);  
  27.         lenb = strlen(b);  
  28.     }  
  29.     //倒序相减   
  30.     k = 0;    
  31.     for(i = lena-1,j = lenb-1;i >= 0 && j >= 0;i--,j--){    
  32.         sum[k] = a[i] - b[j] + '0' + c;    
  33.         c = 0;    
  34.         //如果相减小于0    
  35.         if(sum[k] < '0'){    
  36.             sum[k] += 10;    
  37.             c = -1;    
  38.         }    
  39.         k++;    
  40.     }    
  41.     //a > b    
  42.     while(i >= 0){    
  43.         sum[k] = a[i] + c;    
  44.         c = 0;    
  45.         //如果相减小于0    
  46.         if(sum[k] < '0'){    
  47.             sum[k] += 10;    
  48.             c = -1;    
  49.         }    
  50.         k++;    
  51.         i--;    
  52.     }    
  53.     //b > a    
  54.     while(j >= 0){    
  55.         sum[k] = b[j] + c;    
  56.         c = 0;    
  57.         //如果相减小于0    
  58.         if(sum[k] < '0'){    
  59.             sum[k] += 10;    
  60.             c = -1;    
  61.         }    
  62.         k++;    
  63.         j--;    
  64.     }  
  65.     int index = k - 1;  
  66.     //检索高位,有可能相减为0  
  67.     while(sum[index] == '0' && index > 0){  
  68.         index--;  
  69.     }  
  70.     //正号  
  71.     if(positive == 1){  
  72.         sum[index+1] = '\0';  
  73.     }  
  74.     //负号  
  75.     else{  
  76.         sum[++index] = '-';  
  77.         sum[index+1] = '\0';  
  78.     }  
  79.     //翻转  
  80.     char t;  
  81.     for(i = 0,j = index;i < j;i++,j--){  
  82.         t = sum[i];  
  83.         sum[i] = sum[j];  
  84.         sum[j] = t;  
  85.     }  
  86.     return 0;  
  87. }  
  88.   
  89. int main(){  
  90.     while(scanf("%s %s",a,b) != EOF){  
  91.         BigIntegerMinus();  
  92.         puts(sum);  
  93.     }  
  94. }  

【大数乘法】

【代码一】
/**********************************   日期:2015-01-28*   作者:SJF0115*   题目: 高精度乘法(大数乘法)*   博客:**********************************/#include 
#include
using namespace std;string MultiplyString(string num1, string num2) { int len1 = num1.length(); int len2 = num2.length(); // 容错处理 if(len1 <= 0 || len2 <= 0){ return ""; }//if int sum = 0; int len3 = len1 + len2; char result[len3]; memset(result,'0',sizeof(result[0])*(len3+1)); for(int i = len1 - 1,m = 0;i >= 0;--i,++m){ for(int j = len2 - 1,n = 0;j >= 0;--j,++n){ sum = (num1[i] - '0') * (num2[j] - '0') + result[m+n] - '0'; result[m+n] = sum % 10 + '0'; // 进位 result[m+n+1] += sum / 10; }//for }//for //去掉前导0 确定乘积的位数 while(result[len3] == '0' && len3 > 0){ --len3; }//while //注意:加'\0' result[len3+1] = '\0'; //翻转 int temp; for(int i = 0,j = len3;i < j;++i,--j){ temp = result[i]; result[i] = result[j]; result[j] = temp; }//for return string(result);}int main(){ string num1("2"); string num2("123"); string result = MultiplyString(num1,num2); // 输出 cout<
<
【代码二】

[cpp] 
  1. #include<stdio.h>  
  2. #include<string.h>  
  3.   
  4. char a[10001],b[10001],c[20002];  
  5.   
  6. int BigIntegerMulti()  
  7. {  
  8.     int i,j,lena,lenb,lenc;  
  9.     //初始化  
  10.     memset(c,'0',20002);  
  11.     //两个数的长度  
  12.     lena = strlen(a);  
  13.     lenb = strlen(b);  
  14.     //乘积最大位数  
  15.     lenc = lena + lenb - 1;  
  16.     //翻转    
  17.     char temp;    
  18.     for(i = 0,j = lena-1;i < j;i++,j--){    
  19.         temp = a[i];    
  20.         a[i] = a[j];    
  21.         a[j] = temp;    
  22.     }    
  23.     for(i = 0,j = lenb-1;i < j;i++,j--){    
  24.         temp = b[i];    
  25.         b[i] = b[j];    
  26.         b[j] = temp;    
  27.     }   
  28.     //倒序相乘  
  29.     /* 
  30.           123 
  31.         *  54 
  32.         ------ 
  33.           492 
  34.          615 
  35.         ----- 
  36.          6642  
  37.     */  
  38.     int t;  
  39.     for(i = 0;i < lena;i++){  
  40.         for(j = 0;j < lenb;j++){  
  41.             /* c[i+j] = (a[i] - '0') * (b[j] - '0') + c[i+j];  
  42.                9 * 9 + '0' 超出char范围越界所以设置一个int临时变量t    */  
  43.             t = (a[i] - '0') * (b[j] - '0') + c[i+j] - '0';  
  44.             //进位  
  45.             c[i+j+1] = t / 10 + c[i+j+1];  
  46.             c[i+j] = t % 10 + '0';  
  47.         }  
  48.     }  
  49.     //确定乘积的位数  
  50.     while(c[lenc] == '0' && lenc >0){  
  51.         lenc--;  
  52.     }  
  53.     //注意:加'\0'  
  54.     c[lenc+1] = '\0';  
  55.     //翻转  
  56.     for(i = 0,j = lenc;i < j;i++,j--){    
  57.         temp = c[i];    
  58.         c[i] = c[j];    
  59.         c[j] = temp;    
  60.     }   
  61.     return 0;  
  62. }  
  63.   
  64. int main(){  
  65.     while(scanf("%s %s",a,b) != EOF){  
  66.         BigIntegerMulti();  
  67.         puts(c);  
  68.     }  
  69.     return 0;  
  70. }  

【代码三】

/**********************************   日期:2015-01-29*   作者:SJF0115*   题目: Karatsuba快速相乘算法*   博客:**********************************/#include 
#include
#include
using namespace std;// given two unequal sized bit strings, converts them to// same length by adding leading 0s in the smaller string. Returns the// the new lengthint MakeSameLen(string& num1,string& num2){ int len1 = num1.length(); int len2 = num2.length(); if(len1 < len2){ for(int i = 0;i < len2 - len1;++i){ num1 = "0" + num1; }//for return len2; }//if else{ for(int i = 0;i < len1 - len2;++i){ num2 = "0" + num2; }//for return len1; }//else}// big number minus functionstring MinusString(string num1, string num2) { int len1 = num1.length(); int len2 = num2.length(); // 相等 if(num1 == num2){ return "0"; }//if // 正负 bool positive = true; if(len1 < len2 || (len1 == len2 && num1 < num2)){ positive = false; // 交换使之num1 > num2 string tmp = num1; num1 = num2; num2 = tmp; int temp = len1; len1 = len2; len2 = temp; }//if string result; int i = len1 - 1,j = len2 - 1; int a,b,sum,carray = 0; // 从低位到高位对位做减法 while(i >= 0 || j >= 0){ a = i >= 0 ? num1[i] - '0' : 0; b = j >= 0 ? num2[j] - '0' : 0; sum = a - b + carray; carray = 0; // 不够减 if(sum < 0){ sum += 10; carray = -1; }//if result.insert(result.begin(),sum + '0'); --i; --j; }//while // 删除前导0 string::iterator it = result.begin(); while(it != result.end() && *it == '0'){ ++it; }//while result.erase(result.begin(),it); return positive ? result : "-"+result;}// big number add functionstring AddString(string num1,string num2){ int len1 = num1.length(); int len2 = num2.length(); // 容错处理 if(len1 <= 0){ return num2; }//if if(len2 <= 0){ return num1; } string result; int i = len1-1,j = len2-1; int a,b,sum,carry = 0; // 倒序相加 while(i >= 0 || j >= 0 || carry > 0){ a = i >= 0 ? num1[i] - '0' : 0; b = j >= 0 ? num2[j] - '0' : 0; // 按位相加并加上进位 sum = a + b + carry; // 进位 carry = sum / 10; result.insert(result.begin(),sum % 10 + '0'); --i; --j; }//while return result;}// 移位string ShiftString(string num,int len){ if(num == "0"){ return num; }//if for(int i = 0;i < len;++i){ num += "0"; }//for return num;}// Karatsuba快速相乘算法string KaratsubaMultiply(string num1, string num2) { int len = MakeSameLen(num1,num2); if(len == 0){ return 0; }//if // all digit are one if(len == 1){ return to_string((num1[0] - '0')*(num2[0] - '0')); }//if int mid = len / 2; // Find the first half and second half of first string. string x1 = num1.substr(0,mid); string x0 = num1.substr(mid,len - mid); // Find the first half and second half of second string string y1 = num2.substr(0,mid); string y0 = num2.substr(mid,len - mid); // Recursively computer string z0 = KaratsubaMultiply(x0,y0); string z1 = KaratsubaMultiply(AddString(x1,x0),AddString(y1,y0)); string z2 = KaratsubaMultiply(x1,y1); // (z2*10^(2*m))+((z1-z2-z0)*10^(m))+(z0) // z2*10^(2*m) string r1 = ShiftString(z2,2*(len - mid)); // (z1-z2-z0)*10^(m) string r2 = ShiftString(MinusString(MinusString(z1,z2),z0),len - mid); return AddString(AddString(r1,r2),z0);}int main(){ string num1("12345001"); string num2("1006789"); string result = KaratsubaMultiply(num1,num2); // 输出 cout<
<

自己写的如有问题,请告知一下。

转载地址:http://jwyhl.baihongyu.com/

你可能感兴趣的文章
HDU——2067 小兔的棋盘
查看>>
我的友情链接
查看>>
【Java基础】 Java跳转页面的两种方法以及它们的区别
查看>>
Oracle RMAN 的 show,list,crosscheck,delete命令整理
查看>>
[MySQL]-->查询5天之内过生日的同事中的闰年2月29日问题的解决过程
查看>>
系统基础之用户管理作业题
查看>>
CentOS系统安装中文man手册
查看>>
Windows Server 2012活动目录域服务部署
查看>>
检测sshd端口误封脚本
查看>>
ps查询进程
查看>>
Linux两块磁盘挂载指向一个文件夹LVM磁盘管理(三)
查看>>
使用消息队列的 10 个理由
查看>>
WSUS服务器的详细配置和部署
查看>>
Python.Unix和Linux系统管理指--第二章(读书笔记)
查看>>
【XP配置××× 及 经常遇到的问题(二)】
查看>>
海量存储之十七–一致性和高可用专题
查看>>
Red Hat Linux 安装及服务控制
查看>>
备份利器Rsync应用详解
查看>>
undefined reference to `libiconv_open 无法编译PHP
查看>>
用MDT 2012为企业部署windows 7(八)--部署windows 7旗舰版(光盘版,非模板部署)...
查看>>