将整数转换为罗马数字

时间:2011-08-12 12:46:39

标签: c# c#-3.0 roman-numerals

我正在尝试编写一个将数字转换为罗马数字的函数。到目前为止这是我的代码;但是,它只适用于小于400的数字。是否有一种快速简便的方法来执行此转换,或扩展现有代码以便处理所有情况?提前感谢您的帮助。

static string convertroman(int number)
    {
        int l = number / 10;
        StringBuilder sb = new StringBuilder();
        for (int m = 0; m <= l; m++)
        {
            if (l == 0)
            {
                break;
            }
            if (l == 5)
            {
                sb = sb.Append(ro.L.ToString());
                break;
            }
            if (l == 4)
            {
                sb = sb.Append(ro.X.ToString()).Append(ro.L.ToString());
                break;
            }
            if (l == 9)
            {
                sb = sb.Append(ro.X.ToString()).Append(ro.C.ToString());
                break;
            }
            if (l == 10)
            {
                sb = sb.Append(ro.C.ToString());
                break;
            }

            if (l > 5 && l < 9)
            {
                sb = sb.Append(ro.L.ToString());
                l = l - 5;
                m = 0;
                // break;
                continue;
            }
            if (l > 10)
            {
                sb = sb.Append(ro.C.ToString());
                l = l - 10;
                m = 0;
                // continue;

            }
            else
            {
                sb = sb.Append(ro.X.ToString());
            }

        }
        int z = number % 10;
        for (int x = 0; x <= z; x++)
        {
            if (z == 0)
            {
                break;
            }
            if (z == 5)
            {
                sb = sb.Append(ro.V.ToString());
                break;
            }
            if (z == 4)
            {
                sb = sb.Append(ro.I.ToString()).Append(ro.V.ToString());
                break;
            }
            if (z == 9)
            {
                sb = sb.Append(ro.I.ToString()).Append(ro.X.ToString());
                break;
            }
            if (z == 10)
            {
                sb = sb.Append(ro.X.ToString());
                break;
            }
            if (z > 5 && z < 9)
            {
                sb = sb.Append(ro.V.ToString());
                z = z - 5;
                x = 0;
            }
            else
            {
                sb.Append(ro.I.ToString());
            }              

        }
        return sb.ToString();           
    }

28 个答案:

答案 0 :(得分:91)

试试这个,简单紧凑:

public static string ToRoman(int number)
{
    if ((number < 0) || (number > 3999)) throw new ArgumentOutOfRangeException("insert value betwheen 1 and 3999");
    if (number < 1) return string.Empty;            
    if (number >= 1000) return "M" + ToRoman(number - 1000);
    if (number >= 900) return "CM" + ToRoman(number - 900); 
    if (number >= 500) return "D" + ToRoman(number - 500);
    if (number >= 400) return "CD" + ToRoman(number - 400);
    if (number >= 100) return "C" + ToRoman(number - 100);            
    if (number >= 90) return "XC" + ToRoman(number - 90);
    if (number >= 50) return "L" + ToRoman(number - 50);
    if (number >= 40) return "XL" + ToRoman(number - 40);
    if (number >= 10) return "X" + ToRoman(number - 10);
    if (number >= 9) return "IX" + ToRoman(number - 9);
    if (number >= 5) return "V" + ToRoman(number - 5);
    if (number >= 4) return "IV" + ToRoman(number - 4);
    if (number >= 1) return "I" + ToRoman(number - 1);
    throw new ArgumentOutOfRangeException("something bad happened");
}

答案 1 :(得分:20)

这是一个更简单的算法 - 请原谅我,我不知道C#所以我用JavaScript写这个,但应该应用相同的算法(我已经评论过,你可以理解算法):

function intToRoman(int) {

    // create 2-dimensional array, each inner array containing 
    // roman numeral representations of 1-9 in each respective 
    // place (ones, tens, hundreds, etc...currently this handles
    // integers from 1-3999, but could be easily extended)
    var romanNumerals = [
        ['', 'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix'], // ones
        ['', 'x', 'xx', 'xxx', 'xl', 'l', 'lx', 'lxx', 'lxxx', 'xc'], // tens
        ['', 'c', 'cc', 'ccc', 'cd', 'd', 'dc', 'dcc', 'dccc', 'cm'], // hundreds
        ['', 'm', 'mm', 'mmm'] // thousands
    ];

    // split integer string into array and reverse array
    var intArr = int.toString().split('').reverse(),
        len = intArr.length,
        romanNumeral = '',
        i = len;

    // starting with the highest place (for 3046, it would be the thousands 
    // place, or 3), get the roman numeral representation for that place 
    // and append it to the final roman numeral string
    while (i--) {
        romanNumeral += romanNumerals[ i ][ intArr[i] ];
    }

    return romanNumeral;

}

console.log( intToRoman(3046) ); // outputs mmmxlvi

答案 2 :(得分:16)

我创建了这个decimal <=> roman

的类
public static class Roman
{
    public static readonly Dictionary<char, int> RomanNumberDictionary;
    public static readonly Dictionary<int, string> NumberRomanDictionary;

    static Roman()
    {
        RomanNumberDictionary = new Dictionary<char, int>
        {
            { 'I', 1 },
            { 'V', 5 },
            { 'X', 10 },
            { 'L', 50 },
            { 'C', 100 },
            { 'D', 500 },
            { 'M', 1000 },
        };

        NumberRomanDictionary = new Dictionary<int, string>
        {
            { 1000, "M" },
            { 900, "CM" },
            { 500, "D" },
            { 400, "CD" },
            { 100, "C" },
            { 50, "L" },
            { 40, "XL" },
            { 10, "X" },
            { 9, "IX" },
            { 5, "V" },
            { 4, "IV" },
            { 1, "I" },
        };
    }

    public static string To(int number)
    {
        var roman = new StringBuilder();

        foreach (var item in NumberRomanDictionary)
        {
            while (number >= item.Key)
            {
                roman.Append(item.Value);
                number -= item.Key;
            }
        }

        return roman.ToString();
    }

    public static int From(string roman)
    {
        int total = 0;

        int current, previous = 0;
        char currentRoman, previousRoman = '\0';

        for (int i = 0; i < roman.Length; i++)
        {
            currentRoman = roman[i];

            previous = previousRoman != '\0' ? RomanNumberDictionary[previousRoman] : '\0';
            current = RomanNumberDictionary[currentRoman];

            if (previous != 0 && current > previous)
            {
                total = total - (2 * previous) + current;
            }
            else
            {
                total += current;
            }

            previousRoman = currentRoman;
        }

        return total;
    }
}

To方法的某些单元测试:

[TestClass]
public class DecimalToRomanTest
{
    [TestMethod]
    public void Roman_1_I()
    {
        Assert.AreEqual("I", Roman.To(1));
    }

    [TestMethod]
    public void Roman_2_II()
    {
        Assert.AreEqual("II", Roman.To(2));
    }

    [TestMethod]
    public void Roman_3_III()
    {
        Assert.AreEqual("III", Roman.To(3));
    }

    [TestMethod]
    public void Roman_4_IV()
    {
        Assert.AreEqual("IV", Roman.To(4));
    }

    [TestMethod]
    public void Roman_5_V()
    {
        Assert.AreEqual("V", Roman.To(5));
    }

    [TestMethod]
    public void Roman_9_IX()
    {
        Assert.AreEqual("IX", Roman.To(9));
    }

    [TestMethod]
    public void Roman_10_X()
    {
        Assert.AreEqual("X", Roman.To(10));
    }

    [TestMethod]
    public void Roman_49_XLIX()
    {
        Assert.AreEqual("XLIX", Roman.To(49));
    }

    [TestMethod]
    public void Roman_50_L()
    {
        Assert.AreEqual("L", Roman.To(50));
    }

    [TestMethod]
    public void Roman_100_C()
    {
        Assert.AreEqual("C", Roman.To(100));
    }

    [TestMethod]
    public void Roman_400_CD()
    {
        Assert.AreEqual("CD", Roman.To(400));
    }

    [TestMethod]
    public void Roman_500_D()
    {
        Assert.AreEqual("D", Roman.To(500));
    }

    [TestMethod]
    public void Roman_900_CM()
    {
        Assert.AreEqual("CM", Roman.To(900));
    }

    [TestMethod]
    public void Roman_1000_M()
    {
        Assert.AreEqual("M", Roman.To(1000));
    }

    [TestMethod]
    public void Roman_11984_MMMMMMMMMMMCMLXXXIV()
    {
        Assert.AreEqual("MMMMMMMMMMMCMLXXXIV", Roman.To(11984));
    }
}

From方法的某些单元测试:

[TestClass]
public class RomanToDecimalTest
{
    [TestMethod]
    public void Roman_I_1()
    {
        Assert.AreEqual(1, Roman.From("I"));
    }

    [TestMethod]
    public void Roman_II_2()
    {
        Assert.AreEqual(2, Roman.From("II"));
    }

    [TestMethod]
    public void Roman_III_3()
    {
        Assert.AreEqual(3, Roman.From("III"));
    }

    [TestMethod]
    public void Roman_IV_4()
    {
        Assert.AreEqual(4, Roman.From("IV"));
    }

    [TestMethod]
    public void Roman_V_5()
    {
        Assert.AreEqual(5, Roman.From("V"));
    }

    [TestMethod]
    public void Roman_IX_9()
    {
        Assert.AreEqual(9, Roman.From("IX"));
    }

    [TestMethod]
    public void Roman_X_10()
    {
        Assert.AreEqual(10, Roman.From("X"));
    }

    [TestMethod]
    public void Roman_XLIX_49()
    {
        Assert.AreEqual(49, Roman.From("XLIX"));
    }

    [TestMethod]
    public void Roman_L_50()
    {
        Assert.AreEqual(50, Roman.From("L"));
    }

    [TestMethod]
    public void Roman_C_100()
    {
        Assert.AreEqual(100, Roman.From("C"));
    }

    [TestMethod]
    public void Roman_CD_400()
    {
        Assert.AreEqual(400, Roman.From("CD"));
    }

    [TestMethod]
    public void Roman_D_500()
    {
        Assert.AreEqual(500, Roman.From("D"));
    }

    [TestMethod]
    public void Roman_CM_900()
    {
        Assert.AreEqual(900, Roman.From("CM"));
    }

    [TestMethod]
    public void Roman_M_1000()
    {
        Assert.AreEqual(1000, Roman.From("M"));
    }

    [TestMethod]
    public void Roman_MMMMMMMMMMMCMLXXXIV_11984()
    {
        Assert.AreEqual(11984, Roman.From("MMMMMMMMMMMCMLXXXIV"));
    }
}

答案 3 :(得分:12)

这实际上是一个非常有趣的问题,基于dofactory.com上的反向示例(将罗马数字转换为小数),它很容易扭转模式,并且可能会稍微改进一下。此代码将支持1到3999999之间的数字。

从上下文类开始,这定义了解析器的I / O

public class Context
{
    private int _input;
    private string _output;

    public Context(int input)
    {
        this._input = input;
    }

    public int Input
    {
        get { return _input; }
        set { _input = value; }
    }

    public string Output
    {
        get { return _output; }
        set { _output = value; }
    }
}

一个抽象表达式,它定义了解析操作

public abstract class Expression
{
    public abstract void Interpret(Context value);
}

现在,您需要一个抽象终端表达式,它定义将要执行的实际操作:

public abstract class TerminalExpression : Expression
{
    public override void Interpret(Context value)
    {
        while (value.Input - 9 * Multiplier() >= 0)
        {
            value.Output += Nine();
            value.Input -= 9 * Multiplier();
        }
        while (value.Input - 5 * Multiplier() >= 0)
        {
            value.Output += Five();
            value.Input -= 5 * Multiplier();
        }
        while (value.Input - 4 * Multiplier() >= 0)
        {
            value.Output += Four();
            value.Input -= 4 * Multiplier();
        }
        while (value.Input - Multiplier() >= 0)
        {
            value.Output += One();
            value.Input -= Multiplier();
        }
    }

    public abstract string One();
    public abstract string Four();
    public abstract string Five();
    public abstract string Nine();
    public abstract int Multiplier();
}

然后,定义罗马数字行为的类(注意,香港专业教育学院使用小写的惯例,其中罗马数字在字母上使用一个条形来表示1000次)

class MillionExpression : TerminalExpression
{
    public override string One() { return "m"; }
    public override string Four() { return ""; }
    public override string Five() { return ""; }
    public override string Nine() { return ""; }
    public override int Multiplier() { return 1000000; }
}
class HundredThousandExpression : TerminalExpression
{
    public override string One() { return "c"; }
    public override string Four() { return "cd"; }
    public override string Five() { return "d"; }
    public override string Nine() { return "cm"; }
    public override int Multiplier() { return 100000; }
}
class ThousandExpression : TerminalExpression
{
    public override string One() { return "M"; }
    public override string Four() { return "Mv"; }
    public override string Five() { return "v"; }
    public override string Nine() { return "Mx"; }
    public override int Multiplier() { return 1000; }
}
class HundredExpression : TerminalExpression
{
    public override string One() { return "C"; }
    public override string Four() { return "CD"; }
    public override string Five() { return "D"; }
    public override string Nine() { return "CM"; }
    public override int Multiplier() { return 100; }
}
class TenExpression : TerminalExpression
{
    public override string One() { return "X"; }
    public override string Four() { return "XL"; }
    public override string Five() { return "L"; }
    public override string Nine() { return "XC"; }
    public override int Multiplier() { return 10; }
}
class OneExpression : TerminalExpression
{
    public override string One() { return "I"; }
    public override string Four() { return "IV"; }
    public override string Five() { return "V"; }
    public override string Nine() { return "IX"; }
    public override int Multiplier() { return 1; }
}

