【问题标题】:Project Euler Problem 17 - What's wrong?欧拉计划问题 17 - 怎么了?
【发布时间】:2011-05-13 20:20:44
【问题描述】:

我今天决定尝试项目 euler 问题 17,我很快用 C++ 编写了一个非常快的代码来解决它。但是,由于某种原因,结果是错误的。 问题是:

如果数字 1 到 5 用单词写出:一、二、三、四、五,那么总共使用了 3 + 3 + 5 + 4 + 4 = 19 个字母。

如果从 1 到 1000(包括一千)的所有数字都用文字写出来,会使用多少个字母?

注意:不要计算空格或连字符。例如,342(三百四十二)包含 23 个字母,而 115(一百一十五)包含 20 个字母。写出数字时使用“and”符合英国用法。

我真的不知道为什么,因为我已经彻底检查了程序的每个部分,我找不到任何错误。我能找到的唯一不好的是在检查 1000 时,我的 while 循环没有正确检查。我通过将我的while循环的限制降低到

int getDigit (int x, int y)
{
 return (x / (int)pow(10.0, y)) % 10;
}

int main()
{
 string dictionary[10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
 string dictionary2[18] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
 string dictionary3[10] = { "onehundred", "twohundred", "threehundred", "fourhundred", "fivehundred", "sixhundred", "sevenhundred", "eighthundred", "ninehundred", "onethousand" };

 int i = 1;
 int last;
 int first;
 int middle;

 _int64 sumofletters = 0;

 while (i < 10)     //OK
 {
  sumofletters += dictionary[i].length();

  i++;
 }

 cout << sumofletters << endl;

 while (i < 20)     //OK
 {
  last = i % 10;

  sumofletters += dictionary2[last].length();

  i++;
 }

 while (i < 100)     //OK 
 {
  first = (i / 10) + 8;
  last = i % 10;

  if (last != 0)
  {
   sumofletters += dictionary2[first].length() + dictionary[last].length();
  }

  else
   sumofletters += dictionary2[first].length();

  i++;
 }

 cout << sumofletters << endl;

 while (i < 1000)       //OK
 {
  last = i % 10;
  first = (i / 100) - 1;
  middle = (getDigit(i, 1)) + 8;

  if (middle != 0 && last != 0)   //OK
  {
   if (middle == 1)
    sumofletters += dictionary3[first].length() + dictionary2[last].length() + 3;
   else
    sumofletters += dictionary3[first].length() + dictionary2[middle].length() + dictionary[last].length() + 3;
  }

  else if (last == 0 && middle != 0)  //OK
  {
   if (middle == 1)
    sumofletters += dictionary3[first].length() + 6;
   else
    sumofletters += dictionary3[first].length() + dictionary2[middle].length() + 3;
  }

  else if (middle == 0 && last != 0)   //OK
   sumofletters += dictionary3[first].length() + dictionary[last].length() + 3;

  else
   sumofletters += dictionary3[first].length();

  i++;
 }

 sumofletters += 11;

 cout << sumofletters << endl;

 return 0;
}

【问题讨论】:

  • 对于不熟悉Project Euler问题17的人,您可以解释它是什么或至少给出一个链接。如果人们不知道程序应该做什么,你不能指望他们告诉你问题出在哪里。
  • 哦,是的..忘记了。已编辑:P
  • 我建议您以计算方式解决您的计算难题:以易于验证的形式获取输出 - 打印出每个数字的文字描述以及您对字母数量的计算,然后仔细检查并进行健全性检查,尤其是在更不寻常的情况下。
  • 谢谢..但是..这不是和我按相反顺序做的基本相同吗?如果不是,我仍然很想看看我当前的代码有什么问题 - 以节省未来的问题。
  • 为什么不使用字符串的长度而不是字符串文字,此外,如果您缓存 1-99 的所有数字的长度,您可以将它们重用于接下来的 9 100s 值 - 虽然这不一定是 DP 问题。

标签: c++ c letters


【解决方案1】:

而不是为你做你的工作:

将其拆分为更小的函数。 然后你就可以独立测试每个函数了。

如果需要,然后编写一些单元测试,或者只是使用调试器并单步执行,也可以在纸上进行,看看你和你的代码在哪里分歧。

【讨论】:

  • +1 拆分和测试部件几乎可以在所有情况下捕获此类错误。
【解决方案2】:

fourty 拼错了,应该是四十。

检查您的比较中间 == 0 / 中间!= 0 / 中间 = 0。回头看看你计算中间的位置。错了。

解决这两个问题会得到正确的答案。

【讨论】:

  • +1。但是对于英语不流利的人来说太不公平了! ;)
【解决方案3】:

问题似乎出在这一行:

middle = (getDigit(i, 1)) + 8; 

你在这个数字上加 8 - 大概是作为你的 dictionary2 的偏移量 - 但在下面的 if 语句中,你有需要为 0 的情况。除非 getDigit 返回 -8,否则这些情况永远不会满足.

与其在此处添加偏移量,不如在需要时添加它 - 或者更好的是,不要将这些内容存储在同一个字典中。

更好的是完全不同的结构:编写一个生成数字字符串的函数,然后获取该字符串的长度进行计数。这也将使调试此类问题变得更加容易,因为您可以看到实际的字符串长度。

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多