2011-03-10 23 views
3

您對這段代碼有什麼看法?這是最好的方法嗎?有什麼改進?羅馬到十進制轉換

Roman.h

#ifndef ROMAN_H 
#define ROMAN_H 

#include <string> 

#include <map> 

typedef unsigned long int UL_I; 
typedef std::map< std::string, UL_I, std::less<std::string> > Map; 

class Roman_Number 
{ 
public: 
    //Constructor 
    Roman_Number(std::string); 

    void Convert_to_decimal(); 

    UL_I get_Decimal() const; 
    std::string get_Roman() const; 

private: 
    std::string s_roman_number; 
    UL_I d_number; 

    Map pairs; 
    Map pairs_substracting; 

    //Utilitaries functions 
    void _validate_(); 
    void _initilize_pairs_() 
    { 
    pairs.insert(Map::value_type("I", 1)); 
    pairs_substracting.insert(Map::value_type ("IV", 4)); 
    pairs.insert(Map::value_type("V", 5)); 
    pairs_substracting.insert(Map::value_type("IX", 9)); 
    pairs.insert(Map::value_type("X", 10)); 
    pairs_substracting.insert(Map::value_type("XL", 40)); 
    pairs.insert(Map::value_type("L", 50)); 
    pairs_substracting.insert(Map::value_type("XC", 90)); 
    pairs.insert(Map::value_type("C", 100)); 
    pairs_substracting.insert(Map::value_type("CD", 400)); 
    pairs.insert(Map::value_type("D", 500)); 
    pairs_substracting.insert(Map::value_type("CM", 900)); 
    } 
    UL_I _recursive_convert(std::string); 
}; 

#endif 

Roman.cpp

#include <iostream> 

#include "Roman.h" 

void Roman_Number::_validate_() 
{ 
    std::cout << "Validating" << std::endl; 

} 

Roman_Number::Roman_Number(std::string r_number) 
{ 
    _initilize_pairs_(); 
    s_roman_number = r_number; 
    d_number = 0; 
} 

void Roman_Number::Convert_to_decimal() 
{ 
    std::string s_aux = s_roman_number; 
    d_number = _recursive_convert(s_aux); 
} 

UL_I Roman_Number::_recursive_convert(std::string new_roman) 
{ 
    if(new_roman == "") 
    return 0; 
    if(pairs_substracting.find(new_roman.substr(0 , 2)) != pairs_substracting.end()) 
    return pairs_substracting[new_roman.substr(0, 2)] + 
     _recursive_convert(new_roman.erase(0, 2)); 
    else 
    return pairs[new_roman.substr(0, 1)] + _recursive_convert(new_roman.erase(0, 1)); 
} 

UL_I Roman_Number::get_Decimal() const 
{ 
    return d_number; 
} 

std::string Roman_Number::get_Roman() const 
{ 
    return s_roman_number; 
} 

的main.cpp

#include <iostream> 

#include "Roman.h" 

int main() { 
    Roman_Number R_N("XIL"); 
    R_N.Convert_to_decimal(); 
    std::cout << R_N.get_Decimal(); 
    return 0; 
} 
+1

[程序員](http://Programmers.stackexchange.com)是一個更好的網站審查請求。還有一個類似的問題[codegolf.stackexchange.com](http://codegolf.stackexchange.com/questions/797/roman-numeral-converter-function) – 2011-03-10 03:24:52

+0

我給它X星的第八。 – 2011-03-10 03:28:25

+0

如果你想對你寫的代碼進行一般評論,我建議使用http://codereview.stackexchange.com/。 – MadcapLaugher 2011-03-10 03:40:33

回答

7

這個怎麼樣? http://codepad.org/mJ05BldC

#include <stdio.h> 

int main(void) { 
    const char* s = "MCDXLIV"; 
    int x = 0; // result 

    int j,m=0; // max used digit 
    const char* p=s, *q; while(*p) ++p; 
    for(--p; p>=s; p--) for(q="IVXLCDM",j=0; *q; q++,j++) if(*p==*q) 
    x += ((j>=m)?m=j,1:-1) * (1+j%4/2*9) * (1+j/4*99) * (1+j%2*4); 

    printf("s=%s x=%i\n", s, x); 
} 
+4

我覺得我的眼睛剛剛爆炸。 – 2011-03-10 04:32:02

+0

我對STL有同感:) – Shelwien 2011-03-10 04:37:45

+0

Shelwien喜歡混淆ppl – 2016-03-02 12:31:06

1

鑑於

public static final String romanNums = "IVXLCDM"; 

public static void main(String[] args) { 
    Scanner console = new Scanner(System.in); 
    String input = console.nextLine(); 

    int arabInt = 0; 
    for (int i = 0; i < romanNums.length(); i++) { 
     for (int j = 0; j < input.length(); j++) { 
      if (input.substring(j, j + 1).equals(romanNums.substring(i, i + 1))) { 
       arabInt += convertRomToNum(i); 
       if (j > 0 && romanNums.indexOf(input.substring(j, j + 1)) > romanNums.indexOf(input.substring(j - 1, j))) { 
       arabInt -= 2 * convertRomToNum(romanNums.indexOf(input.substring(j - 1, j))); 
       } 
      } 
    } 
    // AFTER OBSERVING PATTERN: 1, 5, 10, 50, 100, 500, 1000; AND ASSOCIATING INDEXES 
    // OF EACH ROMAN LETTER WITH CORRESPONDING NUMBER IN SEQUENCE ABOVE 

public static int convertRomToNum(int i) {  
    int numBehindLetter = (int) (Math.pow(2, Math.floor(i/2)) * Math.pow(5, Math.ceil(i/2.))); 
    return numBehindLetter; 
} 

1 = 5^0 * 2^0; 5 = 5^1 * 2^0; 10 = 5^1 * 2^0; 50 = 5^2 * 2^1; 100 = 5^2 * 2^2; 500 = 5^3 * 2^2; 1000 = 5^3 * 2^3等等。這就是爲什麼我使用'floor'和'ceil'功能。