2013-07-18 96 views
3

這個程序是我剛剛參加的考試的一部分,我必須寫。我只有這麼遠,無法到達任何地方。這裏是提示符:「寫一個測試函數toDecimal(),將羅馬數字(如MMLXVII)轉換爲它的十進制數字表示形式,使用Main()函數測試函數toDecimal()函數應該有2個參數,字符串數組羅馬數字和輔助函數,這個輔助函數將返回羅馬數字中每個字母的數字值,然後將字符串參數轉換爲:查看前兩個字符,如果第一個字符較大,則將第一個字符如果第一個字符小於第二個字符,則從第二個字符中減去第一個字符,然後將結果添加到字符串轉換中,而不驗證它也會轉換字符串,比如「IC」。VAlidate字符串參數,如果有錯誤,調用錯誤處理函數。提供至少兩個錯誤處理函數,並且每個函數都測試toDecimal()。 ct,另一個可能會糾正它。「 I,X,C,M不能連續重複3次以上,D,L,V不能連續重複。我只能從V和X中減去,X只能從中減去L和C,C只能從D和M中減去。V,L和D永遠不能被減去。C++將羅馬數字轉換爲小數

我已經失去了大約2天的睡眠時間,試着用數百種不同的方式使用和打破規則。這是我得到的最接近的。

#include <iostream> 
#include <string> 
#include <map> 
#include <algorithm> 
#include <cstring> 
using namespace std; 

bool checker(string roman); 
// Adds each value of the roman numeral together 
int toDecimal(string, bool* (*function)(string)); 
int convert(string roman, int i); 

int main(){ 
    string roman; 
    cout << "This program takes a roman numeral the user enters then converts it to decimal notation." << endl; 
    cout << "Enter a roman numeral: "; 
    cin >> roman; 
    transform(roman.begin(), roman.end(), roman.begin(), toupper); 
    cout << roman << " is equal to " << toDecimal(roman, *checker(roman)) << endl; 
} 

bool checker(string roman){ 
    int length = roman.length(); 
    for (int count = 0; count < length; count++){ 
     string sub = roman.substr(count, count); 
     if(sub != "I" || sub != "V" || sub != "X" || sub != "L" || sub != "C" || sub != "D" || sub != "M"){ 
      cout << "Error. Try Again"<< endl; 
      return false; 
     } 
     else if(convert(roman, count) == convert(roman, count-1) && convert(roman, count) == convert(roman, count+1)){ 
      if (convert(roman,count) == 1 || convert(roman,count) == 10 || convert(roman,count) == 100 || convert(roman,count) == 1000) 
       if(convert(roman, count-1) == convert(roman, count-2) || convert(roman, count+1) == convert(roman, count+2)){ 
        cout << "Error Try again" << endl; 
        return false; 
       } 
      else if (convert(roman,count) == 5 || convert(roman,count) == 50 || convert(roman,count) == 500){ 
       cout << "Error Try again" << endl; 
        return false; 
      } 
      else return true; 

     }   
    } 
    return true; 
} 

int toDecimal(string s, bool*(checker) (string roman)){ 
    /**map<char, int> roman; 
    roman['M'] = 1000; 
    roman['D'] = 500; 
    roman['C'] = 100; 
    roman['L'] = 50; 
    roman['X'] = 10; 
    roman['V'] = 5; 
    roman['I'] = 1;*/ 
    checker(s); 
    int res = 0; 
    for (int i = 0; i < s.length() - 1; ++i){ 
     int num = convert(s,i); 
     res += num; 
     /**if (roman[s[i]] < roman[s[i+1]]) 
      res -= roman[s[i]]; 
     else 
      res += roman[s[i]]; 
    } 
    res += roman[s[s.size()-1]];*/} 
    return res; 
} 

