编程之美读书笔记(2)大数问题(高精度运算)

<1>大数相加

#include<stdio.h>
#include<string.h>

char a[10001],b[10001],sum[10002];

int BigIntegerAdd(){
	//两个数的长度
	int lena = strlen(a);
	int lenb = strlen(b);
	//进位标记
	int c = 0;
	int i,j,k;
	//初始化数组sum
	memset(sum,0,10001);
	//倒序相加
	k = 0;
	for(i = lena-1,j = lenb-1;i >= 0 && j >= 0;i--,j--){
		sum[k] = a[i] + b[j] - '0' + c;
		c = 0;
		//如果相加大于等于10
		if(sum[k] > '9'){
			sum[k] -= 10;
			c = 1;
		}
		k++;
	}
	//a > b
	while(i >= 0){
		sum[k] = a[i] + c;
		c = 0;
		//如果相加大于等于10
		if(sum[k] > '9'){
			sum[k] -= 10;
			c = 1;
		}
		k++;
		i--;
	}
	//b > a
	while(j >= 0){
		sum[k] = b[j] + c;
		c = 0;
		//如果相加大于等于10
		if(sum[k] > '9'){
			sum[k] -= 10;
			c = 1;
		}
		k++;
		j--;
	}
	//如果最后两个数相加有进位的情况
	//例如:67 + 51:5+6有进位
	if(c == 1){
		sum[k++] = '1';
	}
	//翻转
	char temp;
	for(i = 0,j = k-1;i < j;i++,j--){
		temp = sum[i];
		sum[i] = sum[j];
		sum[j] = temp;
	}
	return 0;
}

int main(){
	while(scanf("%s %s",a,b) != EOF){
		BigIntegerAdd();
		puts(sum);
	}
}


<2>大数相减

/*
1.比较减数与被减数的长度,确定正负号
2.模拟减法运算
    (1)a[i] == b[j] 
    (2)a[i] < b[j] //借位
    (3)a[i] > b[j] 
 */
#include<stdio.h>
#include<string.h>

char a[10001],b[10001],sum[10001],temp[10001];

int BigIntegerMinus(){
	//两个数的长度
	int lena = strlen(a);
	int lenb = strlen(b);
	//借位标记
	int c = 0;
	int i,j,k,positive = 1;
	//判断正负号
	if(lena < lenb || (lena == lenb && strcmp(a,b) < 0) ){
		strcpy(temp,a);
		strcpy(a,b);
		strcpy(b,temp);
		positive = -1;//负号
		lena = strlen(a);
		lenb = strlen(b);
	}
	//倒序相减 
    k = 0;  
    for(i = lena-1,j = lenb-1;i >= 0 && j >= 0;i--,j--){  
        sum[k] = a[i] - b[j] + '0' + c;  
        c = 0;  
        //如果相减小于0  
        if(sum[k] < '0'){  
            sum[k] += 10;  
            c = -1;  
        }  
        k++;  
    }  
    //a > b  
    while(i >= 0){  
        sum[k] = a[i] + c;  
        c = 0;  
        //如果相减小于0  
        if(sum[k] < '0'){  
            sum[k] += 10;  
            c = -1;  
        }  
        k++;  
        i--;  
    }  
    //b > a  
    while(j >= 0){  
        sum[k] = b[j] + c;  
        c = 0;  
		//如果相减小于0  
        if(sum[k] < '0'){  
            sum[k] += 10;  
            c = -1;  
        }  
        k++;  
        j--;  
    }
	int index = k - 1;
	//检索高位,有可能相减为0
	while(sum[index] == '0' && index > 0){
		index--;
	}
	//正号
	if(positive == 1){
		sum[index+1] = '\0';
	}
	//负号
	else{
		sum[++index] = '-';
		sum[index+1] = '\0';
	}
	//翻转
	char t;
	for(i = 0,j = index;i < j;i++,j--){
		t = sum[i];
		sum[i] = sum[j];
		sum[j] = t;
	}
	return 0;
}

int main(){
	while(scanf("%s %s",a,b) != EOF){
		BigIntegerMinus();
		puts(sum);
	}
}

<3>大数乘法

#include<stdio.h>
#include<string.h>

char a[10001],b[10001],c[20002];

int BigIntegerMulti()
{
    int i,j,lena,lenb,lenc;
	//初始化
	memset(c,'0',20002);
	//两个数的长度
	lena = strlen(a);
	lenb = strlen(b);
	//乘积最大位数
	lenc = lena + lenb - 1;
	//翻转  
    char temp;  
    for(i = 0,j = lena-1;i < j;i++,j--){  
        temp = a[i];  
        a[i] = a[j];  
        a[j] = temp;  
    }  
	for(i = 0,j = lenb-1;i < j;i++,j--){  
        temp = b[i];  
        b[i] = b[j];  
        b[j] = temp;  
    } 
	//倒序相乘
	/*
	      123
	    *  54
		------
		  492
		 615
	    -----
		 6642 
	*/
	int t;
	for(i = 0;i < lena;i++){
		for(j = 0;j < lenb;j++){
			/* c[i+j] = (a[i] - '0') * (b[j] - '0') + c[i+j]; 
			   9 * 9 + '0' 超出char范围越界所以设置一个int临时变量t    */
			t = (a[i] - '0') * (b[j] - '0') + c[i+j] - '0';
			//进位
			c[i+j+1] = t / 10 + c[i+j+1];
			c[i+j] = t % 10 + '0';
		}
	}
	//确定乘积的位数
	while(c[lenc] == '0' && lenc >0){
		lenc--;
	}
	//注意:加'\0'
	c[lenc+1] = '\0';
	//翻转
	for(i = 0,j = lenc;i < j;i++,j--){  
        temp = c[i];  
        c[i] = c[j];  
        c[j] = temp;  
    } 
	return 0;
}

int main(){
	while(scanf("%s %s",a,b) != EOF){
		BigIntegerMulti();
		puts(c);
	}
	return 0;
}


自己写的如有问题,请告知一下。





你可能感兴趣的:(编程之美,剑指offer)