【问题标题】:remove the '0' from a string after calculation计算后从字符串中删除“0”
【发布时间】:2020-01-18 17:36:31
【问题描述】:

我试图在两个字符串中进行乘法运算; 完成后,代码向我显示了 calloc 中所有“0”的答案。

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

typedef char* verylong;

verylong input_long(void) {
    int len = sizeof(char),size=0,c,i=0;
    verylong num = malloc(len);
    char ch;
    size = len;
    if (num != NULL) {
        while ((c = getchar()) != '\n' && c != EOF) {
              ch = (char)c;
             if (isdigit(ch))
                num[i++] = ch;
             else
                 return NULL;
             if (i == size) {
                size = i + len;
                if ((num = realloc(num, size)) == NULL)
                   return NULL;
            }
        }
   }
   else
       return NULL;
   num[i] = '\0';
   return num;

}

verylong_multiply(verylong num1, verylong num2) {
int long1 = strlen(num1), long2 = strlen(num2);
verylong ret = calloc(long1 + long2 +1, sizeof(char));
_strrev(num1);
_strrev(num2);
int carry = 0;

for (int i = 0; i < long2; i++) {
    int dig2 = num2[i]-'0';
    carry = 0;
    for (int j = 0; j < long1; j++) {
        int dig1 = num1[j]-'0';
        int temp = ret[i+j]-'0';
        int cur = dig1 * dig2 + temp + carry;
        ret[i+j] = cur % 10+'0';
        carry = cur / 10;
    }
    if (carry>0)
        ret[i+long1] = carry +'0';
}

_strrev(ret);
return ret;
}
void main() {
char* a = input_long();
char* b = input_long();
printf(multiply(a, b));
}

这是整个代码,输出似乎一直给我两个字符串 (10*10) 580 的答案,它不断添加 if '0' 的乘法(ascii 中的 48)。

【问题讨论】:

  • 不再是“非常长”:(您应该解释该类型是一个类型化的字符指针 - 所有其他海报都这样做了。
  • 我做了一个早期的功能,
  • 如果我理解你的代码,它会将数字保存为字符数组,准备打印。考虑将数字存储在数组中作为相反方向的数值(“123”-> {3, 2, 1})以及结构中的数字大小,以简化计算。您可能在数学运算中更频繁地使用它们,而不仅仅是打印它们,因此“优化”这种用法是有意义的。
  • 另外,如果verylongchar * 的typedef(这本身就是个坏主意),那么第一个return '0'; 是错误的。
  • 代码保存的是计算后的数字,但是因为我使用“calloc”来构建新字符串,所以它保留了'0'。如果我制作 10*10,它会给我 580。100+10*'0'(480)

标签: c


【解决方案1】:

除了算法和数据结构的一般设计之外,还有几个问题(存储大小以及从最低有效位开始的数字数组的结构可以简化所有计算)。

verylong_multiply(verylong num1, verylong num2) {
if (strlen(num1) == 0 || strlen(num2) == 0) return '0';

这里至少有一个复制粘贴错误,要么函数为verylong multiply(...),要么缺少返回类型。此外,如果我们假设(而且我们不应该)verylongchar * 的类型定义,那么return '0'; 是完全错误的。 '0'char,而不是 char *

在整个 sn-p 中,'0''\0'NULL 之间似乎存在混淆。

这一行

verylong ret = calloc(sizeof(char) , long1 + long2 + 1);
//                    ^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^   Those should be switched

将分配数组并用填充它,而不是'0'

如果你想用'0' 填充它(空终止符除外),你可以使用

memset(ret, '0', long1 + long2);

这样,在后面的代码中,您也可以更改这一行

int temp = ret[i+j];                   //  -->    int temp = ret[i+j] - '0';
int cur = dig1 * dig2 + temp + carry;
ret[i+j] = cur % 10 + '0';

Thrn,在反转字符串并返回它之前,您可以将最终的 '0' 转换为 '\0',以避免使用 10 * 123 = 01230 而不是 1230

请注意,每次调用此函数时,选择的数据结构都会强制您反转表示数字的字符串并计算它们的长度,如果您还应该将它们反转回原来的状态打算再次使用它们。

【讨论】:

  • 修改后的输出是一样的,我会复制整个代码来复习,谢谢你的回答。
  • @DanielLevi 如果您在讨论问题中的编辑代码,您错过了一些建议:wandbox.org/permlink/NQtxl2PCVXEvDwS5
  • @DanielLevi 正如我已经评论过的,考虑将任意大小的数字存储在struct 中。
  • 非常感谢 Bob,您非常有帮助,我很感激。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 2017-12-21
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多