【问题标题】:C++: Confusion on converting integers to roman numeralsC++:将整数转换为罗马数字的困惑
【发布时间】:2014-03-04 06:51:57
【问题描述】:

我正在为我的 C++ 课程开发一个程序。指导方针是创建一个将整数转换为罗马数字的转换器,规范是我必须至少使用一个 while 语句、do while 语句和一个 switch。

我的代码大部分都在工作,但我不能涉及涉及 4 和 9 的特殊情况(例如 (4, 14, 24 34, etc) 40, (140, 240, etc) 400, (1400, 2400、3400 等)和(9、19、29、39 等)90、(190、290 等)900、9000))为我工作。这是我此时的代码:

#include <iostream>
#include <string>
using namespace std;
int main( )
{ 
   cout << "Please enter  an interger." << endl;
   int num = 0;
   cin >> num;
   string rep = "";     


     switch(num)
   {
      case 40:                                    
      rep += "XL"; 
      num -= 40;                                   
      break;                                     
      case 90:
      rep += "XC";
      num -= 90;
      break;
   }


      if (num >= 1000){
         rep += string(num / 1000,'M');
         num %= 1000;
      }
      if (num >= 500){
          rep += string(num / 500,'D');
          num %= 500;
      }
      if (num >= 100){
          rep += string(num / 100,'C');
          num %= 100;

      }
      if (num >= 50){
          rep += string(num / 50,'L');
          num %= 50;

      }
      if (num >= 10){
          rep += string(num / 10,'X');
          num %= 10;
      }
      if (num >= 5){
          rep += string(num / 5,'V');
          num %= 5;
      }    
      if (num >= 1){
         rep += string(num,'I');
         num %= 1;
      }


      cout << num << endl;
      cout << rep << endl;

    return 0;  
}

【问题讨论】:

  • 那些是一些相当愚蠢的规范。 (你的老师指定的)
  • @nhgrif:好吧,代码的表面目的是将整数转换为罗马数字,但即使它做了一些明显有建设性的事情,这个目标也完全没用。练习的真正目的是学习这三个控制结构,尽管它可能与代码的表面目的无关,但它非常有用。从根本上说,看起来真实的任务不一定是学习语法的最佳方式:-)
  • 这就是为什么我认为规范是愚蠢的。学习语法应该在课堂讲座、测验或作为小家庭作业的一部分:“编写一个 for 循环”。例如。像这样的实际项目不应该有超出整个项目应该完成的要求,并且应该根据学生实施最佳控制结构的能力来评分。
  • @nhgrif:不幸的是,如果你这样做,就会有人抱怨小任务很无聊/抽象/不吸引人等等,甚至比你抱怨罗马数字项目愚蠢的声音还要大。就我个人而言,我喜欢对编程语言进行无聊、抽象、不吸引人的介绍,但我不正常。大多数人也没有达到合理的编程水平。入门练习并不适合他们。
  • 在我的编程课上,我从来没有做过小项目。我们进行了涵盖基本语法的测验(我自己花了 15 分钟在线完成),并且我们的项目一次开放 2-3 周。

标签: c++ string while-loop switch-statement


【解决方案1】:
switch(num)
{
case 40:                                    
   rep += "XL"; 
   num -= 40;                                   
   break;                                     
case 90:
   rep += "XC";
   num -= 90;
   break;
}

它们仅在数字准确无误时才有效 4090。尝试将数字分开而不是比较相等。

【讨论】:

  • 在维护我的项目中应该存在的开关的同时,我该如何做呢?
  • @Titanguy654 不要那样做。
【解决方案2】:

我会首先找到一个合适的算法(谷歌为我提供了有用的结果),然后,在实现它之后,我会找到一种方法来推动所需的三个控制结构。

我怀疑这些要求实际上可能对您有所帮助。例如,让我们考虑一个简单的转换,数字 2000。This should produce "MM"

让我们从这个想法开始。您的算法需要类似于:

while (the number is greater than zero) {
  Check if the number is greater than 1000.  If so, take 1000 off the number and put an "M" in the string.
}

此代码使用 while 循环(您当前的代码缺少某些内容)。

然后您可以继续进行新的测试用例,例如 100。这应该会产生“C”。然后我会在 200 和 300 上工作,从上面获取相同的 while 循环来完成工作。

我在网上找到了一个有趣的算法,它检查大于 400 和小于 500 并将其替换为“CD”。也许这会帮助你思考。

【讨论】:

    【解决方案3】:

    来自http://rosettacode.org/wiki/Roman_numerals/Encode#C.2B.2B

    std::string to_roman(unsigned int value)
    {
        struct romandata_t { unsigned int value; char const* numeral; };
        const struct romandata_t romandata[] =
        {
            {1000, "M"}, {900, "CM"},
            {500, "D"}, {400, "CD"},
            {100, "C"}, { 90, "XC"},
            { 50, "L"}, { 40, "XL"},
            { 10, "X"}, { 9, "IX"},
            { 5, "V"}, { 4, "IV"},
            { 1, "I"},
            { 0, NULL} // end marker
        };
    
        std::string result;
        for (const romandata_t* current = romandata; current->value > 0; ++current)
        {
            while (value >= current->value)
            {
                result += current->numeral;
                value -= current->value;
            }
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-01-09
      • 2011-10-25
      • 2012-10-09
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      • 2021-12-15
      相关资源
      最近更新 更多