zoukankan      html  css  js  c++  java
  • 算法学习(一)(大数运算)(大数相加、大数相减、大数相乘、大数相除(取模、取余)、大数阶乘(求位数、求值))

    一、大数相乘

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    int main()
    {
    	char chr1[100],chr2[100];
    	int len1,len2;
    	while(scanf("%s %s",chr1,chr2))
    	{
    		int i,j=0,k=0,s;
    		int a[110]={0},b[110]={0},c[220]={0};
    		len1=strlen(chr1);
    		len2=strlen(chr2);
    		for(i=len1-1,j=0;i>=0;i--) a[j++]=chr1[i]-'0';
    		for(i=len2-1,k=0;i>=0;i--) b[k++]=chr2[i]-'0';
    		for(i=0;i<len1;i++)
    		{
    			for(s=0;s<len2;s++)
    			{
    				c[i+s]=c[i+s]+a[i]*b[s];
    			}
    		}
    		for(i=0;i<200;i++)
    		{
    			if(c[i]>=10){
    				c[i+1]=c[i+1]+c[i]/10;  //这一步和下面一步位置不要写反了
    				c[i]=c[i]%10;
    			}
    		}
    		for(i=200;i>0;i--)
    		{
    			if(c[i]==0) continue;
    			else break;
    		}
    		for(;i>=0;i--) cout<<c[i];
    		cout<<endl;
    	}
    	return 0;
    }
    

     二、大数相除(取模,取余)(没有看懂)

    #include<stdio.h>
    #include<string.h>
    char a[100],b[100];//用两个字符串用来输入两个大数 
    int x[100],y[100],z[100],m[100];//被除数  除数  商  余数 
    int digit;//大数的位数 
    void sub(int x[],int y[],int len1,int len2)//大数减法 
    {
    	int i;
    	for(i=0;i<len1;i++)
    	{
    		if(x[i]<y[i])
    		{
    			x[i]=x[i]+10-y[i];
    			x[i+1]--;
    		}
    		else
    			x[i]=x[i]-y[i];
    	}
    	for(i=len1-1;i>=0;i--)//判断减法结束之后,被除数的位数 
    	{
    		if(x[i])
    		{ 
    			digit=i+1;
    			break;		   
    		} 
    	}
    }
    int judge(int x[],int y[],int len1,int len2)
    {
    	int i;
    	if(len1<len2)
    		return -1;
    	if(len1==len2)//若两个数位数相等 
    	{
    		for(i=len1-1;i>=0;i--)
    		{
    			if(x[i]==y[i])//对应位的数相等 
    				continue;
    			if(x[i]>y[i])//被除数 大于 除数,返回值为1 
    				return 1;
    			if(x[i]<y[i])//被除数 小于 除数,返回值为-1 
    				return -1;
    		}
    		return 0;//被除数 等于 除数,返回值为0 
    	}	
    }
    int main()
    {
    	int i,j=0,k=0,temp;
    	int len1,len2,len;//len两个大数位数的差值   
    	while(~scanf("%s %s",a,b))
    	{
    		len1=strlen(a);//被除数位数
    		len2=strlen(b);//除数位数
    		for(i=len1-1,j=0;i>=0;i--)//将字符串中各个元素倒序储存在数组中 
    			x[j++]=a[i]-'0';
    		for(i=len2-1,k=0;i>=0;i--)
    			y[k++]=b[i]-'0';		    
    		if(len1<len2)//当被除数位数 小于 除数位数时 
    		{
    			printf("商是:0
    ");
    			printf("余数是:");
    			puts(a); 
    		}
    		else //当被除数位数 大于或者 除数位数时
    		{
    			len=len1-len2;//两个大数位数的差值
    			for(i=len1-1;i>=0;i--)//将除数后补零,使得两个大数位数相同。被除数:4541543329 除数:98745,加零后:9874500000 
    			{
    				if(i>=len)
    					y[i]=y[i-len];
    				else
    					y[i]=0;
    			}
    			len2=len1;//将两个大数数位相同 		
    			digit=len1;	//将原被除数位数赋值给digit 
    			for(j=0;j<=len;j++)
                {
    				z[len-j]=0;
    				while(((temp=judge(x,y,len1,len2))>=0)&&digit>=k)//判断两个数之间的关系以及位数与除数原位数的关系 
    				{	
    					sub(x,y,len1,len2);	//大数减法函数			    
    					z[len-j]++;//储存商的每一位
    					len1=digit;//重新修改被除数的长度
    					if(len1<len2&&y[len2-1]==0)		
    						len2=len1;//将len1长度赋给len2;						
    				}
    				if(temp<0)//若被除数 小于 除数,除数减小一位。例如:被除数:4541543329 除数:(原)98745,(加零后)9874500000,后退一位后:0987450000 
    				{
    					for(i=1;i<len2;i++)
    						y[i-1]=y[i];
    					y[i-1]=0;
    					if(len1<len2) 
    						len2--;			        				        
    				}
    			}
    			printf("商是:");
    			for(i=len;i>0;i--)//去掉前缀0 
    			{
    				if(z[i])
    					break;
    			}
    			for(;i>=0;i--)
    				printf("%d",z[i]);
    			printf("
    ");
    			printf("余数是:");
    			for(i=len1;i>0;i--)
    			{
    				if(x[i])
    					break;
    			}
    			for(;i>=0;i--)
    				printf("%d",x[i]);
    			printf("
    ");
    		}
    	}
    	return 0;
    }  

    三、大数阶乘(求位数)

    法一:

    lg(N!)=[lg(N*(N-1)*(N-2)*......*3*2*1)]+1 =[lgN+lg(N-1)+lg(N-2)+......+lg3+lg2+lg1]+1

    #include<stdio.h>
    #include<math.h>
    int main()
    {
    	int n;
    	double sum=0;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		sum=sum+log10(i);
    	}
    	printf("%d
    ",(int)sum+1);
    	return 0;
    }  

    法二:

    log10(n!) = log10(2*PI*n)/2+n*log10(n/E); 
    故n!的位数= log10(2*PI*n)/2+n*log10(n/E)+1(注意:当n=1时,算得的结果为0)

    #include<stdio.h>
    #include<math.h>
    #define PI 3.141592654
    #define E 2.71828182846
    int main()
    {
    	int n,sum=1;
    	scanf("%d",&n);
    	if(n>3)
    		sum=log10(2*PI*n)/2+n*log10(n/E)+1;
    	printf("%d
    ",sum);
    	return 0;   
    }  

    四、大数阶乘(求值)

    #include <cstdio>
    #include <iostream>
    using namespace std;
    int main()
    {
    	int n,a[20001];
    	int temp,digit=1;
    	a[0]=1;
    	cin>>n;
    	int i,j;
    	for(i=2;i<=n;i++)
    	{
    		int num=0;
    		for(j=0;j<digit;j++)
    		{
    			temp=a[j]*i+num;
    			a[j]=temp%10;
    			num=temp/10;
    		}
    		while(num)
    		{
    			a[digit]=num%10;
    			num/=10;
    			digit++;
    		}
    	}
    	for(i=digit-1;i>=0;i--) cout<<a[i];
    	cout<<endl;
    	return 0;
    }

    五、大数相减

    //大数相减
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int x[100]={0},y[100]={0},z[100]={0};
    void sub(int x[],int y[],int len)
    {
    	for(int i=0;i<len;i++)
    	{
    		if(x[i]>=y[i]) z[i]=x[i]-y[i];
    		else if(x[i]<y[i])
    		{
    			z[i]=x[i]+10-y[i];
    			x[i+1]=x[i+1]-1;
    		}
    	}
    	for(int i=len-1;i>0;i--)
    	{
    		if(z[i]==0) len--;
    		else break;
    	}
    	for(int i=len-1;i>=0;i--) cout<<z[i];
    	cout<<endl;
    }
    int main()
    {
    	char chr1[100],chr2[100];
    	int len1,len2;
    	while(scanf("%s %s",chr1,chr2))
    	{
    		
    		int i,j=0,k=0;
    		len1=strlen(chr1);
    		len2=strlen(chr2);
    		for(i=len1-1,j=0;i>=0;i--) x[j++]=chr1[i]-'0';
    		for(i=len2-1,k=0;i>=0;i--) y[k++]=chr2[i]-'0';
    		if(len1>len2) sub(x,y,len1);
    		else if(len1<len2) 
    		{
    			printf("-");
    			sub(y,x,len2);
    		}
    		else if(len1==len2)
    		{
    			for(i=len1-1;i>=0;i--)
    			{
    				if(x[i]==y[i]) continue;
    				else if(x[i]>y[i])
    				{
    					sub(x,y,len1);
    					break;
    				}
    				else if(x[i]<y[i])
    				{
    					printf("-");
    					sub(y,x,len1);
    					break;
    				}
    			}
    		    if(i==-1) sub(x,y,len1);
    		}
    	}
    	return 0;
     }   

    六、大数相加

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int main()
    {
    	char chr1[100],chr2[100];
    	int a[100]={0},b[100]={0},c[100]={0};
    	int len1,len2,len;
    	while(scanf("%s %s",chr1,chr2))
    	{
    		int i,j=0,k=0;
    		len1=strlen(chr1);
    		len2=strlen(chr2);
    		for(i=len1-1;i>=0;i--) 
    		{
    			a[j]=chr1[i]-'0';
    			j++;
    		}
    		for(i=len2-1;i>=0;i--)
    		{
    			b[k]=chr2[i]-'0';
    			k++;
    		}
    		if(len1>len2) len=len1;
    		else len=len2;
    		int m=0;
    		for(i=0;i<len;i++)
    		{
    			c[i]=(a[i]+b[i]+m)%10;
    			if(a[i]+b[i]+m>=10) m=1;
    			else m=0;
    		}
    		if(a[i-1]+b[i-1]+m>10) c[i]=1;
    		else i=i-1;
    		for(;i>=0;i--) cout<<c[i];
    		cout<<endl;
    	}
    	return 0;
     }
    天晴了,起飞吧
  • 相关阅读:
    Python之路系列:面向对象初级:静态属性、静态方法、类方法
    对象和类
    Python的函数参数传递
    python参数传递:对象的引用
    Python的locals()函数
    Python 异常处理
    Python变量类型的强制转换
    日常问题总结
    高效能人士的七个习惯
    Dojo入门:DOM操作
  • 原文地址:https://www.cnblogs.com/jianqiao123/p/12067077.html
Copyright © 2011-2022 走看看