您对此代码有何看法?这是最好的方式吗?有什么改进吗?
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;
}
答案 0 :(得分: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 );
}
答案 1 :(得分: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'功能的原因。
答案 2 :(得分:0)
介于复杂和可读之间......
int convRomanToInt(string roman) {
char[] symbol = { 'M', 'D', 'C', 'L', 'X','V','I' };
int[] weight = { 1000, 500, 100, 50, 10, 5 , 1 };
int res = 0, rom = 0, num = 0;
while (rom < roman.Length){
if (roman[rom] == symbol[num]){
res += weight[num];
rom++;
} else if (rom < roman.Length-1 && roman[rom+1] == symbol[num]){
res -= weight[(num&~1)+2];
rom++;
} else {
num++;
}
}
return res;
}