各类大数模板
ps:转自http://blog.csdn.net/y990041769/article/details/20116995
大数加法模板(本人验证过,其他还没用,只是写在这)
1 string sum(string s1,string s2) 2 { 3 if(s1.length()<s2.length()) 4 { 5 string temp=s1; 6 s1=s2; 7 s2=temp; 8 } 9 int i,j; 10 for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--) 11 { 12 s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节 13 if(s1[i]-'0'>=10) 14 { 15 s1[i]=char((s1[i]-'0')%10+'0'); 16 if(i) s1[i-1]++; 17 else s1='1'+s1; 18 } 19 } 20 return s1; 21 }
大数乘法模版:
1 string Mult(string s,int x) //大数乘以整形数 2 { 3 reverse(s.begin(),s.end()); 4 int cmp=0; 5 for(int i=0;i<s.size();i++) 6 { 7 cmp=(s[i]-'0')*x+cmp; 8 s[i]=(cmp%10+'0'); 9 cmp/=10; 10 } 11 while(cmp) 12 { 13 s+=(cmp%10+'0'); 14 cmp/=10; 15 } 16 reverse(s.begin(),s.end()); 17 return s; 18 }
1 string Multstr(string str1,string str2){ //大数乘大数!!!之前贴的代码复杂度高了点,这个更低 2 3 string strResult = ""; 4 int len1 = str1.length(); 5 int len2 = str2.length(); 6 int num[500] = {0}; 7 for(int i=0;i<len1;i++){ 8 for(int j=0;j<len2;j++){ 9 num[len1-1-i+len2-1-j]+=(str1[i]-'0')*(str2[j]-'0'); 10 } 11 } 12 for(int i=0;i<len1+len2;i++){ 13 num[i+1]+=num[i]/10; 14 num[i]=num[i]%10; 15 } 16 int a=0; 17 for(int i=len1+len2-1;i>=0;i--){ 18 if(num[i]!=0){ 19 a=i;break; 20 } 21 } 22 for(int i=a;i>=0;i--){ 23 strResult += num[i]+'0'; 24 } 25 return strResult; 26 }
大数除法模板
string Except(string s,int x) //大数除以整形数 { int cmp=0,ok=0; string ans=""; for(int i=0;i<s.size();i++) { cmp=(cmp*10+s[i]-'0'); if(cmp>=x) { ok=1; ans+=(cmp/x+'0'); cmp%=x; } else{ if(ok==1) ans+='0'; //注意这里啊。才找出错误 } } return ans; }
浮点的N次方
1 string Multiply(string s,long x) //大数乘以整形数 2 { 3 reverse(s.begin(),s.end()); 4 long cmp=0; 5 for(int i=0; i<s.size(); i++) 6 { 7 cmp=(s[i]-'0')*x+cmp; 8 s[i]=(cmp%10+'0'); 9 cmp/=10; 10 } 11 while(cmp) 12 { 13 s+=(cmp%10+'0'); 14 cmp/=10; 15 } 16 reverse(s.begin(),s.end()); 17 return s; 18 } 19 string Remove_later(string s) //删除一个字符串的后倒0 20 { 21 int ok=1; 22 for(int i=s.size()-1; i>=0; i--) 23 { 24 if(s[i]=='0'){ 25 s.erase(i); 26 } 27 else if(s[i]=='.') 28 { 29 s.erase(i); 30 ok=0; 31 } 32 else 33 ok=0; 34 if(ok==0) 35 break; 36 } 37 return s; 38 } 39 string factorial(string s,int n) //浮点数的n次方 40 { 41 if(n==0) 42 return "1"; 43 string cmp="",count=""; 44 long x=0,point=0; 45 for(int i=0; i<s.size(); i++) 46 if(s[i]!='.') 47 { 48 cmp+=s[i]; 49 x=x*10+(s[i]-'0'); 50 } 51 else 52 point=s.size()-1-i; 53 for(int i=1; i<n; i++) 54 { 55 cmp=Multiply(cmp,x); 56 } 57 int ans_point=cmp.size()-n*point; 58 if(ans_point<0) 59 { 60 count+='.'; 61 for(int i=ans_point; i!=0; i++) 62 count+='0'; 63 } 64 string::iterator it=cmp.begin(); 65 if(ans_point>=0&&ans_point<cmp.size()) 66 cmp.insert(it+ans_point,'.'); 67 count+=(Remove_later(cmp)); 68 return count; 69 }
字符串去除后导0函数,前导0可以先反转取后导。
1 string Remove_later(string s) //删除一个字符串的后倒0 2 { 3 for(int i=s.size()-1; i>=0; i--) 4 { 5 if(s[i]=='0') 6 s.erase(i); 7 else 8 break; 9 } 10 return s; 11 }
大整数开方:
思路一:来源:http://blog.csdn.net/wlxsq/article/details/50812680
给定一个数n,它的位数是Len,如果len为偶数,则他的平方根的位数为len/2.如果len为奇数,那么它的平方根的位数为len/2+1.
知道了位数之后,即可从高位到低位计算平方根。比如要求250的平方根。平方根的位数为2.
首先求最高位
10*10=100<250
20*20=400>250(故最高位为1)
再求次高位
11*11=121<250
12*12=144<250
。。。。。
15*15=225<250
16*16=256>250(故次高位为5)
结果为15.
以此类推,直到求到最低位。
思路二:前面和思路一 一样,关键在于不用遍历每一位,比如平方根为四位数,则从1000~9999进行二分查找。
思路一的模板:
1 string Big_sqrt(string a){ 2 int alen =a.length(); 3 string asqrt=""; 4 if(alen%2==0){ 5 for(int i=0;i<alen/2;i++){ 6 asqrt+="0"; 7 } 8 }else{ 9 for(int i=0;i<alen/2+1;i++){ 10 asqrt+="0"; 11 } 12 } 13 int now=0; 14 string sum1,sum2; 15 sum1=Multstr(asqrt,asqrt); 16 while( alen%2==0 ? now!=alen/2 : now!=alen/2+1){ 17 string tmp1=asqrt; 18 for(int i=0;i<9;i++){ 19 tmp1[now]=tmp1[now]+1; 20 sum2=Multstr(tmp1,tmp1); 21 if(sum1==a){ 22 return asqrt; 23 } 24 if(sum1<=a&&sum2>a&&sum2.length()==a.length()){ 25 break; 26 } 27 if(sum1<=a&&sum2.length()>a.length()){ 28 break; 29 } 30 asqrt=tmp1; 31 sum1=sum2; 32 } 33 now++; 34 } 35 return asqrt; 36 }