大一 学习记录

学习记录 2

大数的存储与运算

c语言中,如果一个数超过了long long int的范围,我们就应该用数组的方式去实现这个大数的存储与运算。

首先我们可以定义一个字符数组char[100] (一般来说,经常用字符数组去接受一个未知长度的数字,只需要减去‘0’即可),之后转化到int number[100]里面去。

运算的算法完全模拟我们的人工计算
1.加法
现在有number[100],number1[100],要实现加法运算。我们可以先把数组里面的数倒过来,也就是用number[0]来存储个位数,number[1] 存储十位数·····这样做的好处在于之后可以用一个循环变量如i就可以把它们的对应位数相加。我们用result[100]来存储结果,result[0]就是number[0]与number1[0]的和,之后再把每个位置的数进位一下就行了。

2.减法
同样先把数倒过来,让对应位置的数相减,如果不够减,就向后借一位。
这样的算法只能够是较大的数减较小的数,不过没有关系,只需要先判断一下谁更大就行了。

3.乘法
一开始应该用一个数组的number[0]去乘另一个number1[0],结果存在result[0]里面.然后乘number1[1],结果存在result[1]里面。直至number[0]把每一个number1里面的元素都乘完,再对number[1]进行类似操作。

笔者在进制转化问题,以及阶乘问题中也经常遇到大数。
如:输入一个字符串(字符串的长度不超过20),对其做如下处理:滤去所有的非十六进制字符后,组成一个新字符串(十六进制形式),然后将其转换为十进制数后输出。
例:
输入: A4 1cDb ACDB
输出: 十六进制:0xA41CDBACDB 十进制:704858795227
这题的关键在于如何生成16的高次幂,首先生成0次幂,也就是1。1次幂只需用16乘以0次幂的每个数,再进位。二次幂就用16乘以一次幂的每个数,再进位······

如:
给n个数字,输出这些数字在二进制下的位数。

如:计算100的阶乘

代码如下

#include<stdio.h>  //大数运算器
#define MAX 100
int size,size1;

void carry(int* num);
void add(int* num,int* num1);
void subtract(int* num,int* num1);
void multiply(int* num,int* num1);
int main()
{
	char str_number[MAX]={0},str_number1[MAX]={0};
	int number[MAX]={0},number1[MAX]={0};
	int i,temp,ch;
	void (*pf[3])(int* num,int* num1)={add,subtract,multiply};

	printf("欢迎使用”孤铉“计算器\n");
	printf("请您先输入2个数字\n");

	gets(str_number);
	gets(str_number1);

	for(i=MAX-1;str_number[i]==0;i--);
	size=i+1;

	for(i=MAX-1;str_number1[i]==0;i--);
	size1=i+1;


	for(i=0;i<size/2;i++)           //从低位到高位
	{
		temp=str_number[i];
		str_number[i]=str_number[size-1-i];
		str_number[size-1-i]=temp;
	}

		for(i=0;i<size;i++)
	{
		number[i]=str_number[i]-'0';
		//printf("%d",number[i]);
	}	

	//printf("\n");
	
	for(i=0;i<size1/2;i++)           //从低位到高位
	{
		temp=str_number1[i];
		str_number1[i]=str_number1[size1-1-i];
		str_number1[size1-1-i]=temp;
	}


	for(i=0;i<size1;i++)
	{
		number1[i]=str_number1[i]-'0';
		//printf("%d",number1[i]);
	}

	printf("请输入您要进行的运算:");
	printf("\n加法:0\n减法:1\n乘法:2\n");
	while(1)
	{
	scanf("%d",&ch);
	if(ch>=0&&ch<=2)
		break;
	else
		printf("指令错误,请重新输入\n");
	fflush(stdin);
	}

	pf[ch](number,number1);
	
}
void carry(int* num)
{
	int i;
	for(i=0;i<MAX;i++)
	{
		if(num[i]>=10)
		{		
			num[i+1]+=num[i]/10;
			num[i]%=10;
		}
	}
}

void add(int* num,int* num1)
{
	int result[MAX]={0};
	int i,size;
	
	for(i=0;i<MAX;i++)
		result[i]=num[i]+num1[i];

	carry(result);

	for(i=MAX-1;result[i]==0;i--);
	size=i+1;

	printf("\n");
	for(i=size-1;i>=0;i--)
	{		
		printf("%d",result[i]);
	}

}

void subtract(int* num,int* num1)  //num-num1  
{
	int result[MAX]={0};
	int i,size_res,flag;

	if(size>size1)
		flag=1;
	if(size<size1)
		flag=0;

	if(size==size1)
	{
		for(i=size-1;i>=0;i--)
			if(num[i]!=num1[i])
				break;

		if(num[i]>num1[i]||i==-1)
			flag=1;
		else
			flag=0;
	}


	if(flag==1)
	{
		for(i=0;i<MAX;i++)
		{

			if(num[i]<num1[i])
			{
				num[i]+=10;
				num[i+1]-=1;
			}
			result[i]=num[i]-num1[i];	
		}
	}

	else
	{
		for(i=0;i<MAX;i++)
		{
			if(num1[i]<num[i])
			{
				num1[i]+=10;
				num1[i+1]-=1;
			}
			result[i]=num1[i]-num[i];
		}
	}

	if(flag==0)
		printf("-");

	for(i=MAX-1;result[i]==0;i--);
	size_res=i+1;
	
	for(i=size_res-1;i>=0;i--)
	{		
		printf("%d",result[i]);
	}

	if(size_res==0)
		printf("0");
}