几乎在那里,我们需要一个包含解析树的非终结表达式:

public class DecimalToRomaNumeralParser : Expression
{
    private List<Expression> expressionTree = new List<Expression>()
                                                  {
                                                      new MillionExpression(),
                                                      new HundredThousandExpression(),
                                                      new TenThousandExpression(),
                                                      new ThousandExpression(),
                                                      new HundredExpression(),
                                                      new TenExpression(),
                                                      new OneExpression()
                                                  };

    public override void Interpret(Context value)
    {
        foreach (Expression exp in expressionTree)
        {
             exp.Interpret(value);
        }
    }
}

最后,客户端代码:

Context ctx = new Context(123);
var parser = new DecimalToRomaNumeralParser();
parser.Interpret(ctx);
Console.WriteLine(ctx.Output); // Outputs CXXIII

实例:http://rextester.com/rundotnet?code=JJBYW89744

答案 4 :(得分:9)

在一行中,效率不高但有效:

public string RomanNumeralFrom(int number)
{
    return
        new string('I', number)
            .Replace(new string('I', 1000), "M")
            .Replace(new string('I', 900), "CM")
            .Replace(new string('I', 500), "D")
            .Replace(new string('I', 400), "CD")
            .Replace(new string('I', 100), "C")
            .Replace(new string('I', 90), "XC")
            .Replace(new string('I', 50), "L")
            .Replace(new string('I', 40), "XL")
            .Replace(new string('I', 10), "X")
            .Replace(new string('I', 9), "IX")
            .Replace(new string('I', 5), "V")
            .Replace(new string('I', 4), "IV");
}

答案 5 :(得分:4)

以下是来自DotNetSnippets

的简洁解决方案
private string ToRomanNumber(int number)
{
    StringBuilder result = new StringBuilder();
    int[] digitsValues = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
    string[] romanDigits = { "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M" };
    while (number > 0)
    {
        for (int i = digitsValues.Count() - 1; i >= 0; i--)
            if (number / digitsValues[i] >= 1)
            {
                number -= digitsValues[i];
                result.Append(romanDigits[i]);
                break;
            }
    }
    return result.ToString();
}

答案 6 :(得分:4)

希望您能想到的最简单的解决方案:)

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

    return roman;
}   

答案 7 :(得分:3)

虽然我喜欢MosèBottacini的答案,但在这种情况下使用递归会产生一些负面影响。一个是可能的堆栈溢出,因此他限制了数字的上限。虽然,是的,我意识到一个巨大的数字看起来多么荒谬的罗马数字,这仍然是一个限制,不是实现结果所必需的。

此外,由于字符串是不可变的,因为字符串连接的大量使用,他的版本将非常低效。下面是我的方法的修改版本,只使用while循环和StringBuilder。我的版本实际上应该更高性能(尽管我们讨论的是亚毫秒范围内的差异)并且更容易在系统内存上使用。

public static string ToRomanNumeral(this int value)
{
    if (value < 0)
        throw new ArgumentOutOfRangeException("Please use a positive integer greater than zero.");

    StringBuilder sb = new StringBuilder();
    int remain = value;
    while (remain > 0)
    {
        if (remain >= 1000) { sb.Append("M"); remain -= 1000; }
        else if (remain >= 900) { sb.Append("CM"); remain -= 900; }
        else if (remain >= 500) { sb.Append("D"); remain -= 500; }
        else if (remain >= 400) { sb.Append("CD"); remain -= 400; }
        else if (remain >= 100) { sb.Append("C"); remain -= 100; }
        else if (remain >= 90) { sb.Append("XC"); remain -= 90; }
        else if (remain >= 50) { sb.Append("L"); remain -= 50; }
        else if (remain >= 40) { sb.Append("XL"); remain -= 40; }
        else if (remain >= 10) { sb.Append("X"); remain -= 10; }
        else if (remain >= 9) { sb.Append("IX"); remain -= 9; }
        else if (remain >= 5) { sb.Append("V"); remain -= 5; }
        else if (remain >= 4) { sb.Append("IV"); remain -= 4; }
        else if (remain >= 1) { sb.Append("I"); remain -= 1; }
        else throw new Exception("Unexpected error."); // <<-- shouldn't be possble to get here, but it ensures that we will never have an infinite loop (in case the computer is on crack that day).
    }

    return sb.ToString();
}

答案 8 :(得分:3)

为时已晚,可能你已经解决了这个问题,但是这个算法也可以帮到你。

在开始之前,您可以简单地对罗马文字进行分析。对于已知的ASCII集,仅支持0到4000之间的值。如果你想超越,那么你可以定义自己的罗马文字。

在我们开始之前,我们知道在上面给定的范围内,我们可以从七次出现的罗马文字(I,V,X,L,C,D和M)形成一个罗马字符串。

因此,我们从一个简单的查找表开始,基于在另一个函数中计算的索引。未知索引作为空白字符返回。正如我上面所写,可以在需要时添加其他字符:

    /// <summary>
    /// Helper method that looks up a given index to it's roman value.
    /// </summary>
    /// <param name="decimalValue"></param>
    /// <returns>The roman literal corresponding to it's index</returns>
    private char DecimalToRoman(int index)
    {
        switch (index)
        {
            case 1: return 'I';
            case 2: return 'V';
            case 3: return 'X';
            case 4: return 'L';
            case 5: return 'C';
            case 6: return 'D';
            case 7: return 'M';
            default: return ' ';
        }
    }

真正的转换将在这里发生:

    private string ConvertToRoman(string input)
    {
        int index = 0;
        string output = "";

        for (int i = 0; i < input.Length; i++)
        {
            //Some magic here, this formula will calculate the correct starting
            //index of the roman literal to find in the look-up table.
            //Since units, tens and hundreds (up to thousand) can be formed of
            //three roman literals, we need three indices for looking up the
            //correct roman literal.
            index = 2 * (input.Length - (i + 1)) + 1;

            char digit1 = DecimalToRoman(index);
            char digit2 = DecimalToRoman(index + 1);
            char digit3 = DecimalToRoman(index + 2);

            int originalValue = System.Convert.ToInt32(input[i] - '0');

            switch (originalValue)
            {
                case 1:
                case 2:
                case 3: for (int j = 0; j < originalValue; j++)
                        output += digit1.ToString();
                    break;
                case 4: output += digit1.ToString() + digit2.ToString();
                    break;
                case 5: output += digit2.ToString();
                    break;
                case 6:
                case 7:
                case 8: output += digit2.ToString();
                    for (int j = 0; j < originalValue - 5; j++)
                        output += digit1.ToString();
                    break;
                case 9: output += digit1.ToString() + digit3.ToString();
                    break;
            }              
        }
        return output;
    }

