hdu1753 大明A+B && nyoj 513 A+B Problem IV

高精度问题,我改的自己写的那个高精度模版,c++来写高精度就是麻烦,还要考虑一大堆特殊情况。

我用的一些个测试数据:

000   00

0

00001.1000   2.9

4

00001.1110   3.333000

4.444

99.2   0.8

100

主要的特殊情况就是前导0和后导0,以及全部都是0的情况。


我的思路就是:

以009.200和00.8 为例,

1)首先把小数转化成小数部分位数相同的数,转化成009.200和00.800;

2)然后去掉小数点,009200和00800

3)再大整数相加调用add(),相加得010000

4)然后在输出ans字符数组的时候忽略前面的所有0和小数点后的某位之后全是零的情况,以及在输出的时候注意什么时候输出小数点。




/*任务:高精度,计算大数加大数 
*
*参数:乘法函数mul参数为 被加数a[],加数b[],保存最终结果的ans数组
*结果:ans数组中ans[0]为最高位,以此类推  
*/ 
#include <iostream>
#include <string.h>
#define MAX 10000
using namespace std;
int max(int a,int b){
	if(a>b)return a;
	else return b;
}
void delete_point(char*a){
	int len=strlen(a);
	int i;
	for(i=0;i<len;i++){
		if(a[i]=='.') break;
	}
	if(i<len-1){
		for(int j=i;j<len-1;j++)
			a[j]=a[j+1];
		a[len-1]=0;	
	}
	
}
int add(char a[],char b[],char ans[]) {
	     int i,j,s,len,c=0;
		 int temp_a[MAX],temp_b[MAX],temp_ans[MAX];
		 memset(ans,0,sizeof(ans));
		 memset(temp_a,0,sizeof(temp_a));
		 memset(temp_b,0,sizeof(temp_b));
		 memset(temp_ans,0,sizeof(temp_ans));
		 len=max(strlen(a),strlen(b)); 
		 for (i=0;i<strlen(a);i++)         
		 	temp_a[strlen(a)-i-1]=a[i]-'0';
	 	 for (i=0;i<strlen(b);i++)         
		 	temp_b[strlen(b)-i-1]=b[i]-'0';
		 
		 for(j=0;j<len;j++){
			s=temp_a[j]+temp_b[j]+c;
			temp_ans[j]=s%10;
			c=s/10;
		 }
		 if(c) temp_ans[len++]=c;		 
    	 for (i=0;i<len;i++)
			ans[len-1-i]=temp_ans[i]+'0';
		 ans[len]='\0'; 	 
		 return len;
		}
int main()
{
	char a[MAX],b[MAX],ans[MAX];
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	while(cin>>a>>b){
		int len_a=strlen(a);
		int len_b=strlen(b);
		int len_a_1=0,len_a_2=0;
		int len_b_1=0,len_b_2=0;
		for(int i=0;i<len_a;i++){
			if(a[i]!='.') len_a_1++;
			else {
				len_a_2=len_a-len_a_1-1;
				break;
			}
		}
		for(int i=0;i<len_b;i++){
			if(b[i]!='.') len_b_1++;
			else {
				len_b_2=len_b-len_b_1-1;
				break;
			}
		}
		//cout<<"差"<<abs(len_b_2-len_a_2)<<endl;
		if(len_b_2>len_a_2){
			for(int i=len_a;i<len_a+len_b_2-len_a_2;i++)
				a[i]='0';
			len_a+=len_b_2-len_a_2;
		}
		else if(len_b_2<len_a_2){
			for(int i=len_b;i<len_b+len_a_2-len_b_2;i++)
				b[i]='0';
			len_b+=len_a_2-len_b_2;
		}
		//cout<<a<<endl;
		//cout<<b<<endl;
		//去除小数点
		delete_point(a);
		delete_point(b);
		//cout<<a<<endl;
		//cout<<b<<endl;
		int len_ans=add(a,b,ans);
		//cout<<ans<<endl;
		int flag_point=len_ans-max(len_a_2,len_b_2);
		int flag_int=1;  //标志是否是整数 ,1代表整数 
		int flag_zero_front=1;  //忽略前导零时使用 ,1表示全部为0,0表示最终结果不是零 
		int flag_zero_behand;//忽略后导零时使用 ,1表示后面全部为0,0表示后面不全是0 
		int flag_zero_all=1;
		for(int i=flag_point;i<len_ans;i++)
			if(ans[i]!='0') flag_int=0;
		for(int i=0;i<len_ans;i++)
				if(ans[i]!='0') flag_zero_all=0;
		if(flag_zero_all==1) {
			cout<<"0"<<endl;
			continue;
		}
		for(int i=0;i<len_ans;i++){
			flag_zero_behand=1;
			if(i==flag_point-1) flag_zero_front=0;
			if(i==flag_point&&flag_int==1)break; 
			if(i==flag_point) cout<<'.';			
			if(flag_zero_front==0||ans[i]!='0'){
				for(int j=i;j>=flag_point&&j<len_ans;j++){
					if(ans[j]!='0') flag_zero_behand=0; 
				}
				if(i>=flag_point&&flag_zero_behand==1) break;
				cout<<ans[i];
				flag_zero_front=0;
			}
		}
		
		cout<<endl;		
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
	}
	return 0;
}

java秒过

import java.io.*;
import java.util.*;
import java.math.*;

public class Main {
	public static void main(String[] args) {
		Scanner cin=new Scanner(System.in);
		BigDecimal a=new BigDecimal(0);
		BigDecimal b=new BigDecimal(0);
		while(cin.hasNext()){
			a=cin.nextBigDecimal();
			b=cin.nextBigDecimal();
			System.out.println(a.add(b).stripTrailingZeros().toPlainString());
		}		
	}
}


你可能感兴趣的:(c,测试,BI,delete,任务,ansj)