void multiply(int* num,int* num1)
{
	int result[MAX]={0};
	int i,j,size_res;

	for(i=0;i<MAX;i++)
	{
		for(j=0;j<size1;j++)
			result[i+j]+=num[i]*num1[j];
	}

	carry(result);

	for(i=MAX-1;result[i]==0;i--);
	size_res=i+1;
	
	for(i=size_res-1;i>=0;i--)
	{		
		printf("%d",result[i]);
	}
}
#include<stdio.h>          
#include<string.h>
void input_out(char *);
void wash(char *str,int *number);
void multi(int *time,int flag);
void push (int *time);
void add(int *sum,int *number,int *time);
int main()
{
	char str[20];
	int number[20]={0};	
	int sum[30]={0};
	int time[30];
	
	input_out(str);
	wash(str,number);
	add(sum,number,time);
	
	printf("\n\n\n");
}

void input_out(char *str_m)
{
	char str[20];
	int cur,pre;
	
	printf("请输入一个字符串");
	gets(str);

	for(cur=0,pre=0;str[pre];pre++)    //最后一个就是0
	{
		if('A'<=str[pre]&&str[pre]<='F') str[cur++]=str[pre];
		if('a'<=str[pre]&&str[pre]<='f') str[cur++]=str[pre];
		if('0'<=str[pre]&&str[pre]<='9') str[cur++]=str[pre];
	}
	str[cur]=0;

	printf("十六进制: 0x%s",str);
	strcpy(str_m,str);
}
void wash(char *str,int *number)
{
	int i,flag,temp;
	for(i=0;str[i]!=0;i++)
	{
		if(str[i]>='a'&&str[i]<='f')
			number[i]=str[i]-'a'+10;
		if(str[i]>='A'&&str[i]<='F')
			number[i]=str[i]-'A'+10;
		if(str[i]>='0'&&str[i]<='9')
			number[i]=str[i]-'0';
	}
	flag=i-1;

	for(i=0;i<=flag/2;i++)    //从低位到高位排
	{
		temp=number[i];
		number[i]=number[flag-i];
		number[flag-i]=temp;
	}
}

void multi(int *time,int flag)
{
	int i,j;

	for(i=0;i<30;i++)
		time[i]=0;
	time[0]=1;

	for(i=0;i<flag;i++)
	{
		for(j=0;j<29;j++)
			time[j]*=16;
		push(time);
	}
}
void push (int *time)
{
	int i;
	for(i=0;i<29;i++)
	{
		if(time[i]>=10)
		{		
			time[i+1]+=time[i]/10;
			time[i]%=10;
		}
	}
}
void add(int *sum,int *number,int *time)
{
	int i,j;
	for(i=0;i<20;i++)      // 第几个number
	{
		multi(time,i);     //对应的16倍数

		for(j=0;j<30;j++)    		
			time[j]*=number[i];		//乘以系数			

		for(j=0;j<30;j++)
				sum[j]+=time[j];

				push(sum);
	}

	printf("\n十进制:");
	for(i=29;sum[i]==0;i--);        //从后开始第一个不为0的数
	for(;i>=0;i--)
		printf("%d",sum[i]);
}
# include<stdio.h>
#include<stdlib.h>
void multi(int *time,int flag);
void push (int *time);
int main ()
{
	char strNumber[1000];
	int time[1000];
	int i,j,k,flag,sizeStr,sizeTime,n;   //k为次数  
	int *p;

	scanf("%d",&n);
	p=(int *)calloc(n,sizeof(int));
	fflush(stdin);

	for(k=0;k<n;k++)
	{
		for(i=0;i<1000;i++)
			strNumber[i]=0;

		gets(strNumber);

		for(i=999;strNumber[i]==0;i--);  //i+1个数字
		sizeStr=i+1;

		for(i=0;i<sizeStr;i++)
			strNumber[i]-='0';

		for(flag=1;;flag++)
		{
			multi(time,flag);

			for(i=999;time[i]==0;i--);  //i个数字
			sizeTime=i+1;

			if(sizeTime<sizeStr)
				continue;

			if(sizeTime>sizeStr)
				break;

			if(sizeTime==sizeStr)
			{
				for(j=0;j<sizeTime;j++)
				{
					if(time[j]!=strNumber[j])
						break;
				}
			}

			if(time[j]>strNumber[j])  
				break;	
		}
		p[k]=flag;
	}
	for(k=0;k<n;k++)
		printf("%d\n",p[k]);	
}
void multi(int *time,int flag)
{
	int i,j,temp;

	for(i=0;i<1000;i++)
		time[i]=0;
	time[0]=1;

	for(i=0;i<flag;i++)
	{
		for(j=0;j<999;j++)
			time[j]*=2;
		push(time);
	}


	for(i=999;time[i]==0;i--);  //有i+1个数字

	for(j=0;j<(i+1)/2;j++)
	{
		temp=time[j];
		time[j]=time[i-j];
		time[i-j]=temp;
	}
}
void push (int *time)
{
	int i;
	for(i=0;i<999;i++)
	{
		if(time[i]>=10)
		{		
			time[i+1]+=time[i]/10;
			time[i]%=10;
		}
	}
}

#include<stdio.h>
#define MAX 200
void carry(int* num);

int main()
{
	int factorial[MAX]={0},i,j,n;
	scanf("%d",&n);

	factorial[0]=1;
	for(i=1;i<=n;i++)
	{
		for(j=0;j<MAX;j++)
		{
			factorial[j]*=i;
		}
		carry(factorial);
	}

	for(i=MAX-1;factorial[i]==0;i--);

	for(;i>=0;i--)
		printf("%d",factorial[i]);
}

void carry(int* num)
{
	int i;

	for(i=0;i<MAX;i++)
	{
		if(num[i]>=10)
		{		
			num[i+1]+=num[i]/10;
			num[i]%=10;
		}
	}
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页