So, das hat mir ja keine Ruhe gegeben. Hier eine Lösung, welche meiner vorherigen sehr nahe kommt, allerdings den Roman-Numeral-String von hinten aufrollt.
Dieses Mal nur die optimierte Version. Im Vergleich zur vorhergehenden optimierten Variante liegt der Performance-Gewinn bei weit unter einem Prozent - beide sind also (fast) gleichwertig.
Man nehme die, die einem besser gefalle.
Delphi-Quellcode:
function RomanToDec5Optimized(
const Roman:
String): LongInt;
var
Current, This, IPos: Integer;
begin
// endergebnis
Result := 0;
// current hält den letzten ermittelten wert
Current := 0;
This := 0;
// jedes roman testen und verarbeiten
// dabei merkt sich der algo, die aktuelle position im string
// das ist schneller, als den string an und für sich zu manipulieren
IPos := Length(Roman);
while IPos > 0
do
begin
// nächstes roman holen
case Roman[IPos]
of
// die sonder-numerals sind 3 char lang, deshalb INC(IPos, 3)
'
}':
begin
This := 1000000;
Dec(IPos, 3);
end;
'
]':
begin
This := 100000;
Dec(IPos, 3);
end;
'
)':
begin
This := 10000;
Dec(IPos, 3);
end;
// die standard-numerals sind 1 char lang
'
M':
begin
This := 1000;
Dec(IPos);
end;
'
D':
begin
This := 500;
Dec(IPos);
end;
'
C':
begin
This := 100;
Dec(IPos);
end;
'
L':
begin
This := 50;
Dec(IPos);
end;
'
X':
begin
This := 10;
Dec(IPos);
end;
'
V':
begin
This := 5;
Dec(IPos);
end;
'
I':
begin
This := 1;
Dec(IPos);
end;
else
// fehlerhaft, skip
Dec(IPos);
Continue;
end;
if This < Current
then
Dec(Result, This)
else
Inc(Result, This);
Current := This;
end;
end;
...
...