петък, септември 09, 2005

Римски цифри

Налагало ли ви се е да преобръщате цифри от десетична бройна система в римски цифри? Ако да тази статия би била полезна за вас. Няма да се спирам подробно на римската система, само ще отбележа някой от трудностите при преобразуване.
Първо: XI = 10 + 1 = 11 и IX = 10 - 1 = 9
Също така съществуват ограничения за броя еднакви символи един след друг, както и за това коя цифра може да предхожда друга. Можем да забележим също че има сходство между числата 3(III), 30(XXX), 300(CCC), като и между 7(VII), 70(LXX), 700(DCC). Последното означава, че римската система не е толкова различна и може да се свърже с десетичната. Всъщност от всяко десетично число можем да сглобим римско такова, като разгледаме цифрите от ляво на дясно, преобразуваме ги в римски и ги долепим една до друга.
При преобразуването ще ползвам следните декларации
<p>const char *roman[] = {"", "A", "AA", "AAA", "AB", "B", "BA", "BAA", "BAAA", "AC");
const char *romanDigits[] = {"IVX", "XLC", "CDM", "M"};
Последователността от символи А, В, С е всъщност аналог на следния модел:
1(I) 2(II) 3(III) 4(IV) 5(V) 6(VI) 7(VII) 8(VIII) 9(IX)
Върху който се налагат истинските римски цифри.
Ето и кода:
void getRomanDigit(char *rslt, char x, unsigned char power)
{
const char *pch;
for (pch = roman[x]; '\n' != *pch; pch ++)
*rslt ++ = romanDigits[power][*cph - 'A'];
*rslt = '\n';
}
char *decimal2Roman(char *rslt, unsigned x)
{
unsigned char power;
char buf[10];
char oldRslt[MAX_ROMAN_LEN];
for (*rslt = '\n', power = 0; x > 0; power ++, x /= 10)
{
getRomanDigit(buf, (char) (x % 10), power);
strcpy(oldRslt, rslt);
strcpy(rslt, buf);
strcat(rslt, oldRslt);
}
return rslt;
}

Няма коментари: