项目欧拉问题17 - 出了什么问题?

时间:2010-11-22 13:23:08

标签: c++ c letters

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

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

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

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

我真的不知道为什么,因为我已经彻底检查了我的程序的每一部分,我找不到任何错误。我能找到的唯一不好的是检查1000时,我的while循环没有正确检查。我通过将while循环的限制降低到< 1000而不是< 1001并且只是手动地将11(onethousand = 11)加到总和来修复了这个问题。然而,它不起作用。如果你能告诉我什么是错的,我真的很感激。我确定我的代码非常糟糕,但它只需几分钟即可完成。所以这就是:

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;
}

3 个答案:

答案 0 :(得分:4)

而不是为你工作:

将其拆分为较小的功能。 然后你可以独立测试每个功能。

如果需要,写一些单元测试,或者只是使用调试器并逐步完成并在一些纸上进行,看看你和你的代码在哪里分开。

答案 1 :(得分:2)

四十四是错误的,应该四十岁。

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

修复这两个问题得到了正确答案。

答案 2 :(得分:1)

问题似乎在于这一行:

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

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

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

更好的是一个完全不同的结构:编写一个为数字生成字符串的函数,然后将该字符串的长度用于计数。这样也可以更容易地调试这样的问题,因为你可以看到你所花费的实际字符串。