2010-11-22 61 views
1

我决定今天试试euler问题17,并且我很快用C++编写了一个非常快速的代码来解决它。但是,由于某种原因,结果是错误的。 现在的问题是:欧拉项目问题17 - 有什么问题?

如果数字1到5用字写出:1,2,3,4,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; 
} 
+1

对于那些不熟悉Project Euler问题17的人,你可以解释它是什么或至少给出一个链接。如果不知道程序应该做什么,你不能指望人们告诉你问题在哪里。 – ereOn 2010-11-22 13:25:18

+0

哦,是的..忘了这一点。编辑:P – Lockhead 2010-11-22 13:27:00

+2

我建议你用计算机的方式解决你的计算难题:以容易验证的形式得到输出结果 - 打印出每个数字的文本描述,并计算字母数量,然后得到仔细观察,并做一个完整的检查,特别是在比较特殊的情况下。 – 2010-11-22 13:37:36

回答

1

的问题似乎是这一行:

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

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

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

更好的是一个完全不同的结构:编写一个函数,它为一个数字生成一个字符串,然后取这个字符串的长度来进行计算。这也会使调试这样的问题变得更容易,因为你可以看到你正在使用的实际字符串。

+0

谢谢!它现在有效。 :d – Lockhead 2010-11-22 15:29:56

2

四十是mispelt,应该是四十。

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

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

+0

结果仍然不正确= [ – Lockhead 2010-11-22 13:30:36

+0

+1。但对于英文不流利的人来说这么不公平! ;) – ereOn 2010-11-22 13:31:41

+0

增加了第二个修复程序,现在它得到了正确的答案。 – marcog 2010-11-22 13:46:30

4

而不是做你的工作给你:

把它分成更小的功能。 然后您可以独立测试每个功能。

编写一些单元测试,然后如果您需要,或者只是使用调试器并逐步完成,也可以在一小撮纸上进行,并查看您和代码分歧的位置。

+0

+1在几乎所有情况下,拆分和测试零件都会捕获这些类型的错误。 – daramarak 2010-11-22 13:57:44