问题链接:HDU1753 大明A+B。基础训练级的题,用C语言编写程序。
问题简述:参见上述链接。
问题分析:两个数可以能非常长,带有小数点,所以相加的话要么直接相加,要么转换为大数。大数的话,因为有小数点,就不那么好算了。所以还是直接相加。
程序说明:直接相加也有两种计算方法,一种是把两个数读到字符串数组中,然后对齐小数点并且补0,再行相加;另外一种方法(本程序使用的方法)是直接计算位置,进行相加。
读入数据时也有两种方法,一是用函数scanf()读入数据(字符串);二是使用函数getchar()读入数据(逐个字符读入)。由于进行相加时,需要计算小数点前后的位数,后一种可以一边读入数据一边计算。本程序采用后一种做法,逻辑上稍微复杂一些,需要更高的技巧。
程序中,需要注意两点:
1.计算结果的整数部分左边有可能有很多0;
2.输入的最后一行,有可能没有换行("
")文件就直接结束了,需要做特殊处理。
AC的C语言程序如下:
/* HDU1753 大明A+B */ #include <stdio.h> #include <stdlib.h> #define MAXN 400 char a[MAXN+1], b[MAXN+1], ans[MAXN+1]; int main(void) { char c; int aleftcount, arightcount, bleftcount, brightcount, carry, count, i, j, k, l; for(;;) { c=getchar(); if(c == EOF) break; // step1 读入A i = 0; aleftcount = 0; arightcount = 0; // setp1.1 读入A的小数点前的各位,并且位数计数 while(c != '.' && c != ' ') { a[i++] = c; aleftcount++; c=getchar(); } a[i++] = c; // 小数点或空格 // step1.2 读入A的小数点后的各位,并且位数计数 if(c != ' ') while((c=getchar()) != ' ') { a[i++] = c; arightcount++; } k = i - 1; // step2 读入B i = 0; bleftcount = 0; brightcount = 0; // setp2.1 读入B的小数点前的各位,并且位数计数 while((c=getchar()) != '.' && c != ' ') { b[i++] = c; bleftcount++; } b[i++] = c; // 小数点或换行符 // step2.2 读入B的小数点后的各位,并且位数计数 if(c != ' ' && c != EOF) while((c=getchar()) != ' ' && c != EOF) { b[i++] = c; brightcount++; } l = i - 1; // step3 计算A+B // step3.1 小数部分相加 j = 0; // step3.1.1 拷贝长的部分 if(arightcount > brightcount) { count = arightcount - brightcount; while(count--) ans[j++] = a[k--]; } else if(arightcount < brightcount) { count = brightcount - arightcount; while(count--) ans[j++] = b[l--]; } // step3.1.2 同长部分相加 carry = 0; count = (arightcount > brightcount) ? brightcount : arightcount; for(i=1; i<=count; i++) { ans[j] = carry + a[k] + b[l] - '0'; if(ans[j] > '9') { ans[j] -= 10; carry = 1; } else carry = 0; j++; k--; l--; } // step3.2 小数点 ans[j++] = '.'; // step3.3 整数部分相加 k--; l--; while(k >= 0 || l >= 0) { ans[j] = carry + ((k>=0) ? a[k] : '0') + ((l>=0) ? b[l] : '0') - '0'; if(ans[j] > '9') { ans[j] -= 10; carry = 1; } else carry = 0; j++; k--; l--; } if(carry == 1) ans[j++] = '1'; // step4 输出结果 // step4.1 去掉右边的0和小数点 k = 0; while(ans[k] == '0') k++; if(ans[k] == '.') k++; // step4.2 输出结果 for(i=j-1; i>=k; i--) putchar(ans[i]); putchar(' '); } return 0; }