就是这样。如果您寻找更多OO设计方法,请接受此帖子上方的答案。解决这种方法的方法很多。

编辑: 请注意,此解决方案也不会作弊(只是查找所有出现的罗马文字):)

答案 9 :(得分:3)

这个版本不像其他人那样“作弊”:它在内部生成带有所有“基本”“可组合”数字的“基础”表。对于懒惰我使用Tuple s,而不是创建专门的类。如果您没有C#4.0,则可以将Tuple<>替换为KeyValuePair<>,将Item1替换为Key,将Item2替换为Value

static Tuple<IList<Tuple<string, int>>, int> GenerateBaseNumbers()
{
    const string letters = "IVXLCDM";

    var tuples = new List<Tuple<string, int>>();
    Tuple<string, int> subtractor = null;

    int num = 1;
    int maxNumber = 0;

    for (int i = 0; i < letters.Length; i++)
    {
        string currentLetter = letters[i].ToString();

        if (subtractor != null)
        {
            tuples.Add(Tuple.Create(subtractor.Item1 + currentLetter, num - subtractor.Item2));
        }

        tuples.Add(Tuple.Create(currentLetter, num));

        bool isEven = i % 2 == 0;

        if (isEven)
        {
            subtractor = tuples[tuples.Count - 1];
        }

        maxNumber += isEven ? num * 3 : num;
        num *= isEven ? 5 : 2;
    }

    return Tuple.Create((IList<Tuple<string, int>>)new ReadOnlyCollection<Tuple<string, int>>(tuples), maxNumber);
}

static readonly Tuple<IList<Tuple<string, int>>, int> RomanBaseNumbers = GenerateBaseNumbers();

static string FromNumberToRoman(int num)
{
    if (num <= 0 || num > RomanBaseNumbers.Item2)
    {
        throw new ArgumentOutOfRangeException();
    }

    StringBuilder sb = new StringBuilder();

    int i = RomanBaseNumbers.Item1.Count - 1;

    while (i >= 0)
    {
        var current = RomanBaseNumbers.Item1[i];

        if (num >= current.Item2)
        {
            sb.Append(current.Item1);
            num -= current.Item2;
        }
        else
        {
            i--;
        }
    }

    return sb.ToString();
}

static void Main(string[] args)
{
    for (int i = 1; i <= RomanBaseNumbers.Item2; i++)
    {
        var calc = FromNumberToRoman(i);

        Console.WriteLine("{1}", i, calc);
    }
}

答案 10 :(得分:1)

我可以提供一种比现有

更简单的方法
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Form1
{
    int[] indx = {
        1,
        2,
        3,
        4,
        5,
        10,
        50,
        100,
        500,
        1000
        // initialize array of integers 
    };
    string[] row = {
        "I",
        "II",
        "III",
        "IV",
        "V",
        "X",
        "L",
        "C",
        "D",
        "M"
        //Carasponding roman letters in for the numbers in the array
    };
        // integer to indicate the position index for link two arrays 
    int limit = 9;
        //string to store output
    string output = "";
    private void Button1_Click(System.Object sender, System.EventArgs e)
    {
        int num = 0;
        // stores the input 
        output = "";
        // clear output before processing
        num = Convert.ToInt32(txt1.Text);
        // get integer value from the textbox
        //Loop until the value became 0
        while (num > 0) {
            num = find(num);
            //call function for processing
        }
        txt2.Text = output;
        // display the output in text2
    }
    public int find(int Num)
    {
        int i = 0;
        // loop variable initialized with 0
        //Loop until the indx(i).value greater than or equal to num
        while (indx(i) <= Num) {
            i += 1;
        }
        // detemine the value of limit depends on the itetration
        if (i != 0) {
            limit = i - 1;
        } else {
            limit = 0;
        }
        output = output + row(limit);
        //row(limit) is appended with the output
        Num = Num - indx(limit);
        // calculate next num value
        return Num;
        //return num value for next itetration 
    }
}

答案 11 :(得分:1)

我试一试,我的解决方案如下:

