【问题标题】:I am trying to figure out how to convert roman numerals into integers我想弄清楚如何将罗马数字转换为整数
【发布时间】:2013-07-17 23:02:01
【问题描述】:

我想弄清楚如何将罗马数字转换为整数。这是我的代码的一部分。当我提示用户输入 M 时,它显示 1000,但是当我提示用户输入一个罗马数字(如 VM)时,它没有给我 995 而是 1005。这是因为我告诉我的程序这样做。

我想弄清楚的是如何向前看并让它知道它何时添加或减去罗马数字。

我该如何开始做这件事?

class Roman
{

    public int inprogress = 0;
    public Roman(string roman)
    {

        char temp = 'Z';
        int length;

        length = roman.Length;

        for (int i = 0; i < length; i++)
        {
            temp = roman[i];
            if (temp == 'M')
            {
                inprogress = inprogress + 1000;
            }
            if (temp == 'D')
            {
                inprogress = inprogress + 500;
            }
            if (temp == 'C')
            {
                inprogress = inprogress + 100;
            }
            if (temp == 'L')
            {
                inprogress = inprogress + 50;
            }
            if (temp == 'X')
            {
                inprogress = inprogress + 10;
            }
            if (temp == 'V')
            {
                inprogress = inprogress + 5;
            }
            if (temp == 'I')
            {
                inprogress = inprogress + 1;
            }
        }
    }
}

【问题讨论】:

  • 您的主题是“将整数转换为罗马数字”,但您的代码显示的是“将罗马数字转换为整数”。你真正问的是哪一个? (他们是相反的。)请edit你的问题并澄清你在问什么。
  • 一点建议:在编写这样的解决方案时,如果您弄清楚您将如何解决问题,然后编写该解决方案,将会更容易。拿出一张纸,试着想出一种方法来正确计算一些样本的罗马数字(只使用数字和其他东西,你不是在纸上写代码!)。然后,编写该解决方案的代码。
  • 您能解释一下您所说的“向前看”是什么意思吗?我可能会帮助您?附言。你正在做不必要的 if 检查,要么使用 switch/case,要么将所有 if 语句,但第一个语句更改为 ''else if'。
  • 罗马数字转整数就是我的意思。
  • 顺便说一句,罗马人在公元 1 年左右没有使用像“IV”这样的减法原理,意思是 4。减法的使用要晚得多(大约 13 世纪)。在“罗马”时代,IV 和 VI 的含义相同: 6. 更多的是关于艺术而非地位。因此,不考虑这种减法原则的 OP 方法更“罗马”而不是欧洲。

标签: c# roman-numerals


【解决方案1】:

转换罗马数字的诀窍是向后(从字符串的末尾)而不是向前工作,这样会更容易。

例如,如果你有 IX

  • 你从 X 开始,= 10
  • 后退 1.... 现在它的 I,I 小于 X,所以现在减去 1 = 9

参考解决方案....

public class RomanNumeral
    {
        public static int ToInt(string s)
        {
              var last = 0;
              return s.Reverse().Select(NumeralValue).Sum(v =>
              {                    
                var r = (v >= last)? v : -v;
                last = v;
                return r;
              });
        }

        private static int NumeralValue(char c)
        {
            switch (c)
            {
                case 'I': return 1;
                case 'V': return 5;
                case 'X': return 10;
                case 'L': return 50;
                case 'C': return 100;
                case 'D': return 500;
                case 'M': return 1000;                    
            }
            return 0;
        }
    }

注意:这不会验证罗马数字,只是转换已经有效的数字。

【讨论】:

  • 另外值得注意的是,这是一个经典的编码kata(连同保龄球游戏)codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals
  • 这个问题对我来说可能太难了。这不是一个等级,但我认为它是书本上的整洁。我相信我对语言的了解不够。
  • 这是一个很好的问题,你只需要知道循环和if语句,一开始就会感到沮丧。斗争很重要,因为你有“啊哈”的时刻,然后事情开始变得更有意义
  • 我意识到 4 周并不是真正的编码时间。这是我做错的事情。我做 if('I'
  • @user2593398 我有你的答案
【解决方案2】:
 List<Level> levels = new List<Level>();
    int[] val = new int[255];
    private void Form1_Load(object sender, EventArgs e)
    {

        val[(byte)'I'] = 1;
        val[(byte)'V'] = 5;
        val[(byte)'X'] = 10;
        val[(byte)'L'] = 50;
        val[(byte)'C'] = 100;
        val[(byte)'D'] = 500;
        val[(byte)'M'] = 1000;
        levels.Clear();
        levels.Add(new Level('I', 'V', 'X'));
        levels.Add(new Level('X', 'L', 'C'));
        levels.Add(new Level('C', 'D', 'M'));
    }
    int fromRoman(string n)
    {
        n = n.ToUpper();

        var result = 0;
        var lastDigit = 0;
        for (var pos = n.Length - 1; pos >= 0; pos--)
        {
            var curDigit = val[(byte)n[pos]];


            if (curDigit >= lastDigit)
                result += curDigit;
            else
                result -= curDigit;

            lastDigit = curDigit;
        }

        return result;
    }
    public class Level
    {
        public Level(char i, char v, char x)
        {
            this.i = i;
            this.x = x;
            this.v = v;
        }
        public char i;
        public char v;
        public char x;
    }

然后运行

int Result =  fromRoman("X");

【讨论】:

  • 为什么要将chars 转换为bytes?
  • 因为我必须给数组中的元素一个索引号。
【解决方案3】:

您需要添加基本上表示如果 V 在 M 之前然后减去它的逻辑。基于这里的这一行:

如果(温度 == 'V') { 进行中 = 进行中 + 5;

【讨论】:

    猜你喜欢
    • 2019-01-09
    • 2011-10-25
    • 2012-10-09
    • 1970-01-01
    • 2020-05-11
    • 2021-12-15
    • 2011-09-10
    相关资源
    最近更新 更多