0

我需要将罗马数字转换为整数值,顺序无关紧要。(9=VIII)

目前我开始从我的代码中得到一个软糖因子,它在我实现 X 时从 20 开始,到我达到 M 时达到 530。我不能简单地将它分解为当 I = 531 和V = 535,MDCLXVI = 1560。那个和eclipse有时说它不能运行,有时它可以。

这是代码

C int romanToInt(char *s) {
  int n, k=0;
  while(k<[MAX_LINE]) {
    if(s[k]==’I’) {
      n=n++
    }
    if(s[k]==’v’) {
      n=n+5
    }
    if(s[k]==’X’) {
      n=n+10
    }
    if(s[k]==’L’) {
      n=n+50
    }
    if(s[k]==’C’) {
      n=n+100
    }
    if(s[k]==’D’) {
      n=n+500
    }
    if(s[k]==’M’) {
      n=n+1000
    }
    return n;
  }

谢谢你的帮助。

4

2 回答 2

2

你初始化你的循环计数器,k,但不是你的累加器,n。初始化 n=0; C 假设您知道自己在做什么,因此它不会像某些 OOP 语言那样自动将 int 初始化为零。所以,你可以从垃圾开始,这会抛出你所有的计算。第二:为什么n=n++?用户 n+=1 或 n++

此外,for 循环可能会比 while 循环更好,因为它会强制您初始化计数器变量(如果您还没有)并设置迭代次数的限制,因此几乎没有无限循环的机会。

最后,考虑 if/else if 或 select/case,而不是所有这些 if。

哦,我敢肯定这可能是一个错字,但你的 return 语句应该在循环结束之后。您要么忘记在 return 语句之前添加额外的大括号,要么我算错了。

于 2014-12-01T19:16:31.043 回答
1

这里发生了几件事。

int n, k=0;

您应该将两个变量都初始化为 0。目前,您只需初始化k. n很可能含有垃圾。

while(k<[MAX_LINE]) ...

该语法不应该编译。但即使它做到了,它也不是你想要的。我假设这MAX_LINE是您在fgets或类似函数中使用的最大缓冲区长度。但实际输入通常更小,它包含一个 C 字符串,即以空字符结尾的字符,'\0'. 之后的一切都将是垃圾。因此,您的终止条件应该是while (s[k] != '´\0') ...。因为空字符的值'\0'为零,所以您可以将其写为while (s[k]) ....

if(s[k]==’I’) {
  n=n++
}

这种递增的语法在 C 中是不合法的。(这是一个常见的陷阱,因为它会编译。)如果你想 inctement n,使用 plain n++。或者,您可以使用n = n + 1n += 1

if(s[k]==’v’) {
  n=n+5
}

在这里,您使用了'v'与 upper-case 不同的小写字母'V'

return n;

您从循环内无条件返回,即在第一次迭代之后。那不是你想要的。返回循环后的累加值。

除了在你的情况下,你会有一个无限循环:你的位置标记k永远不会改变。您应该在循环内递增k作为最后一件事。您还可以在更新 部分重写您的whileasfor和 incrementb 。

所以,把它们放在一起:

int romanToInt(const char *s)
{
    int n = 0;
    int k = 0;

    while (s[k]) {
        if (s[k] == 'I') n++;
        if (s[k] == 'V') n = n + 5;
        if (s[k] == 'X') n = n + 10;
        if (s[k] == 'L') n = n + 50;
        if (s[k] == 'C') n = n + 100;
        if (s[k] == 'D') n = n + 500;
        if (s[k] == 'M') n = n + 1000;
        k++;
    }
    return n;
}

这将累积由大写字母表示的罗马数字(不做 IV 中的减法操作)并忽略其他所有内容。

于 2014-12-01T19:18:37.470 回答