Objective C数字转罗马数字

6

我一直在寻找如何在Objective-C中将数字转换为罗马数字的示例代码。有人知道哪里可以找到好的例子吗?

更新:

算了,我找到了一个可以实现我想要的功能的PHP函数,并进行了移植。目前看来似乎运行良好。

-(NSString*)numberToRomanNumerals:(int)num{

    if (num < 0 || num > 9999) { return @""; } // out of range



    NSArray *r_ones = [[NSArray alloc]initWithObjects:@"I", @"II", @"III", @"IV", @"V", @"VI", @"VII", @"VIII",@"IX",nil];
    NSArray *r_tens = [[NSArray alloc]initWithObjects:@"X", @"XX", @"XXX", @"XL", @"L", @"LX", @"LXX",@"LXXX", @"XC",nil];
    NSArray *r_hund = [[NSArray alloc]initWithObjects:@"C", @"CC", @"CCC", @"CD", @"D", @"DC", @"DCC",@"DCCC", @"CM",nil];
    NSArray *r_thou = [[NSArray alloc]initWithObjects:@"M", @"MM", @"MMM", @"MMMM", @"MMMMM", @"MMMMMM",@"MMMMMMM",
               @"MMMMMMMM", @"MMMMMMMMM",nil];


    int ones = num % 10;
    int tens = (num - ones) % 100;
    int hundreds = (num - tens - ones) % 1000;
    int thou = (num - hundreds - tens - ones) % 10000;


    tens = tens / 10;
    hundreds = hundreds / 100;
    thou = thou / 1000;

    NSString *rnum=@"";

    if (thou) { rnum = [rnum stringByAppendingString:[r_thou objectAtIndex:thou-1]]; }
    if (hundreds) { rnum = [rnum stringByAppendingString:[r_hund objectAtIndex:hundreds-1]];    }
    if (tens) { rnum = [rnum stringByAppendingString:[r_tens objectAtIndex:tens-1]]; }
    if (ones) { rnum = [rnum stringByAppendingString:[r_ones objectAtIndex:ones-1]]; }

    [r_ones release];
    [r_tens release];
    [r_hund release];
    [r_thou release];

    return rnum;
}
3个回答

2
基于第一种算法,只需要稍微缩短并进行优化即可。
+(NSString*)romain:(int)num {
    if (num < 0 || num > 9999) { return @""; } // out of range

    NSArray *r_ones = [NSArray arrayWithObjects:@"I", @"II", @"III", @"IV", @"V", @"VI", @"VII", @"VIII", @"IX", nil];
    NSArray *r_tens = [NSArray arrayWithObjects:@"X", @"XX", @"XXX", @"XL", @"L", @"LX", @"LXX",@"LXXX", @"XC", nil];
    NSArray *r_hund = [NSArray arrayWithObjects:@"C", @"CC", @"CCC", @"CD", @"D", @"DC", @"DCC",@"DCCC", @"CM", nil];
    NSArray *r_thou = [NSArray arrayWithObjects:@"M", @"MM", @"MMM", @"MMMM", @"MMMMM", @"MMMMMM", @"MMMMMMM", @"MMMMMMMM", @"MMMMMMMMM", nil];
// real romans should have an horizontal   __           ___           _____
// bar over number to make x 1000: 4000 is IV, 16000 is XVI, 32767 is XXXMMDCCLXVII...

    int thou = num / 1000;
    int hundreds = (num -= thou*1000) / 100;
    int tens = (num -= hundreds*100) / 10;
    int ones = num % 10; // cheap %, 'cause num is < 100!

    return [NSString stringWithFormat:@"%@%@%@%@",
        thou ? [r_thou objectAtIndex:thou-1] : @"",
        hundreds ? [r_hund objectAtIndex:hundreds-1] : @"",
        tens ? [r_tens objectAtIndex:tens-1] : @"",
        ones ? [r_ones objectAtIndex:ones-1] : @""];
}

2
这是我创建的格式化程序的实现。它循环遍历不同可能数字的列表,所以修改起来非常简单。目前它只能将整数转换为字符串,但如果我实现反向操作,我会进行更新。
static unsigned majorIntValues[] = {1000,100,10,1,0};
#define numMajorIntValues (sizeof(majorIntValues) / sizeof(unsigned))
static char majorCharValues[] = {'M','C','X','I','N'};
#define numMajorCharValues (sizeof(majorCharValues) / sizeof(char))
static unsigned intValues[] = {1000,500,100,50,10,5,1};
#define numIntValues (sizeof(intValues) / sizeof(unsigned))
static char charValues[] = {'M','D','C','L','X','V','I'};
#define numCharValues (sizeof(charValues) / sizeof(char))

@implementation RomanNumeralFormatter

- (NSString *)stringForObjectValue:(id)number {
    if(![number respondsToSelector:@selector(unsignedIntegerValue)]) return @"0";
    NSUInteger value = [number unsignedIntegerValue];
    if(value == 0) return @"N";
    NSMutableString *string = [NSMutableString new];
    uint8_t i,j;
    for(i = 0, j = 0; value && i < numIntValues; ++i) {
        while(intValues[i] <= majorIntValues[j]) ++j;
        while(value >= intValues[i]) {
            [string appendFormat:@"%c",charValues[i]];
            value -= intValues[i];
        }
        if(value >= (intValues[i] - majorIntValues[j])) {
            [string appendFormat:@"%c%c",majorCharValues[j],charValues[i]];
            value -= (intValues[i] - majorIntValues[j]);
        }
    }
    return [string autorelease];
}
- (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes {
    return [[[NSAttributedString alloc] initWithString:[self stringForObjectValue:anObject]
                                            attributes:attributes] autorelease];
}

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error {
    if(error) *error = @"Decoding roman numerals is currently unsupported";
    return NO;
}

@end

1

我在想这是作业吗?

转换的算法只是一种简单的“减少数字,构建字符串”的迭代方式,您只需要基本的数学、比较和字符串操作。

请访问计算机算法,您将找到讨论和展示各种算法的VB代码 - 即使您不懂该语言,也不难理解VB。


谢谢,看起来代码比我自己写的少,我会尝试进行移植。 - enamrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接