对于每组案例,每组测试数据占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; }