import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Array2D {

    public static void main(String[] args){
        Scanner num = new Scanner(System.in);
        ArrayList<Integer> number = new ArrayList<Integer>();
        int ber = 0;
        String stop = "";

        System.out.println("Type as many number as you like, to get in reverse order. When done typing number, type STOP: ");
        do{
            try{
                ber = num.nextInt();
                number.add(ber);
            }
            catch(InputMismatchException e){
                stop = num.nextLine();
                e.equals(stop);
            }




        }while(!(stop.equalsIgnoreCase("stop")));

答案 12 :(得分:1)

一个简洁,快速和直接的解决方案

function convertToRoman(num) {

  //Roman numerals to have <= 3 consecutive characters, the distances between deciaml values conform to this
  var decimalValue = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ];
  var romanNumeral = [ 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I' ];
  var num_cp = num; // copy the function parameter into num_cp
  var result = '';

  for (var i=0; i < decimalValue.length; i++){ //itarate through array of decimal values
      //iterate more to find values not explicitly provided in the decimalValue array
    while (decimalValue[i] <= num_cp){
      result += romanNumeral[i];
      num_cp -= decimalValue[i];
    }
  }
  return result;
}

convertToRoman(477);

答案 13 :(得分:1)

数字对应的罗马数字的字符串表示形式。

<Appender>
    ....
    <SMTP name="Mail" subject="Error Log"
        to="${mailTo}" smtpHost="smtp.googlemail.com"
        smtpProtocol="smtps" smtpPort="465" bufferSize="512"
        smtpUsername="${smtpUsername}"
        smtpPassword="${smtpPassword}">
        <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
    </SMTP>
    <Async name="AsyncMail">
        <AppenderRef ref="Mail" />
    </Async>
</Appenders>
<Loggers>
    <Logger name="com.github.kilianB" level="trace">
        <AppenderRef ref="STDOUT" />
        <AppenderRef ref="FILE" />
        <AppenderRef ref="AsyncMail" />
    </Logger>
</Loggers>

答案 14 :(得分:0)

使用javascript

function toRoman(num) {
    var listOfNum = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
    var listOfRoman = ['M', 'CM', 'D', 'CD', "C", 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']

    var numToRoman = '';
    for (let i = 0; i < listOfNum.length; i++) {
        while (num >= listOfNum[i]) {
            numToRoman += listOfRoman[i];
            num -= listOfNum[i];
        }
    }
    return numToRoman;
}

答案 15 :(得分:0)

这是我的努力,构想了扩展性,希望易于理解,虽然可能不是最快的方法。我想完成这作为面试的一部分(非常令人沮丧),尽管需要首先理解该问题才能解决。

它应该是所有数字,可以在这里检查 https://www.calculateme.com/roman-numerals/from-roman

        static void Main(string[] args)
    {

        CalculateRomanNumerals(1674);
    }

    private static void CalculateRomanNumerals(int integerInput)
    {
        foreach (var item in Enum.GetValues(typeof(RomanNumerals)).Cast<int>().Reverse())
        {
            integerInput = ProcessNumber(integerInput, item);
        }

        Console.ReadKey();
    }

    private static int ProcessNumber(int input, int number)
    {
        while (input >= number)
        {
            input -= number;
            Console.Write((RomanNumerals)number);
        }

        return input;
    }

    enum RomanNumerals : int
    {
        I = 1,
        IV = 4,
        V = 5,
        IX = 9,
        X = 10,
        L = 50,
        XC = 90,
        C = 100,
        CD = 400,
        D = 500,
        CM = 900,
        M = 1000
    }

答案 16 :(得分:0)

function log(...data) {
  data.forEach(d => console.log(inspect(d, false, null, true)));
}

答案 17 :(得分:0)

@Backwards_Dave您想要一个最大数目的解决方案,在这里:

public class ConvertDecimalNumberToRomanNumberType
{
    public class RomanNumberType
    {
        public string RomanNumber;
        public int RomanNumberValue;
    }

    public List<RomanNumberType> RomanNumbers;

    public void Initialize()
    {
        RomanNumbers = new List<RomanNumberType>();

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "M", RomanNumberValue = 1000 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "CM", RomanNumberValue = 900 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "D", RomanNumberValue = 500 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "CD", RomanNumberValue = 400 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "C", RomanNumberValue = 100 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "XC", RomanNumberValue = 90 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "L", RomanNumberValue = 50 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "XL", RomanNumberValue = 40 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "X", RomanNumberValue = 10 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "IX", RomanNumberValue = 9 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "V", RomanNumberValue = 5 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "IV", RomanNumberValue = 4 });

        RomanNumbers.Add(new RomanNumberType() { RomanNumber = "I", RomanNumberValue = 1 });
    }

    public string ConvertDecimalNumberToRomanNumber(int GetConvertDecimalNumberToRomanNumber)
    {
        string
            FunctionResult
            , CurrentRomanNumber = "";

        int
            FunctionGet = GetConvertDecimalNumberToRomanNumber
            , DecimalNumberRemaining = FunctionGet;

        foreach(RomanNumberType RomanNumber in RomanNumbers)
            while(RomanNumber.RomanNumberValue <= DecimalNumberRemaining)
            {
                DecimalNumberRemaining -= RomanNumber.RomanNumberValue;

                CurrentRomanNumber += RomanNumber.RomanNumber;
            }

        FunctionResult = CurrentRomanNumber;

        return FunctionResult;
    }
}

用法:

ConvertDecimalNumberToRomanNumberType ConvertDecimalNumberToRomanNumberObject = new ConvertDecimalNumberToRomanNumberType();

ConvertDecimalNumberToRomanNumberObject.Initialize();

var SomeVariable = ConvertDecimalNumberToRomanNumberObject.ConvertDecimalNumberToRomanNumber(1999);

答案 18 :(得分:0)

满足“减法表示法”语义检查的解决方案

当前的解决方案都没有完全满足“减法表示法”的整个规则集。 “ IIII”->是不可能的。每个解决方案的结果均为4。字符串“ CCCC”,“ VV”,“ IC”,“ IM”也是无效的。

https://www.romannumerals.org/converter是检查语义的一个很好的在线转换器,因此,如果您真的想进行完整的语义检查,则要复杂得多。

public class RomanNumerals
{

    private List<Tuple<char, ushort, char?[]>> _validNumerals = new List<Tuple<char, ushort, char?[]>>()
    {
        new Tuple<char, ushort, char?[]>('I', 1, new char? [] {'V', 'X'}),
        new Tuple<char, ushort, char?[]>('V', 5, null),
        new Tuple<char, ushort, char?[]>('X', 10, new char?[] {'L', 'C'}),
        new Tuple<char, ushort, char?[]>('L', 50, null),
        new Tuple<char, ushort, char?[]>('C', 100, new char? [] {'D', 'M'}),
        new Tuple<char, ushort, char?[]>('D', 500, null),
        new Tuple<char, ushort, char?[]>('M', 1000, new char? [] {null, null})
    };


    public int TranslateRomanNumeral(string input)
    {
        var inputList = input?.ToUpper().ToList();

        if (inputList == null || inputList.Any(x => _validNumerals.Select(t => t.Item1).Contains(x) == false))
        {
            throw new ArgumentException();
        }

        char? valForSubtraction = null;
        int result = 0;
        bool noAdding = false;
        int equalSum = 0;
        for (int i = 0; i < inputList.Count; i++)
        {
            var currentNumeral = _validNumerals.FirstOrDefault(s => s.Item1 == inputList[i]);
            var nextNumeral = i < inputList.Count - 1 ? _validNumerals.FirstOrDefault(s => s.Item1 == inputList[i + 1]) : null;
            bool currentIsDecimalPower = currentNumeral?.Item3?.Any() ?? false;

            if (nextNumeral != null)
            {
                // Syntax and Semantics checks
                if ((currentNumeral.Item2 < nextNumeral.Item2) && (currentIsDecimalPower == false || currentNumeral.Item3.Any(s => s == nextNumeral.Item1) == false) ||
                    (currentNumeral.Item2 == nextNumeral.Item2) && (currentIsDecimalPower == false || nextNumeral.Item1 == valForSubtraction) ||
                    (currentIsDecimalPower && result > 0 &&  ((nextNumeral.Item2 -currentNumeral.Item2) > result )) ||
                    (currentNumeral.Item2 > nextNumeral.Item2) && (nextNumeral.Item1 == valForSubtraction)

                    )
                {
                    throw new ArgumentException();
                }

                if (currentNumeral.Item2 == nextNumeral.Item2)
                {
                    equalSum += equalSum == 0 ? currentNumeral.Item2 + nextNumeral.Item2 : nextNumeral.Item2;
                    int? smallest = null;
                    var list = _validNumerals.Where(p => _validNumerals.FirstOrDefault(s => s.Item1 == currentNumeral.Item1).Item3.Any(s2 => s2 != null && s2 == p.Item1)).ToList();
                    if (list.Any())
                    {
                        smallest = list.Select(s3 => s3.Item2).ToList().Min();
                    }

                    // Another Semantics check
                    if (currentNumeral.Item3 != null && equalSum >= (smallest - currentNumeral.Item2))
                    {
                        throw new ArgumentException();
                    }

                    result += noAdding ? 0 : currentNumeral.Item2 + nextNumeral.Item2;
                    noAdding = !noAdding;
                    valForSubtraction = null;
                }
                else
                if (currentNumeral.Item2 < nextNumeral.Item2)
                {
                    equalSum = 0;
                    result += nextNumeral.Item2 - currentNumeral.Item2;
                    valForSubtraction = currentNumeral.Item1;
                    noAdding = true;
                }
                else 
                if (currentNumeral.Item2 > nextNumeral.Item2)
                {
                    equalSum = 0;
                    result += noAdding ? 0 : currentNumeral.Item2;
                    noAdding = false;

                    valForSubtraction = null;
                }
            }
            else
            {
                result += noAdding ? 0 : currentNumeral.Item2;
            }
        }
        return result;
    }
}

答案 19 :(得分:0)

这个问题很有趣,这是我的看法。

(希望)可以处理数字,直到上划线字符的上限为止。 应该 添加任何其他约定仅是配置新频段并调整ConfigureNext链的问题。

NumeralGenerator.cs

public static class NumeralGenerator
{
    private static readonly INumeralBand RootNumeralBand = ConfigureMapping();

    private static INumeralBand ConfigureMapping()
    {
        var unitBand = new FinalBand(1, "I");

        var fiveBand = new NumeralBand(5, "V", unitBand);
        var tenBand = new NumeralBand(10, "X", unitBand);
        var fiftyBand = new NumeralBand(50, "L", tenBand);
        var hundredBand = new NumeralBand(100, "C", tenBand);
        var fiveHundredBand = new NumeralBand(500, "D", hundredBand);
        var thousandBand = new NumeralBand(1000, "M", hundredBand);

        var thousandUnitBand = new NumeralBand(1000, "I\u0305", thousandBand);

        var fiveThousandBand = new NumeralBand(5000, "V\u0305", thousandUnitBand);
        var tenThousandBand = new NumeralBand(10000, "X\u0305", thousandUnitBand);
        var fiftyThousandBand = new NumeralBand(50000, "L\u0305", tenThousandBand);
        var hundredThousandBand = new NumeralBand(100000, "C\u0305", tenThousandBand);
        var fiveHundredThousandBand = new NumeralBand(500000, "D\u0305", hundredThousandBand);
        var millionBand = new NumeralBand(1000000, "M\u0305", hundredThousandBand);

        millionBand
            .ConfigureNext(fiveHundredThousandBand)
            .ConfigureNext(hundredThousandBand)
            .ConfigureNext(fiftyThousandBand)
            .ConfigureNext(tenThousandBand)
            .ConfigureNext(fiveThousandBand)
            .ConfigureNext(thousandBand)
            .ConfigureNext(fiveHundredBand)
            .ConfigureNext(hundredBand)
            .ConfigureNext(fiftyBand)
            .ConfigureNext(tenBand)
            .ConfigureNext(fiveBand)
            .ConfigureNext(unitBand);

        return millionBand;
    }

    public static string ToNumeral(int number)
    {
        var numerals = new StringBuilder();

        RootNumeralBand.Process(number, numerals);

        return numerals.ToString();
    }
}

INumeralBand.cs

public interface INumeralBand
{
    int Value { get; }
    string Numeral { get; }

    void Process(int number, StringBuilder numerals);
}

NumeralBand.cs

public class NumeralBand : INumeralBand
{
    private readonly INumeralBand _negatedBy;
    private INumeralBand _nextBand;

    public NumeralBand(int value, string numeral, INumeralBand negatedBy)
    {
        _negatedBy = negatedBy;

        Value = value;
        Numeral = numeral;
    }

    public int Value { get; }
    public string Numeral { get; }

    public void Process(int number, StringBuilder numerals)
    {
        if (ShouldNegateAndStop(number))
        {
            numerals.Append(NegatedNumeral);
            return;
        }

        var numeralCount = Math.Abs(number / Value);
        var remainder = number % Value;

        numerals.Append(string.Concat(Enumerable.Range(1, numeralCount).Select(x => Numeral)));

        if (ShouldNegateAndContinue(remainder))
        {
            NegateAndContinue(numerals, remainder);
            return;
        }

        if (remainder > 0)
            _nextBand.Process(remainder, numerals);
    }

    private string NegatedNumeral => $"{_negatedBy.Numeral}{Numeral}";

    private bool ShouldNegateAndStop(int number) => number == Value - _negatedBy.Value;
    private bool ShouldNegateAndContinue(int number) => number >= Value - _negatedBy.Value;

    private void NegateAndContinue(StringBuilder stringBuilder, int remainder)
    {
        stringBuilder.Append(NegatedNumeral);
        remainder = remainder % (Value - _negatedBy.Value);

        _nextBand.Process(remainder, stringBuilder);
    }

    public T ConfigureNext<T>(T nextBand) where T : INumeralBand
    {
        _nextBand = nextBand;

        return nextBand;
    }
}

FinalBand.cs

public class FinalBand : INumeralBand
{
    public FinalBand(int value, string numeral)
    {
        Value = value;
        Numeral = numeral;
    }

    public int Value { get; }
    public string Numeral { get; }

    public void Process(int number, StringBuilder numerals)
    {
        numerals.Append(new string(Numeral[0], number));
    }
}

测试:

FinalBandTests.cs

public class FinalBandTests
{
    [Theory]
    [InlineData(1, "I")]
    [InlineData(2, "II")]
    [InlineData(3, "III")]
    [InlineData(4, "IIII")]
    public void Process(int number, string expected)
    {
        var stringBuilder = new StringBuilder();

        var numeralBand = new FinalBand(1, "I");
        numeralBand.Process(number, stringBuilder);

        Assert.Equal(expected, stringBuilder.ToString());
    }
}

NumeralBandTests.cs

public class NumeralBandTests
{
    private Mock<INumeralBand> _nextBand;
    private Mock<INumeralBand> _negatedBy;

    private StringBuilder _stringBuilder;

    public NumeralBandTests()
    {
        _stringBuilder = new StringBuilder();

        _nextBand = new Mock<INumeralBand>();
        _negatedBy = new Mock<INumeralBand>();
    }

    [Fact]
    public void Process_NegateAndStop()
    {
        var numeral = new NumeralBand(10, "X", _negatedBy.Object);

        _negatedBy.Setup(x => x.Value).Returns(1);
        _negatedBy.Setup(x => x.Numeral).Returns("I");

        numeral.Process(9, _stringBuilder);

        Assert.Equal("IX", _stringBuilder.ToString());
        _nextBand.Verify(x => x.Process(It.IsAny<int>(), It.IsAny<StringBuilder>()), Times.Never);
    }

    [Fact]
    public void Process_Exact()
    {
        var numeral = new NumeralBand(10, "X", _negatedBy.Object);

        _negatedBy.Setup(x => x.Value).Returns(1);
        _negatedBy.Setup(x => x.Numeral).Returns("I");

        numeral.Process(10, _stringBuilder);

        Assert.Equal("X", _stringBuilder.ToString());
        _nextBand.Verify(x => x.Process(It.IsAny<int>(), It.IsAny<StringBuilder>()), Times.Never);
    }

    [Fact]
    public void Process_NegateAndContinue()
    {
        var numeral = new NumeralBand(50, "L", _negatedBy.Object);
        numeral.ConfigureNext(_nextBand.Object);

        _negatedBy.Setup(x => x.Value).Returns(10);
        _negatedBy.Setup(x => x.Numeral).Returns("X");

        numeral.Process(54, _stringBuilder);

        Assert.Equal("L", _stringBuilder.ToString());
        _nextBand.Verify(x => x.Process(4, _stringBuilder), Times.Once);
    }
}

NumeralGeneratorTests.cs

public class NumeralGeneratorTests
{
    private readonly ITestOutputHelper _output;

    public NumeralGeneratorTests(ITestOutputHelper output)
    {
        _output = output;
    }

    [Theory]
    [InlineData(1, "I")]
    [InlineData(2, "II")]
    [InlineData(3, "III")]
    [InlineData(4, "IV")]
    [InlineData(5, "V")]
    [InlineData(6, "VI")]
    [InlineData(7, "VII")]
    [InlineData(8, "VIII")]
    [InlineData(9, "IX")]
    [InlineData(10, "X")]
    [InlineData(11, "XI")]
    [InlineData(15, "XV")]
    [InlineData(1490, "MCDXC")]
    [InlineData(1480, "MCDLXXX")]
    [InlineData(1580, "MDLXXX")]
    [InlineData(1590, "MDXC")]
    [InlineData(1594, "MDXCIV")]
    [InlineData(1294, "MCCXCIV")]
    [InlineData(3999, "MMMCMXCIX")]
    [InlineData(4000, "I\u0305V\u0305")]
    [InlineData(4001, "I\u0305V\u0305I")]
    [InlineData(5002, "V\u0305II")]
    [InlineData(10000, "X\u0305")]
    [InlineData(15000, "X\u0305V\u0305")]
    [InlineData(15494, "X\u0305V\u0305CDXCIV")]
    [InlineData(2468523, "M\u0305M\u0305C\u0305D\u0305L\u0305X\u0305V\u0305MMMDXXIII")]
    public void ToNumeral(int number, string expected)
    {
        var sw = Stopwatch.StartNew();
        var actual = NumeralGenerator.ToNumeral(number);
        sw.Stop();

        _output.WriteLine(sw.ElapsedMilliseconds.ToString());

        Assert.Equal(expected, actual);
    }
}

答案 20 :(得分:0)

public static String convert(int num)
{
    String[] charsArray  = {"I", "IV", "V", "IX", "X", "XL", "L", "XC","C","CD","D","CM","M" };
    int[] charValuesArray = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};

    String resultString = "";
    int temp = num;
    int [] resultValues = new int[13];
    // Generate an array which "char" occurances count
    for(int i = 12 ; i >= 0 ; i--)
    {
        if((temp / charValuesArray[i]) > 0)
        {
            resultValues[i] = temp/charValuesArray[i];
            temp = temp % charValuesArray[i];
        }
    }
    // Print them if not occured do not print
    for(int j = 12 ; j >= 0 ; j--)
    {
        for(int k = 0 ; k < resultValues[j]; k++)
        {
            resultString+= charsArray[j];
        }
    }
    return resultString;

}

