C 如何将整数值转换为罗马数字字符串?
如何将整数转换为C中罗马数字的字符串表示形式?最简单的方法可能是为复杂情况设置三个数组,并使用以下简单函数:C 如何将整数值转换为罗马数字字符串?,c,roman-numerals,C,Roman Numerals,如何将整数转换为C中罗马数字的字符串表示形式?最简单的方法可能是为复杂情况设置三个数组,并使用以下简单函数: // convertToRoman: // In: val: value to convert. // res: buffer to hold result. // Out: n/a // Cav: caller responsible for buffer size. void convertToRoman (unsigned int val, char
// convertToRoman:
// In: val: value to convert.
// res: buffer to hold result.
// Out: n/a
// Cav: caller responsible for buffer size.
void convertToRoman (unsigned int val, char *res) {
char *huns[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
char *tens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
char *ones[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
int size[] = { 0, 1, 2, 3, 2, 1, 2, 3, 4, 2};
// Add 'M' until we drop below 1000.
while (val >= 1000) {
*res++ = 'M';
val -= 1000;
}
// Add each of the correct elements, adjusting as we go.
strcpy (res, huns[val/100]); res += size[val/100]; val = val % 100;
strcpy (res, tens[val/10]); res += size[val/10]; val = val % 10;
strcpy (res, ones[val]); res += size[val];
// Finish string off.
*res = '\0';
}
这将处理任何无符号整数,尽管大数字的前面将有大量的M
字符,并且调用者必须确保其缓冲区足够大
一旦这个数字降到1000以下,就可以进行简单的三表查找,百、十和单位各一个。例如,假设val
是314
在这种情况下,val/100
将是3
,因此huns
数组查找将给出CCC
,然后val=val%100
为tens
查找提供14
然后val/10
在这种情况下将是1
,因此tens
数组查找将给出X
,然后val=val%10
为查找提供4
在这种情况下,val
将是4
,因此数组查找将给出IV
这将为314
提供CCCXIV
缓冲区溢出检查版本是一个简单的升级:
// convertToRoman:
// In: val: value to convert.
// res: buffer to hold result.
// Out: returns 0 if not enough space, else 1.
// Cav: n/a
int convertToRoman (unsigned int val, char *res, size_t sz) {
char *huns[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
char *tens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
char *ones[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
int size[] = { 0, 1, 2, 3, 2, 1, 2, 3, 4, 2};
// Add 'M' until we drop below 1000.
while (val >= 1000) {
if (sz-- < 1) return 0;
*res++ = 'M';
val -= 1000;
}
// Add each of the correct elements, adjusting as we go.
if (sz < size[val/100]) return 0;
sz -= size[val/100];
strcpy (res, huns[val/100]);
res += size[val/100];
val = val % 100;
if (sz < size[val/10]) return 0;
sz -= size[val/10];
strcpy (res, tens[val/10]);
res += size[val/10];
val = val % 10;
if (sz < size[val) return 0;
sz -= size[val];
strcpy (res, ones[val]);
res += size[val];
// Finish string off.
if (sz < 1) return 0;
*res = '\0';
return 1;
}
//转换器阿曼:
//In:val:要转换的值。
//res:保存结果的缓冲区。
//Out:如果没有足够的空间,则返回0,否则返回1。
//Cav:不适用
整型转换器(无符号整型值、字符*res、大小\u t sz){
char*huns[]={”、“C”、“CC”、“CCC”、“CD”、“D”、“DC”、“DCC”、“DCCC”、“CM”};
字符*tens[]={”、“X”、“XX”、“XXX”、“XL”、“L”、“LX”、“LXX”、“XC”};
字符*字符[]={”、“一”、“二”、“三”、“四”、“五”、“六”、“七”、“八”、“九”};
int size[]={0,1,2,3,2,1,2,3,4,2};
//加上“M”直到我们下降到1000以下。
而(val>=1000){
如果(sz--<1)返回0;
*res++='M';
val-=1000;
}
//添加每个正确的元素,并随操作进行调整。
如果(sz
虽然,在这一点上,您可以考虑将数百、十和单位的处理重构为一个单独的函数,因为它们非常相似。我将把这作为一个额外的练习。static string convertoroman(int num)
static string ConvertToRoman(int num)
{
int d = 0;
string result = "";
while (num > 0)
{
int n = num % 10;
result = DigitToRoman(n, d) + result;
d++;
num = num / 10;
}
return result;
}
static string DigitToRoman(int n, int d)
{
string[,] map = new string[3, 3] { { "I", "V", "X" }, { "X", "L", "C" }, { "C", "D", "M" } };
string result="";
if (d <= 2)
{
switch (n)
{
case 0:
result = "";
break;
case 1:
result = map[d, 0];
break;
case 2:
result = map[d, 0] + map[d, 0];
break;
case 3:
result = map[d, 0] + map[d, 0] + map[d, 0];
break;
case 4:
result = map[d, 0] + map[d, 1];
break;
case 5:
result = map[d, 1];
break;
case 6:
result = map[d, 1] + map[d, 0];
break;
case 7:
result = map[d, 1] + map[d, 0] + map[d, 0];
break;
case 8:
result = map[d, 1] + map[d, 0] + map[d, 0] + map[d, 0];
break;
case 9:
result = map[d, 0] + map[d, 2];
break;
}
}
else if (d == 3 && n < 5)
{
while (--n >= 0)
{
result += "M";
}
}
else
{
return "Error! Can't convert numbers larger than 4999.";
}
return result;
}
{
int d=0;
字符串结果=”;
while(num>0)
{
int n=num%10;
结果=DigitToRoman(n,d)+结果;
d++;
num=num/10;
}
返回结果;
}
静态字符串DigitToRoman(int n,int d)
{
字符串[,]map=新字符串[3,3]{{“I”、“V”、“X”}、{“X”、“L”、“C”}、{“C”、“D”、“M”};
字符串结果=”;
如果(d=0)
{
结果+=“M”;
}
}
其他的
{
return“错误!无法转换大于4999的数字。”;
}
返回结果;
}
对于困难的情况,不要使用sissy预先计算的地图
/* roman.c */
#include <stdio.h>
/* LH(1) roman numeral conversion */
int RN_LH1 (char *buf, const size_t maxlen, int n)
{
int S[] = { 0, 2, 4, 2, 4, 2, 4 };
int D[] = { 1000, 500, 100, 50, 10, 5, 1 };
char C[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
const size_t L = sizeof(D) / sizeof(int) - 1;
size_t k = 0; /* index into output buffer */
int i = 0; /* index into maps */
int r, r2;
while (n > 0) {
if (D[i] <= n) {
r = n / D[i];
n = n - (r * D[i]);
/* lookahead */
r2 = n / D[i+1];
if (i < L && r2 >= S[i+1]) {
/* will violate repeat boundary on next pass */
n = n - (r2 * D[i+1]);
if (k < maxlen) buf[k++] = C[i+1];
if (k < maxlen) buf[k++] = C[i-1];
}
else if (S[i] && r >= S[i]) {
/* violated repeat boundary on this pass */
if (k < maxlen) buf[k++] = C[i];
if (k < maxlen) buf[k++] = C[i-1];
}
else
while (r-- > 0 && k < maxlen)
buf[k++] = C[i];
}
i++;
}
if (k < maxlen) buf[k] = '\0';
return k;
}
/* gcc -Wall -ansi roman.c */
int main (int argc, char **argv)
{
char buf[1024] = {'\0'};
size_t len;
int k;
for (k = 1991; k < 2047; k++)
{
len = RN_LH1(buf, 1023, k);
printf("%3lu % 4d %s\n", len, k, buf);
}
return 0;
}
/*roman.c*/
#包括
/*LH(1)罗马数字转换*/
int RN_LH1(字符*buf,常量大小\u t最大值,int n)
{
int S[]={0,2,4,2,4,2,4};
int D[]={1000,500,100,50,10,5,1};
字符C[]={'M','D','C','L','X','V','I'};
常数size_t L=sizeof(D)/sizeof(int)-1;
大小\u t k=0;/*索引到输出缓冲区*/
int i=0;/*索引到映射中*/
int r,r2;
而(n>0){
如果(D[i]=S[i+1]){
/*将在下一次通过时违反重复边界*/
n=n-(r2*D[i+1]);
如果(k=S[i]){
/*违反此通行证上的重复边界*/
如果(k0&&k
你实际上也不需要声明S
。这应该很容易理解为什么。除非你为NFL工作,否则这必须是家庭作业,不是吗?好吧,不是把作业扔到一边,希望得到代码;)@delnan:显然有效:-)@Jason-或者一些本地化项目正在进行中top@jason