2014-02-07 161 views
2

我正在爲我的C++課程開發一個程序。準則是創建一個將整數轉換爲羅馬數字的轉換器,規範是我必須至少使用一個while語句,while語句和一個開關。我的代碼大部分工作正常,但我不能涉及涉及4和9的特殊情況(例如(4,14,24 34等)40,(140,240等)400,(1400) ,2400,3400等)和(9,19,29,39等)90,(190,290等)900,9000))爲我工作。這是我在這一點上,代碼:C++:將整數轉換爲羅馬數字時出現混亂

#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; 
} 
+0

這些都是一些非常愚蠢的規格。 (你的老師指定) – nhgrif

+1

@nhgrif:代碼的表面目的是將一個整數轉換爲羅馬數字,但是這個目標完全沒用,即使它做了一些顯然是有建設性的事情。練習的真正目的是學習這三種控制結構,即使它可能與代碼的表面目的無關,這是非常有用的。從根本上說,真正的任務並不一定是學習語法的最佳方式:-) –

+0

這就是爲什麼我認爲規範是愚蠢的。學習語法應該在課堂講座,測驗或作爲微不足道家庭作業任務的一部分完成:「寫一個for循環。」例如。像這樣的實際項目不應該超出程序應該作爲一個整體來完成的要求,並且應該對學生實施最佳控制結構的能力進行評分。 – nhgrif

回答

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

他們只當數是準確4090工作。嘗試分離數字而不是比較平等。

+0

我該如何去做,同時保持應該存在於我的項目中的開關? – Titanguy654

+0

@ Titanguy654只是不要那樣做。 – xis

0

我會先找到一個合適的算法(Google爲我生成有用的結果),然後在實現它之後,我會找到一種方法來推動所需的三個控制結構。

我懷疑這些要求可能真正幫助你。例如,讓我們考慮一個簡單的轉換,數字爲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上工作,從上面開始做同樣的工作。

我在網上發現了一個有趣的算法,檢查了大於400和小於500,並用「CD」代替。也許這會幫助你的思考。

0

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