答案 21 :(得分:0)

一个更直接的解决方案。尝试稍微提高我使用StringBuilder的性能,迭代更少的键(当然LINQ中的另一个站点 - 可能会增加额外的延迟)

public class ArabicToRomanConverter
{
    private static readonly Dictionary<int, string> _romanDictionary = new Dictionary<int, string>
    {
        {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"}
    };

    public ArabicToRomanConverter()
    {

    }

    public string Convert(int arabicNumber)
    {
        StringBuilder romanNumber = new StringBuilder();
        var keys = _romanDictionary.Keys.Where(k => arabicNumber >= k).ToList();
        for (int i = 0; i < keys.Count && arabicNumber > 0; i++)
        {
            int ckey = keys[i];
            int division = arabicNumber / ckey;
            if (division != 0)
            {
                for (int j = 0; j < division; j++)
                {
                    romanNumber.Append(_romanDictionary[ckey]);
                    arabicNumber -= ckey;
                }
            }
        }

        return romanNumber.ToString();
    }
}

答案 22 :(得分:0)

以下是@Cammilius转换为C#的版本 - 对我来说是低数字的,这对我的用例来说都是我需要的。

public String convertToRoman(int num)
{    
    //Roman numerals to have <= 3 consecutive characters, the distances between deciaml values conform to this
    int[] decimalValue = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
    string[] romanNumeral = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
    int num_cp = num; // copy the function parameter into num_cp
    String result = "";

    for (var i = 0; i < decimalValue.Length; i = i + 1)
    { //itarate through array of decimal values
        //iterate more to find values not explicitly provided in the decimalValue array
        while (decimalValue[i] <= num_cp)
        {
            result = result + romanNumeral[i];
            num_cp = num_cp - decimalValue[i];
        }
    }
    return result;
}

答案 23 :(得分:0)

解决方案很冗长,但对初学者来说很容易理解。处理高达3000

namespace RomansTranslator
{
    using System;
    using System.Collections.Generic;
    /// <summary>
    /// Accepts a number (between 1 and 3000) and prints its Roman equivalent.
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            string number = string.Empty;
            Console.Write("Enter the Numeric number : ");
            number = Console.ReadLine();
            if (IsValid(number)) // Validates the input
            {
                string roman = ConvertToRoman(number);
                Console.WriteLine("Roman Number is " + roman);
            }
            else
            {
                Console.WriteLine("Invalid Number");
            }
            Console.ReadKey();
        }

