计算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;
}