int convert(string roman, int i){ 
    enum romans {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000}; 
    int num = 0; 
    char c = roman[0]; 
    switch(c){ 
     case 'M': 
      num = M; break; 
     case 'D': 
      if(i + 1 != roman.size() && roman[i+1] == 'M'){ 
       num = M - D;break; 
      } 
      else 
       num = D; break; 
     case 'C': 
      if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D'){ 
       if(roman[i+1] == 'M') num = M - C; break; 
       if(roman[i+1] == 'D') num = D - C; break; 
      } 
      else 
       num = C; break; 
     case 'L': 
      if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'){ 
       if(roman[i+1] == 'M') num = M - L; break; 
       if(roman[i+1] == 'D') num = D - L; break; 
       if(roman[i+1] == 'C') num = C - L; break; 
       } 
      else 
       num = L; break; 
     case 'X': 
      if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L'){ 
       if(roman[i+1] == 'M') num = M - X; break; 
       if(roman[i+1] == 'D') num = D - X; break; 
       if(roman[i+1] == 'C') num = C - X; break; 
       if(roman[i+1] == 'L') num = C - X; break; 
      } 
       num = X; break; 
     case 'V': 
      if(i + 1 != roman.size() && roman[i+1] == 'M' || roman[i+1] == 'D' || roman[i+1] == 'C'|| roman[i+1] == 'L' || roman[i+1] == 'X'){ 
       if(roman[i+1] == 'M') num = M - V; break; 
       if(roman[i+1] == 'D') num = D - V; break; 
       if(roman[i+1] == 'C') num = C - V; break; 
       if(roman[i+1] == 'L') num = L - V; break; 
       if(roman[i+1] == 'X') num = X - V; break; 
      } 
       num = V; break; 
     case 'I': 
      if (i + 1 != roman.size() && roman[i + 1] != 'I'){ 
       if(roman[i+1] == 'M') num = M - I; break; 
       if(roman[i+1] == 'D') num = D - I; break; 
       if(roman[i+1] == 'C') num = C - I; break; 
       if(roman[i+1] == 'L') num = L - I; break; 
       if(roman[i+1] == 'X') num = X - I; break; 
      } 
       num =1; break; 
    } 
    return num; 
} 

**我在這裏添加了人的幫助。這是一個顯示進展/大會的編輯。

+2

什麼不行? –

+0

你正在各個地方定義'enum'值,然後不使用它們 - 這實際上沒有任何用處。 –

+0

很多東西都不起作用。我真的迷失了。我有羅馬枚舉的原因爲什麼被註釋掉了,其他枚舉是這樣我可以嘗試比較「sub」,因爲我不能 – Svanhildr

回答

10

這是我用來將Roman(小於3999)轉換爲Integer的代碼。你可以檢查它是否適用於更大的數字。

int romanToInt(string s) { 
    map<char, int> roman; 
    roman['M'] = 1000; 
    roman['D'] = 500; 
    roman['C'] = 100; 
    roman['L'] = 50; 
    roman['X'] = 10; 
    roman['V'] = 5; 
    roman['I'] = 1; 

    int res = 0; 
    for (int i = 0; i < s.size() - 1; ++i) 
    { 
     if (roman[s[i]] < roman[s[i+1]]) 
      res -= roman[s[i]]; 
     else 
      res += roman[s[i]]; 
    } 
    res += roman[s[s.size()-1]]; 
    return res; 
} 

希望這可以幫助你。

+0

嗨,自從我渴望學習STL以來,我一直在尋找這樣的東西。我想知道如何做相反的事情,字符串羅馬(int num),所以它返回一個整數的羅馬形式。這是否容易扭轉,它只是簡單地顛倒標誌?我失去了在地圖上和雙子... –

+0

@JonWeinraub希望這個鏈接可以幫助你。 https://github.com/AnnieKim/LeetCode/blob/master/IntegertoRoman.h –

2

Annie Kim提供的解決方案工作正常,但它使用了std::map,爲同一個角色多次查詢,我沒有看到它的原因。

int convert_roman_digit(char d) 
{ 
    switch (d) 
    { 
     case 'M': return 1000; 
     case 'D': return 500; 
     case 'C': return 100; 
     case 'L': return 50; 
     case 'X': return 10; 
     case 'V': return 5; 
     case 'I': return 1; 
     default: throw std::invalid_argument("Invalid digit"); 
    } 
} 

int roman_to_int(const std::string& roman) 
{ 
    int result = 0, last_added = 0; 

    for (auto it = roman.rbegin(); it != roman.rend(); ++it) 
    { 
     const int value = convert_roman_digit(*it); 
     if (value >= last_added) 
     { 
      result += value; 
      last_added = value; 
     } 
     else 
     { 
      result -= value; 
     } 
    } 

    return result; 
} 

買者:函數愉快地接受一些無效輸入(例如IMM),包括「負」數字(例如IIIIIIIIIIIIIX),沒有溢出檢查,並且它拋出。隨意改進它。