        private static string ConvertToRoman(string numberString)
        {
            string romanValue = string.Empty;
            int number = Convert.ToInt32(numberString);
            if (number >= 1)
            {
                // Loop through each roman character from highest 
                foreach (int item in RomanDictionary().Keys)
                {
                    while (number >= item)
                    {
                        romanValue = romanValue + RomanString(item);
                        number -= item;
                    }
                }
            }
            return romanValue;
        }

        /// <summary>
        /// Returns Roman Equvalent
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        private static string RomanString(int n)
        {
            string romanString = string.Empty;
            romanString = RomanDictionary()[n].ToString();
            return romanString;
        }

        /// <summary>
        /// List of Roman Characters 
        /// </summary>
        /// <returns></returns>
        private static Dictionary<int, string> RomanDictionary()
        {

            Dictionary<int, string> romanDic = new Dictionary<int, string>();
            romanDic.Add(1000, "M");
            romanDic.Add(900, "CM");
            romanDic.Add(500, "D");
            romanDic.Add(400, "CD");
            romanDic.Add(100, "C");
            romanDic.Add(90, "XC");
            romanDic.Add(50, "L");
            romanDic.Add(40, "XL");
            romanDic.Add(10, "X");
            romanDic.Add(9, "IX");
            romanDic.Add(5, "V");
            romanDic.Add(4, "IV");
            romanDic.Add(1, "I");
            return romanDic;
        }


