罗马数字到阿拉伯语 (vinculum) - 读取字符串中的字符



我目前正在从事一个将罗马数字转换为阿拉伯数字的项目,反之亦然。 我还负责实现像vinculum这样的概念,如果你在罗马数字上放一个条形,下面的数字将乘以1,000。

我遇到的问题是我只能让一侧工作,这意味着: 我可以在没有Vinculum的情况下从罗马数字转换为阿拉伯语: CXHI = 1, II = 2 但是,当这起作用时,我的vinculum代码不起作用。

这是我的代码片段:

int romanToDecimal(char input[], size_t end) {
int roman = 0;
int vroman = 0;
for (int i = 0; i < strlen(input); ++i)
{
int s1 = value(input[i]);
int s2 = value(input[i]);
if (input[i] == '-')
{
for (int j = i - 1; j >= 0; --j)
{
roman = (roman + value(input[j]));
}
roman *= 1000;

for (int k = i + 1; k <= strlen(input); k++)
roman += value(input[k]);
}
else
roman += s1;
}
return roman;
}

我们使用"-"而不是字符顶部的栏,因为我们在计算机中无法轻松做到这一点。所以 IV-,将是 4000,XI- 将是 11,000 等等......

我知道我做循环的方式导致一些被转换的数字加两次,因为 if(input[i] == '-'( 一次循环浏览字符串中的每个字符。

好的,所以我的问题基本上是让它工作的逻辑是什么?因此,如果字符串包含"-",它将数字乘以 1000,如果字符串根本不包含"-",那么它将正常转换。现在我相信正在发生的事情是,当"if (input[i] == '-')"为 false 时,那部分代码仍在运行,当字符串包含"-"时,我如何根本不让它运行?

发布的代码似乎不完整,或者至少有一些未使用的(如end,如果它表示字符串的长度,则可以用于代替以下重复的strlen(input)(或无意义的(如s2(变量。

我无法理解您的"Vinculum"实现背后的逻辑,但简单的

roman += s1;  // Where s1 = value(input[i]);

解析罗马数字显然是不够的,其中每个符号的相对位置很重要。例如,考虑"IV",即 4 (= 5 - 1(,而"VI"为 6 (= 5 + 1(。

要解析"减法"表示法,您可以存储部分结果并将当前数字与前一个数字进行比较。如下所示:

#include <stdio.h>
#include <string.h>
int value_of(char ch);
long decimal_from_roman(char const *str, size_t length)
{
long number = 0, partial = 0;
int value = 0, last_value = 0;
for (size_t i = 0; i < length; ++i)
{
if (str[i] == '-')
{
number += partial;
number *= 1000;
partial = 0;
continue;
}
last_value = value;
value = value_of(str[i]);
if (value == 0)
{
fprintf(stderr, "Wrong format.n");   
return 0;
}
if (value > last_value)
{
partial = value - partial;
}
else if (value < last_value)
{
number += partial;
partial = value;
}
else
{
partial += value;   
}
}   
return number + partial;
}
int main(void)
{
char const *tests[] = {
"I", "L", "XXX", "VI", "IV", "XIV", "XXIII-",
"MCM", "MCMXII", "CCXLVI", "DCCLXXXIX", "MMCDXXI", // 1900, 1912, 246, 789, 2421
"CLX", "CCVII", "MIX", "MLXVI"                     // 160, 207, 1009, 1066 
};
int n_samples = sizeof(tests) / sizeof(*tests);
for (int i = 0; i < n_samples; ++i)
{
long number = decimal_from_roman(tests[i], strlen(tests[i]));
printf("%12ld %sn", number, tests[i]);
}
return 0;
}
int value_of(char ch)
{
switch (ch)
{
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;
default:
return 0;
}
}

请注意,前面的代码只检查错误的字符,但不会丢弃像"MMMMMMMMMMIIIIIIIIIIV"这样的字符串。将其视为一个起点,并随时对其进行改进。

最新更新