大数阶乘的一些经典问题解决

来源:互联网 发布:php java bridge 编辑:程序博客网 时间:2024/06/09 21:28

计算N!结果:首先实现利用字符串和vector<char>实现大数的加法:两个字符串从最低位开始相加,把相加的结果存到char类型容器中,注意在相加的过程中设置一个进位符,直到较短的字符串相加完毕;之后把进位符加到较长的字符串余位即可,在加的过程中同时注意的还是进位符的加法。最后如果进位符大于0则放入charvector中,这样生成的字符串是倒置的,需要reverse之后复制到字符串中返回即可。

下面利用字符串和容器实现大数乘法:中心思想就是乘法的本质就是加法,选择一个较短的数从个位开始和较长的数相乘,个位的时候就是把较长的数相加多次,若是十位便是相加多次后结果后面加一个0,百位加两个,一次类推,最后把结果相加就是最终结果。

 

求末尾0的个数:N!进行质因数分解: N!=2X*3Y*5Z…,因为10=2*5,所以M25的个数即XZ有关。每一对25都可以得到10,故M=min(X,Z)。因为能被2整除的数出现的频率要比能被5整除的数出现的频率高,所以M=ZZ =[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;elseAddOn=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;elseAddOn=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;elseAddOn=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;}


 

原创粉丝点击