C++ 罗马到十进制的转换

C++ 罗马到十进制的转换,c++,recursion,roman-numerals,C++,Recursion,Roman Numerals,你觉得这个代码怎么样?这是最好的方式吗?有什么改进吗 罗曼·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 { pub

你觉得这个代码怎么样?这是最好的方式吗?有什么改进吗

罗曼·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
\ifndef ROMAN\u H
#定义ROMAN_H
#包括
#包括
typedef无符号长整数UL_I;
typedef std::map>map;
类罗马_数
{
公众:
//建造师
罗马数字(标准::字符串);
void Convert_to_decimal();
我得到十进制常数;
std::string get_Roman()常量;
私人:
std::字符串s_罗马_编号;
UL_I d_编号;
地图对;
映射对相减;
//实用功能
无效;
void _initilize_pairs u()
{
insert(Map::value_type(“I”,1));
pairs_substrating.insert(Map::value_type(“IV”,4));
插入(Map::value_type(“V”,5));
pairs_substrating.insert(Map::value_type(“IX”,9));
插入(Map::value_type(“X”,10));
pairs_substrating.insert(Map::value_type(“XL”,40));
插入(Map::value_type(“L”,50));
pairs_substrating.insert(Map::value_type(“XC”,90));
插入(Map::value_type(“C”,100));
pairs_substrating.insert(Map::value_type(“CD”,400));
插入(Map::value_type(“D”,500));
pairs_substrating.insert(Map::value_type(“CM”,900));
}
UL_I_递归_转换(std::string);
};
#恩迪夫
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;
}
#包括
#包括“Roman.h”
无效罗马编号::_验证()
{
这个怎么样

#包括
内部主(空){
const char*s=“MCDXLIV”;
int x=0;//结果
int j,m=0;//最大使用位数
常量char*p=s,*q;而(*p)++p;
对于(--p;p>=s;p--)对于(q=“IVXLCDM”,j=0;*q;q++,j++)如果(*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);
}
给定

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;
}
公共静态最终字符串romanums=“IVXLCDM”;
公共静态void main(字符串[]args){
扫描仪控制台=新扫描仪(System.in);
字符串输入=console.nextLine();
int-arabInt=0;
for(int i=0;i0&&romanums.indexOf(input.substring(j,j+1))>romanums.indexOf(input.substring(j-1,j))){
arabInt-=2*转换romtonum(romanums.indexOf(input.substring(j-1,j));
}
}
} 
//观察模式后:1、5、10、50、100、500、1000;以及关联指数
//按上述顺序列出每个罗马字母的编号
公共静态整数变换器(整数i){
int numberhindletter=(int)(Math.pow(2,Math.floor(i/2))*Math.pow(5,Math.ceil(i/2));
回信;
}

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”函数。

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;
}
int-convRomanToInt(字符串罗马){
字符[]符号={'M','D','C','L','X','V','I'};
int[]权重={1000,500,100,50,10,5,1};
int res=0,rom=0,num=0;
而(rom
是一个更好的审查请求网站。另外,在我给它的第八版中也有一个类似的问题。如果你想对你所写的代码发表一般性的评论,我建议你使用。我想我的眼睛已经爆炸了。Shelwien喜欢混淆PPL感谢你的这个代码片段,它可能会提供一些有限的、即时的帮助。一个正确的解释通过展示为什么这是一个很好的问题解决方案,将极大地提高其长期价值,并使其对未来读者提出其他类似问题更有用。请编辑您的答案,添加一些解释,包括您所做的假设。
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;
}
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;
}