        /// <summary>
        /// Validates the Input
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private static bool IsValid(string input)
        {
            int value = 0;
            bool isValid = false;
            if (int.TryParse(input, out value))
            {
                if (value <= 3000)
                {
                    isValid = true;
                }
            }
            return isValid;
        }
    }
}

答案 24 :(得分:0)

        Random r = new Random();
        int[] arreglo = new int[100];
        for (int i=0; i<arreglo.Length;i++) {
            arreglo[i] = r.Next(1,1001);
        }

        for (int t = 0;t < arreglo.Length; t++)
        {
            if (arreglo[t] >= 1000)
            {
                Console.Write("M"); arreglo[t] -= 1000;
            }
            if (arreglo[t] >=900)
            {
                Console.Write("MC"); arreglo[t] -= 900;
            }
            if (arreglo[t] >= 500)
            {
                Console.Write("D"); arreglo[t] -= 500;
            }
            if (arreglo[t] >= 400)
            {
                Console.Write("CD"); arreglo[t] -= 400;
            }
            if (arreglo[t] >= 100) {
                Console.Write("C"); arreglo[t] -= 100;
            }
            if (arreglo[t] >= 90)
            {
                Console.Write("XC"); arreglo[t] -= 90;
            }
            if (arreglo[t] >= 50)
            {
                Console.Write("L"); arreglo[t] -= 50;
            }
            if (arreglo[t] >= 40)
            {
                Console.Write("XL"); arreglo[t] -= 40;
            }
            if (arreglo[t] >= 10)
            {
                Console.Write("X"); arreglo[t] -= 10;
            }
            if (arreglo[t] >= 9)
            {
                Console.Write("IX"); arreglo[t] -= 9;
            }
            if (arreglo[t] >= 5)
            {
                Console.Write("V"); arreglo[t] -= 5;
            }
            if (arreglo[t] >= 4)
            {
                Console.Write("IV"); arreglo[t] -= 4;
            }
            if (arreglo[t] >= 1)
            {
                Console.Write("I"); arreglo[t] -= 1;
            }

            Console.WriteLine();

        }
        Console.ReadKey();    

答案 25 :(得分:0)

我发现BrunoLM的代码非常简单而优雅,但 From(...)功能 确实需要检查来源是否是有效的罗马数字 像这样的东西

public static bool IsValidRomanNumber(string source) {
        bool result = true;

        string[] invalidCouples = { "VV", "LL", "DD", "VX", "VC", "VM", "LC", "LM", "DM", "IC", "IM", "XM" };

        foreach (string s in invalidCouples) {
            if (source.Contains(s)) {
                result = false;
                break;
            }
        }

        return result;
    }

答案 26 :(得分:0)

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter the number\n");
            int num = int.Parse(Console.ReadLine());
            ToRomanNumber tr = new ToRomanNumber();
            string opt=tr.ToRoman(num);
            Console.WriteLine(opt);
        }
    }
    class ToRomanNumber
    {
        string s = "";

        public string ToRoman(int number)
        {

            if ((number < 0) || (number > 3999))
            {
                s = s + "Invalid Input";
            }
            if (number < 1) return s;
            if (number >= 1000) { s = s + "M"; ToRoman(number - 1000);}
            if (number >= 900){ s = s + "CM";ToRoman(number - 900);}
            if (number >= 500){ s = s + "D"; ToRoman(number - 500);}
            if (number >= 400){ s = s + "CD"; ToRoman(number - 400);}
            if (number >= 100){ s = s + "C"; ToRoman(number - 100);}
            if (number >= 90){ s = s + "XC"; ToRoman(number - 90);}
            if (number >= 50){ s = s + "L";ToRoman(number - 50);}
            if (number >= 40){ s = s + "XL";ToRoman(number - 40);}
            if (number >= 10){ s = s + "X"; ToRoman(number - 10); }
            if (number >= 9) { s = s + "IX"; ToRoman(number - 9); }
            if (number >= 5) { s = s + "V"; ToRoman(number - 5); }
            if (number >= 4) { s = s + "IV"; ToRoman(number - 4); }
            if (number >= 1) { s = s + "I"; ToRoman(number - 1);}
            return s;
        }
    }
}

答案 27 :(得分:0)

 public static int pairConversion(int dec, int lastNum, int lastDec)
    {
        if (lastNum > dec)
            return lastDec - dec;
        else return lastDec + dec;
    }

    public static int ConvertRomanNumtoInt(string strRomanValue)
    {
        var dec = 0;
        var lastNum = 0;
        foreach (var c in strRomanValue.Reverse())
        {
            switch (c)
            {
                case 'I':
                    dec = pairConversion(1, lastNum, dec);
                    lastNum = 1;
                    break;
                case 'V':
                    dec=pairConversion(5,lastNum, dec);
                    lastNum = 5;
                    break;
                case 'X':
                    dec = pairConversion(10, lastNum, dec);
                    lastNum = 10;
                    break;
                case 'L':
                    dec = pairConversion(50, lastNum, dec);
                    lastNum = 50;
                    break;
                case 'C':
                    dec = pairConversion(100, lastNum, dec);
                    lastNum = 100;
                    break;
                case 'D':
                    dec = pairConversion(500, lastNum, dec);
                    lastNum = 500;
                    break;
                case 'M':
                    dec = pairConversion(1000, lastNum, dec);
                    lastNum = 1000;
                    break;
            }
        }
        return dec;

    }

如果你反转罗马数字来处理像XIV这样的情况会更容易。代码参考此blog