
A mellékelt példaprogram megnyitása előtt a DecRom.pas-ban lévő komponenst telepítenie kell a Delphi alá. Ehhez válassza a Component - Install Component menüpontot.
A komponens használata
A komponens mindössze két függvénnyel rendelkezik.
function DecToRom(Value: Integer): String;
A DecToRom függvény egy integer típusú számot vár bemeneti paraméterként, amelyet római számmá alakít át. A római számot adja vissza eredményül.
function RomToDec(Value: String): Integer;
A RomToDec függvénnyel egy római számot válthatunk át tízes számrendszerbelivé. A Value paraméterben megadott szabályos római számot váltja át. Eredményül a római számnak megfelelő tízes számrendszerbeli számot adja. Ha a megadott római szám helytelen, akkor -1-et ad vissza értékül.
A számok átváltásánál ügyeljünk arra, hogy 3999-nél nagyobb számot nem adhatunk meg, mivel a római számrendszer erre nincs felkészítve. Ha 3999-nél nagyobb számot adunk meg, akkor azt a program nem váltja át.
A komponens elkészítése
A római számrendszer additív számrendszer, amely azt jelenti, hogy egy szám értékét a számrendszer jeleinek összevonásából lehet létrehozni. Szabály, hogy a számjegyeknek csökkenő sorrendben kell követniük egymást.
A római számrendszer jelei.
| Decimális |
1 |
5 |
10 |
50 |
100 |
500 |
1000 |
| Római |
I |
V |
X |
L |
C |
D |
M |
Ha le akarjuk programozni a római számrendszer logikáját, akkor nekünk viszont 13 számjegyet kell megkülönböztetnünk. Ezek tárolásához vegyünk fel két konstans tömböt az alábbi táblázatban szereplő értékekkel.
| Decimal |
1 |
4 |
5 |
9 |
10 |
40 |
50 |
90 |
100 |
400 |
500 |
900 |
1000 |
| Romans |
I |
IV |
V |
IX |
X |
XL |
L |
XC |
C |
CD |
D |
CM |
M |
Ha a Decimal vagy Romans tömbök bármelyikében megtalálunk egy értéket, akkor a másik tömb ugyanazon indexű eleménél megtalálható a másik számrendszerbeli, megfelelő értéke.
A tízes számrendszerből rómaiba történő átváltás
function TDecRom.DecToRom(Value: Integer): String;
var
i: Integer;
begin
Result:='';
if Value>3999 then Exit;
for i:=13 downto 1 do
while (Value>=Decimal[i]) do
begin
Value:=Value-Decimal[i];
Result:=Result+Romans[i];
end;
end;
Használjuk ki azt a szabályt, hogy a római számoknak csökkenő sorrendben kell követniük egymást. Tulajdonképpen ezért volt szükségünk 13 szám megkülönböztetésére.
A római számok átalakítása tízes számrendszerbe
var
i: Integer;
Found, BadCharacter, InCorrectOrder: Boolean;
s: String[2];
t: String;
Count, PrevIndex: Byte;
Ez az átalakítási folyamat egy picivel bonyolultabb.
Ellenőriznünk kell az alábbiakat:
- A számok csak csökkenő sorrendben követhetik egymást.
- Nem lehet kettőnél több karakter csak a I,X,C és M-ből.
- Nem lehet háromnál több karakter semmiből.
- Nem lehet idegen karakter a szövegben.
A BadCharacter a nem megfelelő karaktereket fogja jelezni. Az IncorrectOrder értékét akkor állítjuk igazra, ha a számok nem kisebb vagy egyenlő sorrendben követik egymást. A Count változó számolja meg az egyforma karaktereket. A PrevIndex-ben az előző szám indexét tároljuk el.
Be kell olvasnunk a Value string első két karakterét. Azért kettőt, mert vannak két karakteres római számok.
s:=Value;
Found:=False;
BadCharacter:=True;
for i:=1 to 13 do
if (Romans[i]=UpperCase(s)) and (Length(Romans[i])=2) then begin
if PrevIndex<i then IncOrrectOrder:=True;
Found:=True;
Result:=Result+Decimal[i];
BadCharacter:=False;
if PrevIndex=i then Inc(Count)
else Count:=1;
PrevIndex:=i;
end;
Ha a Romans tömbben megtaláltuk ezt a karaktert, akkor értékét kikereshetjük a Decimal tömb azonos indexén. A most kiszámított első két karaktert a Values string-ből ezután törölnünk kell.
Ha a két karakterként beolvasott római szám nem szerepelt a Romans tömbben, akkor csak egy karaktert kell beolvasnunk és feldolgoznunk a két karakteres módszerhez hasonlóan.
Ha valami hiba lépne fel, akkor befejezzük a feldolgozást és -1-et adunk eredményül.
if (Count>=2) and not(PrevIndex in [1,5,9,13]) then BadCharacter:=True;
if BadCharacter or (Count>3) or InCorrectOrder then begin
Value:='';
Result:=-1;
end;
Az egész feldolgozást addig kell végezni, ameddig a Values string minden elemét fel nem használjuk, így az üressé nem válik.