代码之家  ›  专栏  ›  技术社区  ›  Lockhead

欧拉问题17-怎么了?

  •  1
  • Lockhead  · 技术社区  · 15 年前

    我决定今天尝试项目Euler问题17,我很快写了一个很快的代码在C++中解决它。然而,由于某种原因,结果是错误的。 问题是:

    如果数字1到5是用单词写出来的:1,2,3,4,5,那么总共有3+3+5+4+4=19个字母。

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

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

    我真的不知道为什么,因为我已经彻底检查了我的程序的每一部分,我找不到任何错误。唯一不好的是当检查1000时,while循环没有正确检查。我通过将while循环的限制降低到<1000而不是<1001来修正了这个问题,并在总和中手动添加了11(一个小时=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 回复  |  直到 11 年前
        1
  •  1
  •   Michael Madsen    15 年前

    问题似乎出在这一行:

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

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

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

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

        2
  •  4
  •   Dynite    15 年前

    而不是为你工作:

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

    如果需要的话,可以编写一些单元测试,或者只使用一个调试器,逐步完成,并在一张纸上完成,看看你和你的代码在哪里有分歧。

        3
  •  2
  •   moinudin    15 年前

    四十岁是不正确的,应该四十岁。

    检查您的比较中间值==0/中间值!=0/中间=0。回去看看你算中间的地方。那是错误的。

    修复两者都得到正确答案。