Объектив C число римскими цифрами - PullRequest
6 голосов
/ 10 мая 2011

Я всегда искал пример кода для преобразования числа в римские цифры в задаче c.Кто-нибудь знает, где я могу найти хороший пример?

Обновление:

Nevermind, нашел функцию 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 ]

3 голосов
/ 08 февраля 2014

Просто немного короче и оптимизировано, на основе первого алгоритма

+(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 голосов
/ 10 мая 2011

Вот реализация созданного мной средства форматирования.Он просматривает список возможных номеров, поэтому его очень легко изменить.Прямо сейчас это только преобразовывает целое число в строку, но я обновлю это, если я реализую противоположное направление.

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 голос
/ 10 мая 2011

Интересно, это домашнее задание?

Алгоритм преобразования - это простая итерация типа «уменьшить число, построить строку», и вам нужны только базовые математические операции, сравнение и строковые операции.

Перейдите на Компьютерные алгоритмы , где вы найдете различные алгоритмы, обсужденные и представленные в VB - понять VB несложно, даже если вы не знаете язык.

...