C++ 将整数转换为罗马数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19266018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:39:47  来源:igfitidea点击:

Converting integer to Roman Numeral

c++

提问by Jim Slatten

I have a test due in about four hours and one of the questions asks us to convert a user-inputed integer up to 100 into a roman numeral. I think my code is very close (I found a youtube video that I sort of used as a guide) but alas my code simply will not work :(. Can anyone spot the errors? EDIT: Ah sry sry sry, the problem is that when it compiles, it gives no Roman numerals. As in I enter a value and it gives me a blank.

我有一个大约四小时后到期的测试,其中一个问题要求我们将用户输入的 100 以内的整数转换为罗马数字。我认为我的代码非常接近(我找到了一个我用作指南的 youtube 视频)但可惜我的代码根本不起作用:(。有人能发现错误吗?编辑:啊,sry sry sry,问题是当它编译时,它没有给出罗马数字。就像我输入一个值一样,它给了我一个空白。

    #include "stdafx.h"
#include <iostream>
#include <string>
    using namespace std;


int main()
{
    string romnum;
    int input;
    int num;
    cout << "Type in an integer: ";
    cin >> input;
    if(( input >= 101) || (input <= 0)) // <-- this is the upper bound
    {
        cout << "\n INVALID INPUT";
    }
    else
    {
        if(input = 100)
        {
            romnum + 'C';

        }
        input %= 100; // gets the remainder after dividing by 100

        if(input <= 10)
        {
            num = (input/10); // now we are dealing with number in 10s place
            if(num == 9)
            {
                romnum += "XC";
            }
            else if(num >= 5)
            {
                romnum += 'L';

                for(int i=0; i < num - 5;i++)
                {
                    romnum += 'X';
                }
            }
            else if(num == 4)
            {
                romnum += "XL";
            }
            else if(num >= 1)
            {
                for(int i=0; i>num; i++)
                {
                    romnum += 'X';
                }
                input %= 10;
            }
            if(num >= 1)
            {
                num = input; //  now we are dealing with number in ones place
                if(num == 9)
                {
                    romnum += "IX";
                }
                else if(num >= 5)
                {
                    romnum += 'V';
                    for(int i=0; i < num - 5; i++)
                    {
                        romnum += 'I';
                    }
                }
                else if(num == 4)
                {
                    romnum += "IV";
                }
                else if(num >= 1)
                {
                    for(int i = 0; i < num; i++)
                    {
                        romnum += 'I';
                    }
                }
        cout << "The Roman Numeral is: " << romnum;

            }
        }



        cout << "The Roman Numeral is: " << romnum;
    }
    int f;
    cin >> f;
    return 0;
}

enter code here

回答by Jarod42

From http://rosettacode.org/wiki/Roman_numerals/Encode#C.2B.2B

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

回答by Neha Agarwal

This code will convert integers (less than 3999) to Roman Numerals.

此代码将整数(小于 3999)转换为罗马数字。

string int_to_roman(int a)
{
    string ans;
    string M[] = {"","M","MM","MMM"};
    string C[] = {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
    string X[] = {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
    string I[] = {"","I","II","III","IV","V","VI","VII","VIII","IX"};
    ans = M[a/1000]+C[(a%1000)/100]+X[(a%100)/10]+I[(a%10)];
    return ans;
}

回答by Some programmer dude

One major problem is here:

一个主要问题在这里:

if(input = 100)

I think you mean

我想你的意思

if(input == 100)

You would have found this very easyif you stepped through your code in a debugger. Remember that a debugger is a programmers best friend, and the first tool to use if things doesn't work as intended.

如果您在调试器中单步调试代码,您会发现这很容易。请记住,调试器是程序员最好的朋友,并且是在事情未按预期工作时使用的第一个工具。

回答by elnigno

I think this can actually be solved much more simply than your attempt, where frankly I fail to understand what you are trying to do (but that's me).

我认为这实际上可以比您的尝试更简单地解决,坦率地说,我无法理解您要做什么(但这就是我)。

Anyway, it can just be a sequence of if/else, not even nested. All you need to do is to check what is the "largest" literal contained in the input number, note it and then subtract the value if represents from the input number. Continue in such a way until you get to 0.

无论如何,它可以只是一个 if/else 序列,甚至不是嵌套的。您需要做的就是检查输入数字中包含的“最大”文字是什么,记下它,然后从输入数字中减去表示的值。以这种方式继续,直到达到 0。

e.g. (I'm not sure this is C++ syntax, but you can adjust it of course):

例如(我不确定这是 C++ 语法,但你当然可以调整它):

string roman = ""
if(input == 100)
{
    roman += "C";
    input -= 100;
}

if(input >= 50)
{
    roman += "L";
    input -= 50;
}

And so on, you can figure the rest out on your own (it's your test after all).

依此类推,您可以自己解决其余的问题(毕竟这是您的测试)。

Two things:

两件事情:

  • some literals can be repeated (3: III, 20: XX).
  • writing e.g. "XXXX" for 40 instead of "XL" is still a valid roman number (although less common), so if I were evaluating your test I would accept it, but that depends on the assignment. (http://en.wikipedia.org/wiki/Roman_numerals)
  • 一些文字可以重复(3:III,20:XX)。
  • 例如,用“XXXX”表示 40 而不是“XL”仍然是一个有效的罗马数字(虽然不太常见),所以如果我正在评估您的测试,我会接受它,但这取决于作业。( http://en.wikipedia.org/wiki/Roman_numerals)

回答by MSalters

Joachim found the first problem, this code is always executed and overwrite input with 100.

Joachim 发现了第一个问题,这段代码总是被执行并用 100 覆盖输入。

    if(input = 100)
    {
        romnum + 'C';

    }

Now, why don't you see anything? That's because you miss another=. All other code correctly uses +=but this uses +. As a result, this doesn't assign the resulting string back to romnum.

现在,你为什么什么都看不到?那是因为你错过了另一个=。所有其他代码都正确使用,+=但这使用+. 因此,这不会将结果字符串分配回romnum.

BTW, since romnumis still empty, you can use romnum = 'C'or romnum += 'C'interchangeably.

顺便说一句,由于romnum仍然是空的,您可以使用romnum = 'C'romnum += 'C'互换。

回答by user2338150

I wrote this for fun; maybe useful. Note however, that it will not work for values greater than 1000. Can adapt it to suit your needs though. Here you go:

我写这个是为了好玩;也许有用。但是请注意,它不适用于大于 1000 的值。不过可以对其进行调整以满足您的需要。干得好:

enum roman_digits{
    I=1,
    V=5,
    X=10,
    L=50,
    C=100,
    D=500,
    M=1000
};

std::string lookup(roman_digits v) {
    switch (v) {
    case I:
        return "I";
    case V:
        return "V";
    case X:
        return "X";
    case L:
        return "L";
    case C:
        return "C";
    case D:
        return "D";
    case M:
        return "M";
    default:
        return NULL;
    }
}

std::string to_roman(const int value) {
    roman_digits weight[] = { I, V, X, L, C, D, M };
    std::string result;
    int t;
    int i;

    if (value == 0) {
        return NULL;
    } else {
        unsigned int i;
        for (i = 0; i < sizeof(weight) / sizeof(roman_digits); ++i) {
            if (value == weight[i]) {
                return lookup(weight[i]);
            }
        }
    }
    i = 0;
    t = value;
    while (t > 0) {
        t = value;
        t /= weight[i++];
    }
    --i;
    int prev_wt_sub = i % 2 ? (i - 1) : (i - 2);
    if ((weight[i] - weight[prev_wt_sub]) < value) {
        result += lookup(weight[prev_wt_sub]) + lookup(weight[i]) +
                to_roman(value - (weight[i] - weight[prev_wt_sub]));
    } else if ((weight[i] - weight[prev_wt_sub]) > value) {
        prev_wt_sub += (value / weight[prev_wt_sub + 1] ? 1 : 0);
        result += lookup(weight[prev_wt_sub]) +
                to_roman(value - weight[prev_wt_sub]);
    } else {
        result += lookup(weight[prev_wt_sub]) + lookup(weight[i]);
    }

    return result;
}

回答by Thrishool MSM

//java code

//java代码

import java.io.*;

导入 java.io.*;

public class NumberToRoman {

公共类 NumberToRoman {

public static void main(String[] args) throws IOException{


    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Enter any number");
    int  num= Integer.parseInt(br.readLine());

     NumberToRoman n = new  NumberToRoman();
     n.conversion(num);

    }




public void conversion(int y) {
    int i=0;

    int decimal[] = {1000,900,500,400,100,90,50,10,9,5,4,1};
    String roman[]= {"M","CM","D","CD","C","XC","L","X","IX","V","IV","I"};
    while(y!=0) {
          while(y/decimal[i]!=0) {
              System.out.print(roman[i]);
              y=y-decimal[i];


          }
          i++;

    }


}

}

}

回答by Hardik Hariyani

Function to Convert Decimal to Roman Numrals string toLongRoman(int x) {

将十进制转换为罗马数字字符串的函数 toLongRoman(int x) {

string Romanvalue;

string  Roman[13] = { "M","CM","D","CD", "C","XC", "L","XL", "X","IX","V","IV", "I" };
int Numbers[13] = { 1000, 900, 500,400, 100,90,50,40,10,9,5,4,1 };

for (int index = 0; index < 13; index++) {



        while (x >= Numbers[index]) {
            Romanvalue += Roman[index];


            x -= Numbers[index];

        }
    }

    return Romanvalue;

回答by Rik

Here's my solution. A bit brute force-ish and could be refactored but actually runs pretty fast and was easy to debug (ran perfectly first try). It does have nested ifs so that you never check the 100s, 1000s etc if there are no 10s.

这是我的解决方案。有点蛮力,可以重构,但实际上运行得非常快并且易于调试(首次尝试运行完美)。它确实有嵌套的 ifs,所以如果没有 10s,你永远不会检查 100s、1000s 等。

   string intToRoman(int num) {
            string retVal="";
            int ones=num%10;
            cout<<ones<<endl;
            int onesRest=(num-ones)/10;
                switch (ones){
                    case 1:
                        retVal="I";
                        break;
                    case 2:
                        retVal="II";
                        break;
                    case 3:
                        retVal="III";    
                        break;
                    case 4:
                        retVal="IV";
                        break;
                    case 5:
                        retVal="V";    
                        break;
                    case 6:
                        retVal="VI";
                        break;
                    case 7:
                        retVal="VII";    
                        break;
                    case 8:
                        retVal="VIII";
                        break;
                    case 9:
                        retVal="IX";
                        break;
                }

            if(onesRest>0){
                int tens=onesRest%10;
                int tensRest=(onesRest-tens)/10;            
                switch (tens){
                    case 1:
                        retVal="X"+retVal;
                        break;
                    case 2:
                        retVal="XX"+retVal;
                        break;
                    case 3:
                        retVal="XXX"+retVal;   
                        break;
                    case 4:
                        retVal="XL"+retVal;
                        break;
                    case 5:
                        retVal="L"+retVal;   
                        break;
                    case 6:
                        retVal="LX"+retVal;
                        break;
                    case 7:
                        retVal="LXX"+retVal;  
                        break;
                    case 8:
                        retVal="LXXX"+retVal;
                        break;
                    case 9:
                        retVal="XC"+retVal;
                        break;

            }
            if(tensRest>0){
                int hundreds=tensRest%10;
                int hundredsRest=(tensRest-hundreds)/10;            
                switch (hundreds){
                    case 1:
                        retVal="C"+retVal;
                        break;
                    case 2:
                        retVal="CC"+retVal;
                        break;
                    case 3:
                        retVal="CCC"+retVal;   
                        break;
                    case 4:
                        retVal="CD"+retVal;   
                        break;
                    case 5:
                        retVal="D"+retVal;      
                        break;            
                    case 6:
                        retVal="DC"+retVal;   
                        break;
                    case 7:
                        retVal="DCC"+retVal;       
                        break;
                    case 8:
                        retVal="DCCC"+retVal;   
                        break;
                    case 9:
                        retVal="CM"+retVal;      
                        break;
                }
                if(hundredsRest>0){
                    int thousands=hundredsRest%10;           
                    switch (thousands){
                        case 1:
                            retVal="M"+retVal;   
                            break;
                        case 2:
                            retVal="MM"+retVal;   
                            break;
                        case 3:
                            retVal="MMM"+retVal;     
                            break;    
                    }

                }  
            }    
        }
            return retVal;
        }