对于每组案例,每组测试数据占2行,分别是两个加数。
每组案例是n行,每组测试数据有一行输出是相应的和。 输出保证一定是一个小数部分不为0的浮点数
0.111111111111111111111111111111 0.111111111111111111111111111111
0.222222222222222222222222222222
主要还是权值对齐,处理好进位
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 反转字符串函数
// 功能:将输入的字符串进行反转,方便后续的加法运算从低位开始处理
// 参数:str 为待反转的字符串
void reverse(char *str) {
// 获取字符串的长度
int len = strlen(str);
// 遍历字符串的前半部分
for (int i = 0; i < len/2; i++) {
// 交换当前字符和对称位置的字符
char temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
// 小数相加(返回进位)
// 功能:将两个以字符串形式表示的小数部分相加,并返回相加后产生的进位
// 参数:dec1 为第一个小数部分的字符串,dec2 为第二个小数部分的字符串,result 用于存储相加结果
int add_decimal(char *dec1, char *dec2, char *result) {
// 获取 dec1 的长度
int len1 = strlen(dec1);
// 获取 dec2 的长度
int len2 = strlen(dec2);
// 找出两个小数部分长度的最大值
int max_len = len1 > len2 ? len1 : len2;
// 补零对齐
// 动态分配内存,用于存储补零后的 dec1,长度为 max_len + 1(包含字符串结束符)
char *temp1 = calloc(max_len+1, sizeof(char));
// 动态分配内存,用于存储补零后的 dec2,长度为 max_len + 1(包含字符串结束符)
char *temp2 = calloc(max_len+1, sizeof(char));
// 将 dec1 复制到 temp1 中
strcpy(temp1, dec1);
// 将 dec2 复制到 temp2 中
strcpy(temp2, dec2);
// 若 dec1 的长度小于 max_len,在 temp1 后面补零
for (int i = len1; i < max_len; i++) temp1[i] = '0';
// 若 dec2 的长度小于 max_len,在 temp2 后面补零
for (int i = len2; i < max_len; i++) temp2[i] = '0';
// 从右往左相加
// 初始化进位为 0
int carry = 0;
// 用于记录结果字符串的索引
int k = 0;
// 从右往左逐位相加
for (int i = max_len-1; i >= 0; i--) {
// 计算当前位的和,包括进位
int sum = (temp1[i]-'0') + (temp2[i]-'0') + carry;
// 将当前位的和对 10 取模,得到当前位的结果,并转换为字符存储到 result 中
result[k++] = sum % 10 + '0';
// 计算新的进位
carry = sum / 10;
}
// 在结果字符串末尾添加字符串结束符
result[k] = '\0';
// 反转结果字符串,因为之前是从低位到高位存储的
reverse(result);
// 去除末尾多余的零
// 当结果字符串末尾有零且长度大于 0 时,将零去除
while (k > 0 && result[k-1] == '0') result[--k] = '\0';
// 释放动态分配的内存
free(temp1);
free(temp2);
// 返回小数相加后产生的进位
return carry;
}
// 整数相加(修复补零方式)
// 功能:将两个以字符串形式表示的整数部分相加,并将结果存储在 result 中
// 参数:int1 为第一个整数部分的字符串,int2 为第二个整数部分的字符串,result 用于存储相加结果
void add_integer(char *int1, char *int2, char *result) {
// 获取 int1 的长度
int len1 = strlen(int1);
// 获取 int2 的长度
int len2 = strlen(int2);
// 找出两个整数部分长度的最大值
int max_len = len1 > len2 ? len1 : len2;
// 补前导零对齐
// 动态分配内存,用于存储补零后的 int1,长度为 max_len + 1(包含字符串结束符)
char *temp1 = calloc(max_len+1, sizeof(char));
// 动态分配内存,用于存储补零后的 int2,长度为 max_len + 1(包含字符串结束符)
char *temp2 = calloc(max_len+1, sizeof(char));
// 将 temp1 初始化为全零
memset(temp1, '0', max_len);
// 将 temp2 初始化为全零
memset(temp2, '0', max_len);
// 将 int1 复制到 temp1 的合适位置,前面补零
strcpy(temp1 + (max_len - len1), int1);
// 将 int2 复制到 temp2 的合适位置,前面补零
strcpy(temp2 + (max_len - len2), int2);
// 从右往左相加
// 初始化进位为 0
int carry = 0;
// 用于记录结果字符串的索引
int k = 0;
// 从右往左逐位相加
for (int i = max_len-1; i >= 0; i--) {
// 计算当前位的和,包括进位
int sum = (temp1[i]-'0') + (temp2[i]-'0') + carry;
// 将当前位的和对 10 取模,得到当前位的结果,并转换为字符存储到 result 中
result[k++] = sum % 10 + '0';
// 计算新的进位
carry = sum / 10;
}
// 如果最后还有进位,将进位添加到结果字符串中
if (carry) result[k++] = '1';
// 在结果字符串末尾添加字符串结束符
result[k] = '\0';
// 反转结果字符串,因为之前是从低位到高位存储的
reverse(result);
// 去除前导零
// 找到第一个非零字符的位置
int start = 0;
// 当结果字符串有前导零且不是最后一个字符时,继续查找
while (result[start] == '0' && start < k-1) start++;
// 将从第一个非零字符开始的子字符串移动到结果字符串的开头
memmove(result, result + start, k - start + 1);
// 释放动态分配的内存
free(temp1);
free(temp2);
}
int main() {
// 定义两个字符数组,用于存储输入的两个浮点数
char num1[1000], num2[1000];
// 循环读取多组输入,直到文件结束
while (scanf("%s %s", num1, num2) != EOF) {
// 定义四个字符数组,分别用于存储两个浮点数的整数部分和小数部分
char int1[1000], int2[1000], dec1[1000], dec2[1000];
// 定义两个字符数组,分别用于存储整数部分和小数部分相加的结果,并初始化为全零
char result_int[1000] = {0}, result_dec[1000] = {0};
// 提取整数和小数部分
// 在 num1 中查找小数点的位置
char *dot = strchr(num1, '.');
if (dot) {
// 复制 num1 的整数部分到 int1 中
strncpy(int1, num1, dot - num1);
// 在 int1 末尾添加字符串结束符
int1[dot - num1] = '\0';
// 复制 num1 的小数部分到 dec1 中
strcpy(dec1, dot + 1);
} else {
// 如果 num1 中没有小数点,整个字符串就是整数部分
strcpy(int1, num1);
// 小数部分为空
dec1[0] = '\0';
}
// 在 num2 中查找小数点的位置
dot = strchr(num2, '.');
if (dot) {
// 复制 num2 的整数部分到 int2 中
strncpy(int2, num2, dot - num2);
// 在 int2 末尾添加字符串结束符
int2[dot - num2] = '\0';
// 复制 num2 的小数部分到 dec2 中
strcpy(dec2, dot + 1);
} else {
// 如果 num2 中没有小数点,整个字符串就是整数部分
strcpy(int2, num2);
// 小数部分为空
dec2[0] = '\0';
}
// 处理小数部分
// 调用 add_decimal 函数计算小数部分相加的结果,并获取进位
int carry_dec = add_decimal(dec1, dec2, result_dec);
// 处理整数部分(包含小数进位)
if (carry_dec) {
// 定义一个字符串表示进位 1
char carry_str[] = "1";
// 先将进位加到 int1 上
add_integer(int1, carry_str, int1);
}
// 再加两个整数部分
add_integer(int1, int2, result_int);
// 输出最终结果
// 如果小数部分不为空,输出整数部分、小数点和小数部分;否则只输出整数部分
printf("%s%s%s\n",
result_int,
strlen(result_dec) ? "." : "",
strlen(result_dec) ? result_dec : "");
}
return 0;
} #include<stdio.h>
#include<string.h>
int main(void){
char a[100],b[100];
scanf("%s %s",a,b);
int len1,len2;
len1=strlen(a);
len2=strlen(b);
int jinwei=0;
int ap,bp;
//找小数点的位置
for(int i=0;i<len1;i++){
if(a[i]=='.'){
ap=i;
}
}
for(int i=0;i<len2;i++){
if(b[i]=='.'){
bp=i;
}
}
//先计算小数部分
//对长度较短的那个数进行扩充
int _len1=len1-ap-1;
int _len2=len2-bp-1;
int cha;
int z_len;
if(_len1>_len2){
cha=_len1-_len2;
for(int i=len2;i<len2+cha;i++){
b[i]='0';
}
z_len=_len1;
}else{
cha=_len2-_len1;
for(int i=len1;i<len1+cha;i++){
a[i]='0';
}
z_len=_len2;
}
int sum[z_len];
int temp=0;
int xs_jw;
for(int i=z_len-1;i>-1;i--){
sum[i]=(a[ap+i+1]-48+b[bp+i+1]-48+temp)%10;
temp=(a[ap+i+1]-48+b[bp+i+1]-48+temp)/10;
}
xs_jw=temp;
// printf("小数部分相加结果:\n");
// for(int i=0;i<z_len;i++){
// printf("%d ",sum[i]);
// }
// printf("\n");
// printf("小数部分相加进位:\n");
// printf("%d",xs_jw);
// printf("\n");
//再计算整数部分
//在短的前面补零
int zz_len;
if(ap>bp){ //b较短
zz_len=ap;
cha=ap-bp;
for(int i=bp-1;i>-1;i--){
b[i+cha]=b[i];
}
//补充前面的0
for(int i=0;i<cha;i++){
b[i]='0';
}
}else{
zz_len=bp;
cha=bp-ap;
for(int i=ap-1;i>-1;i--){
a[i+cha]=a[i];
}
//补充前面的0
for(int i=0;i<cha;i++){
a[i]='0';
}
}
int sum2[zz_len];
int temp2=xs_jw;
int zs_jw;
for(int i=zz_len-1;i>-1;i--){
sum2[i]=(a[i]-48+b[i]-48+temp2)%10;
// printf("%d ",sum2[i]);
temp2=(a[i]-48+b[i]-48+temp2)/10;
// printf("%d ",temp2);
// printf("\n");
}
zs_jw=temp2;
// printf("整数部分相加结果:\n");
// for(int i=0;i<zz_len;i++){
// printf("%d ",sum2[i]);
// }
// printf("\n");
// printf("整数部分相加进位:\n");
// printf("%d",zs_jw);
// printf("\n");
// printf("最后的结果:");
if(zs_jw!=0){
printf("%d",zs_jw);
}
for(int i=0;i<zz_len;i++){
printf("%d",sum2[i]);
}
printf(".");
for(int i=0;i<z_len;i++){
printf("%d",sum[i]);
}
return 0;
}