最近遇到一个需要整数转罗马数字的问题
罗马数字的规则:
I → 1
V → 5
X → 10
L → 50
C → 100
D → 500
M → 1000
字母从大到小依次排列,例如:8→XIII
但存在一种特殊情况,使得小字母在大字母右侧,来表示后者减去前者:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
因此可以穷举出这几种情况,列为两个数组
再直接通过while暴力循环:
public static string IntToRoman(int value)
{
int[] nums =new int[] { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
string[] romans = new string[]{ "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
string result = "";
while (value > 0)
{
for(int i = 0, l = nums.Length; i < l; ++i)
{
if (value >= nums[i])
{
value -= nums[i];
result += romans[i];
break;
}
}
}
return result;
}
后面我思考了一下,当value与第X位相减时,value必不可能大于x-1位,因此可以加一个变量用来记录位置,降低无效的循环次数;
public static string IntToRoman(int value)
{
int[] nums =new int[] { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
string[] romans = new string[]{ "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
string result = "";
int start=0;
while (value > 0)
{
for(int i = start, l = nums.Length; i < l; ++i)
{
if (value >= nums[i])
{
value -= nums[i];
result += romans[i];
start = i;
break;
}
}
}
return result;
}
输入:8
方法1:VIII 循环次数46
方法2:VIII 循环次数12
输入:1994
方法1:MCMXCIV 循环次数17
方法2:MCMXCIV 循环次数11
输入:3999
方法1:MMMCMXCIX 循环次数15
方法2:MMMCMXCIX 循环次数9
可见改过之后的写法在整个值域(1-3999)内都优于原写法
标签:数字,nums,C#,value,int,罗马数字,循环,result,string From: https://blog.csdn.net/m0_69630773/article/details/139690579