计算N!结果:首先实现利用字符串和vector<char>实现大数的加法:两个字符串从最低位开始相加,把相加的结果存到char类型容器中,注意在相加的过程中设置一个进位符,直到较短的字符串相加完毕;之后把进位符加到较长的字符串余位即可,在加的过程中同时注意的还是进位符的加法。最后如果进位符大于0则放入char的vector中,这样生成的字符串是倒置的,需要reverse之后复制到字符串中返回即可。
下面利用字符串和容器实现大数乘法:中心思想就是乘法的本质就是加法,选择一个较短的数从个位开始和较长的数相乘,个位的时候就是把较长的数相加多次,若是十位便是相加多次后结果后面加一个0,百位加两个,一次类推,最后把结果相加就是最终结果。
求末尾0的个数:对N!进行质因数分解: N!=2X*3Y*5Z…,因为10=2*5,所以M与2和5的个数即X、Z有关。每一对2和5都可以得到10,故M=min(X,Z)。因为能被2整除的数出现的频率要比能被5整除的数出现的频率高,所以M=Z。Z =[N/5] + [N/52]+ [N/53] + …
[N/5] 表示不大于N的的数中5的倍数贡献一个5, [N/52]表示不大于N的数中52的倍数在贡献一个5……(这里用到的一个想法就是,如果看n可以贡献多少个m,则使用n/m计算即可)
求N!使用二进制表示的时候最低位1的位置:判断最后一个二进制是否为0:若为0将二进制数右移1位(移位和除法运算),即为商;若为1,则说明这个数是奇数,不能被2整除。所以判断N!的二进制表示中最低位为1的位置的问题可以转换为求N!中含有质因数2的个数的问题。即位置为N!含有质因数2的个数加1.N!中含有质因数2的个数等于:[N/2]+[N/4]+[N/8]+…
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; string bigSum(string str1, string str2){ string result=""; int len1=str1.length(); int len2=str2.length(); int i,j,AddOn=0,sum; vector<char> vSum; vector<char>::iterator it; //注意“,”和“&&”运算符的区别,前者只返回 //最后一个表达式的结果(致命bug所在) for (i=len1-1,j=len2-1;i>=0 && j>=0;i--,j--){ sum=str1.at(i)-'0'+str2.at(j)-'0'+AddOn; if(sum>=10) AddOn=1; else AddOn=0; vSum.push_back(sum%10+'0'); } //分别处理两个字符串长度不相同时候的情况 //注意相等的时候不用处理 if(len1>len2) { for(;i>=0;i--){ sum=str1.at(i)-'0'+AddOn; if(sum>=10) AddOn=1; else AddOn=0; vSum.push_back(sum%10+'0'); } } else if(len2>len1) { for (;j>=0;j--){ sum=str2.at(j)-'0'+AddOn; if(sum>=10) AddOn=1; else AddOn=0; vSum.push_back(sum%10+'0'); } } if(AddOn>0) vSum.push_back(AddOn+'0'); reverse(vSum.begin(),vSum.end()); for (it=vSum.begin();it!=vSum.end();it++){ result+=*it; } return result; } string bigMul(string str1, string str2){ int len1=str1.length(); int len2=str2.length(); int i,j,k; string result="0"; if (len1<len2) { for(i=len1-1;i>=0;i--) { string tmpSum="0"; for (j=str1.at(i)-'0';j>0;j--) tmpSum=bigSum(str2,tmpSum); for(k=i;k<len1-1;k++) tmpSum.append("0"); result=bigSum(result,tmpSum); } } else { for (i=len2-1;i>=0;i--) { string tmpSum="0"; for(j=str2.at(i)-'0';j>0;j--) tmpSum=bigSum(str1,tmpSum); for(k=i;k<len2-1;k++) tmpSum.append("0"); result=bigSum(result,tmpSum); } } return result; } string fac(int n){ string res="1"; char ch[100]; for(int i=n;i>0;i--) res=bigMul(res,itoa(i,ch,10)); return res; } int countZero(int n){ int count=0; while (n/5!=0) { count+=n/5; n/=5; } return count; } int pos(int n){ int pos=0; while(n/2!=0){ pos+=n/2; n/=2; } return ++pos; } int main(){ string str1="12"; string str2="6"; int n=4; //string res=bigSum(str1,str2); //string res=bigMul(str1,str2); cout << fac(n) << endl; cout << countZero(n) << endl; cout << pos(n) << endl; return 0; }