gpt4 book ai didi

c - 如何更改罗马数字转换器中的4个重复数字?

转载 作者:行者123 更新时间:2023-11-30 15:04:31 24 4
gpt4 key购买 nike

我正在编写一个程序,将 0 到 3999 之间的整数转换为其等效的罗马数字。

目前,我的主要函数(实际上执行转换)运行良好。它接受一个数字,使用罗马数字变量组成罗马数字数组,直到用户输入的整数变为0:

int main(int argc, const char * argv[])
{
int num;
char roman[10];
int I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000;

printf("Please input a number from 1 to 3999:\n");
scanf("%d", &num);

do {
for (int j = 0; j < 10; j++) {
if (num >= M) {
num -= M;
roman[j] = 'M';
}
else if (num >= D) {
num -= D;
roman[j] = 'D';
}
else if (num >= C) {
num -= C;
roman[j] = 'C';
}
else if (num >= L) {
num -= L;
roman[j] = 'L';
}
else if (num >= X) {
num -= X;
roman[j] = 'X';
}
else if (num >= V) {
num -= V;
roman[j] = 'V';
}
else if (num >= I) {
num -= I;
roman[j] = 'I';
}
}
} while (num != 0);

// check(roman, 'X');

printf("\nYour number in roman numerals is %s\n", roman);
}

注释行是我编写的一个单独的函数(称为 check())。理想情况下,这个新函数应该检查是否有重复 4 次的字母,如果存在这种情况则返回 true,否则返回 false。它看起来像这样:

int check(char * numeralArray, char numeral)
{
int counter = 0;
int size = strlen(numeralArray);

for (int i = 0; i < size; i++) {
if(numeralArray[i] == numeral) // check for each iteration if numeral is in numeralArray[i]
counter++; // if it is then counter increases by 1
else
counter = 0; // this resets the value to 0 if its not consecutive.

if(counter == 4) // this stops the loop when 4 consecutive letters have been found.
break;
}

if(counter >= 4) // if counter is 4, it means 4 consecutive letters have been found
return 1; // true
else
return 0; // false
}

因此,我的想法是,例如,我将使用该函数并将 romanI 作为参数传递给 check()。然后它会检查 I 是否连续出现 4 次。如果是,该函数返回 true(用 1 表示)。在我的主函数中,如果 check() 返回的值为 1 (true),那么我想将这四个连续值(例如 IIII)更改为适当的值值(例如 IV)。

问题是,它不能正常工作,check() 函数总是返回 0 (false),即使我输入像 14 这样的数字,而不是 XIIII,应该是XIV。所以我不知道在这种情况下如何让我的函数返回 true,然后我需要做什么才能对数组进行所需的更改?另外,在我的主函数中,我是否必须在 do-while 循环内使用 for 循环?或者我可以摆脱 for 循环,并在每次运行 do-while 循环时递增数组(就像这个 j++)?

最佳答案

如果使用正确,您的 check() 函数就会正常工作。这是一个测试它的最小 main() 函数:

int main(void)
{
char *str[] = { "IIII", "XIIII", "XIII", "IIIXIIII", "IIIXIII" };
enum { NUM_STR = sizeof(str)/sizeof(str[0]) };

for (int i = 0; i < NUM_STR; i++)
printf("%s: %d\n", str[i], check(str[i], 'I'));

return 0;
}

输出;

IIII: 1
XIIII: 1
XIII: 0
IIIXIIII: 1
IIIXIII: 0

所以,您遇到的问题不在于 check() 函数本身。

<小时/>

这是格式化罗马数字的另一种方法。它使用表格来确定可接受的内容(并将数字范围限制为 1 .. 3999)。在我的主库中,该结构有两个额外的字段来帮助解析和验证罗马数字字符串,将它们转换为 int

#include <ctype.h>
#include <errno.h>

/* Header "roman.h" */
extern int fmt_roman(int i, char *buffer, size_t buflen);
/* End "roman.h" */

typedef struct Roman
{
int value;
const char chars[3];
} Roman;

enum { MAX_PERMITTED_ROMAN = 4000 };

static const Roman numerals[] =
{
{ 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", },
};
enum { NUM_NUMERALS = sizeof(numerals) / sizeof(numerals[0]) };

int fmt_roman(int i, char *buffer, size_t buflen)
{
int rc = -1;

if (i <= 0 || i > MAX_PERMITTED_ROMAN)
errno = EDOM;
else if (buflen <= 1)
errno = ENOSPC;
else
{
char *end = buffer + buflen;
char *dst = buffer;
const Roman *e = numerals + NUM_NUMERALS;

for (const Roman *r = numerals; i > 0 && r < e; r++)
{
while (i >= r->value)
{
const char *src = r->chars;
char c;
while ((c = *src++) != '\0' && dst < end)
*dst++ = c;
if (dst >= end)
break;
i -= r->value;
}
}
if (dst < end)
{
*dst = '\0';
rc = 0;
}
else
errno = ENOSPC;
}
return(rc);
}

像往常一样,相当多的代码与错误处理相关。

关于c - 如何更改罗马数字转换器中的4个重复数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40262827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com