Page 1 of 2 1 2 LastLast
Results 1 to 15 of 16

Thread: Romeinse cijfers

  1. #1

    Romeinse cijfers

    Weinig credit voor mij deze keer. Ik zocht een manier om een getal om te zetten naar romeinse cijfers. Ik vond een functie om dit te doen. Deze was geschreven in C en heb ik vrijwel letterlijk vertaald naar Delphi. Het lijkt allemaal wel te werken, maar ik weet niet hoe het gaat met ongeldige invoer.
    De basis is er in ieder geval:
    Code:
    // Delphi vertaling van de functies op
    // http://www.nio.ntnu.no/archive/2001_2002/2/4l.php3
    
    function RomToInt(Rom: string): Integer;
    // Vertaalt Romeinse notatie naar Integer;
      function Value(rd: Char): Integer;
      begin
        case rd of
          'M': Result := 1000;
          'D': Result := 500;
          'C': Result := 100;
          'L': Result := 50;
          'X': Result := 10;
          'V': Result := 5;
          'I': Result := 1;
        else
          Result := 0;
        end;
      end;
    
    var
      i, d, lastd, val: Integer;
    begin
      val := 0;
      lastd := 0;
      for i := 1 to Length(Rom) + 1do
      begin
        d := Value(Rom[i]);
        if lastd < d then
          Dec(val, lastd)
        else
          Inc(val, lastd);
        lastd := d;
      end;
      Result := val;
    end;
    
    function IntToRom(i: Integer): string;
    // Vertaalt Integer naar Romeinse notatie;
    const
      M: array[0..3] of Char = ('I', 'X', 'C', 'M');
      D: array[0..3] of Char = ('V', 'L', 'D', '-');
    var
      deg, coef: Integer;
    begin
      coef := 100;
      for deg := 3 downto 1 do
      begin
        while i >= 10 * coef do
        begin
          Result := Result + M[deg];
          Dec(i, 10 * coef);
        end;
    
        if i >= 9 * coef then
        begin
          Result := Result + M[deg - 1];
          Result := Result + M[deg];
          Dec(i, 9 * coef);
        end;
    
        if i >= 5 * coef then
        begin
          Result := Result + D[deg - 1];
          Dec(i, 5 * coef);
        end;
    
        if i >= 4 * coef then
        begin
          Result := Result + M[deg - 1];
          Result := Result + D[deg - 1];
          Dec(i, 4 * coef);
        end;
        coef := coef div 10;
      end;
    
      Result := Result + StringOfChar('I', i);
    end;
    Last edited by GolezTrol; 08-Aug-07 at 18:08. Reason: Code opnieuw gehighlight, wegens nieuwe forum software
    1+1=b

  2. #2
    Old Navigator Matthijs's Avatar
    Join Date
    Mar 2001
    Location
    Ede, NL. Delphi: Delphi 7/2005 :). Matthijs schrijf je Matthijs
    Posts
    2,199
    Code:
      for i := 1 to Length(Rom) + 1 do
      begin
        d := Value(Rom[I]);
    En dit geeft geen foutmelding tijdens het runnen?

    Verder natuurlijk een hele leuke functie.
    What's in a sig?

    Would my posting be less valuable if it didnot have a sig? (Vrij naar William S.)

    Let op de kleine lettertjes. For all postings: e&oe!
    This program performed an illegal function, the police are on their way

  3. #3
    Old Navigator Matthijs's Avatar
    Join Date
    Mar 2001
    Location
    Ede, NL. Delphi: Delphi 7/2005 :). Matthijs schrijf je Matthijs
    Posts
    2,199
    Nog even verder nagedacht,

    misschien werkt dit wel
    Code:
    for I := Length(Rom) downto 1 do begin
      d := value(Rom[I]);
      if lastd >= d then dec(Val, d)
                    else inc(Val, d);
      lastd := d;
    end;
    Niet getest, want ik heb het zo direct neergetypt.
    What's in a sig?

    Would my posting be less valuable if it didnot have a sig? (Vrij naar William S.)

    Let op de kleine lettertjes. For all postings: e&oe!
    This program performed an illegal function, the police are on their way

  4. #4
    Wat voor foutmelding kreeg je dan? Ik kan het me wel voorstellen, want hij leest eigenlijk 1 teken te ver. Dit is in feite wat de C code ook doet, maar daarbij staat er natuurlijk een #0 achter (al zou dat in Delphi ook zo moeten zijn). Ik kreeg zelf geen fout bij het runnen van deze functie, maar als hij incidentieel een AV zou geven (want die krijg je dan waarschijnlijk bij het benaderen van Rom[length+1]), dan zou de makkelijkste aanpassing zijn om er dit van te maken:
    Code:
    Rom := Rom + ' ';
    for i := 1 to Length(Rom) do
    
    Last edited by GolezTrol; 12-Feb-05 at 20:36.
    1+1=b

  5. #5
    Old Navigator Matthijs's Avatar
    Join Date
    Mar 2001
    Location
    Ede, NL. Delphi: Delphi 7/2005 :). Matthijs schrijf je Matthijs
    Posts
    2,199
    Ik heb het niet geprobeerd de code te runnen, maar verwachtte eigenlijk een AV, omdat je voorbij de lengte van de string leest.
    Ik had er natuurlijk niet aangedacht dat Delphi er in verband met het casten naar een PChar al automatisch een #0 achterzet.
    En idd jouw oplossing is dan ook een mogelijkheid.
    What's in a sig?

    Would my posting be less valuable if it didnot have a sig? (Vrij naar William S.)

    Let op de kleine lettertjes. For all postings: e&oe!
    This program performed an illegal function, the police are on their way

  6. #6
    Ik ben nog niet zo goed met Delphi dat ik zelf weet hoe het precies moet. Hoe moet het Form eruit zien oid. en waar moet ik deze code neerzetten.

    Mvg,
    LinkWeb
    No signature...

  7. #7
    Waar je de code zelf wil hebben, vb onder een ButtonClick:
    Zet 2 TButton op je form (BtnRomanToInt en BtnIntToRoman)
    Zet 1 TEdit op je form (EdtInput)
    Zet 1 TLabel op je form (LblOutput)
    Dubbelklik op beide knoppen en zet volgende code:
    Code:
    procedure TForm1.BtnRomanToIntClick(Sender:TObject);
    begin
      LblOutput.caption:=inttostr(RomToInt(EdtInput.text));
    end;
    
    procedure TForm1.BtnIntToRomanClick(Sender:TObject);
    var
      getal:integer;
    begin
      try
        getal:=strtoint(EdtInput.text);
        LblOutput.caption:=IntToRom(getal);
      except
        Showmessage(format('"%s" wordt niet aanvaard als zijnde een getal.'#13#10
          'Gelieve een getal in te geven en opnieuw te proberen.',[EdtInput.text]));
        LblOutput.caption:='';
      end;
    end;
    DeX 3 Delphi := The ease of VB with the power of C; Zoekt en gij zult vinden

  8. #8
    Bedankt voor de hele snelle reactie . Ik ga het meteen proberen
    No signature...

  9. #9
    Het werkt, alleen krijg ik hier nog een foutmelding:
    Code:
    except
        Showmessage(format('"%s" wordt niet aanvaard als zijnde een getal.'#13#10
          'Gelieve een getal in te geven en opnieuw te proberen.',[EdtInput.text]));
        LblOutput.caption:='';
      end;
    No signature...

  10. #10
    notice-itter SvG's Avatar
    Join Date
    Apr 2002
    Location
    's-Hertogenbosch
    Posts
    4,865
    wat is die fout dan? Een vergeten + aan het eind van de 1e showmessage regel?
    !

  11. #11
    @Linkweb: Waar staat de cursor (regel en positie)?
    Normaal zou dit geen foutmelding mogen geven.
    Heb deze code niet getest en zomaar uit de mouw geschud, er kan mogelijk een foutje inzitten maar denk het niet
    DeX 3 Delphi := The ease of VB with the power of C; Zoekt en gij zult vinden

  12. #12
    Dom van mij om de foutmelding niet te laten zien. Dit was de foutmelding:

    [Error] Unit1.pas(117): Missing operator or semicolon
    [Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'

    Maar wat SVG_1986 zij dat er een + achter moest deed ie het goed
    No signature...

  13. #13
    Met regel bedoelde ik niet de regelnummer maar de regel in de code die ik gaf (wij kunnen niet zien welke regel 117 is )
    De regel met Showmessage moet je in code op 1 lijn weergeven, hier heb ik dit enkel gedaan omdat je anders horizontaal moest scrollen om alles te kunnen lezen.
    DeX 3 Delphi := The ease of VB with the power of C; Zoekt en gij zult vinden

  14. #14
    Ik snap het. Nu doet het 't weer goed. Hartelijk bedankt iedereen!
    No signature...

  15. #15
    Ik heb een kleine aanpassing gedaan in de IntToRom functie. > 10 moest natuurlijk >= 10 zijn, anders werd 1000 wel op een heel rare manier geschreven.

    Ook vond ik een vergelijkbare functie op www.Delphi3000.com. Deze is een stuk korter. Ik heb nog geen performance test gedaan, maar ik heb wel de resultaten even naast elkaar gezet (zo kwam ik ook achter dat foutje van hierboven ).
    Code:
    function DecToRoman(Decimal: Longint): string; 
    const 
      Numbers: array[1..13] of Integer = 
        (1, 4, 5, 9, 10, 40, 50, 90, 100, 
        400, 500, 900, 1000); 
      Romans: array[1..13] of string = 
        ('I', 'IV', 'V', 'IX', 'X', 'XL', 
        'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'); 
    var 
      i: Integer; 
    begin 
      Result := ''; 
      for i := 13 downto 1 do 
        while (Decimal >= Numbers[i]) do 
        begin 
          Decimal := Decimal - Numbers[i]; 
          Result  := Result + Romans[i]; 
        end; 
    end;
    1+1=b

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. checken of het cijfers (nummeriek) is/zijn
    By jdinge48 in forum Databases
    Replies: 29
    Last Post: 03-Jul-05, 16:37
  2. Controle op cijfers (via char)
    By casper in forum Algemeen
    Replies: 19
    Last Post: 19-Jun-05, 21:00
  3. Alleen maar cijfers in kolom van TStringGrid
    By Kleine83 in forum Algemeen
    Replies: 11
    Last Post: 16-Mar-04, 20:07
  4. Probleem met dubbele cijfers invoeren
    By john2000 in forum Algemeen
    Replies: 3
    Last Post: 17-Dec-03, 17:44
  5. Hoeveel cijfers in een integer
    By mark_delphi in forum Algemeen
    Replies: 13
    Last Post: 18-Aug-03, 09:44

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •