[C/C++] Römische Zahlen in Dezimal

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von »The Gr4ndp4, 17. November 2009 .

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 17. November 2009
    Römische Zahlen in Dezimal

    Hallo, ich soll für die Schule ein PAP zum Thema, Römische Zahlen in Dezimal umrechnen, machen.

    hab schon überlegt wie ich das am besten um setzen kann, kann mir einer von euch helfen, wie ich das am besten Umsetze, also ein vernütigen algorythmus, den ich in ein PAP umsetzen kann.

    danke
     
  2. 17. November 2009
    AW: Römische Zahlen in Dezimal

    Schau doch einfach mal bei Wikipedia vorbei und überleg ein wenig:

    Römische Zahlschrift – Wikipedia

    Hausaufgaben macht dir hier keiner - hier werden nur Probleme anhand von vorhandenem Code oder probleme WÄHREND der Arbeit gelöst.

    - - -
    Tanya
     
  3. 17. November 2009
    AW: Römische Zahlen in Dezimal

    Hey danke erstmal.

    Habe ja auch nich gesagt, das jemand meine Hausaufgaben machen soll, nur nen Lösungsanfang, damit ich wiss wie ich es umsetzen soll =)
     
  4. 17. November 2009
    AW: Römische Zahlen in Dezimal

    Würde ich in C++ dann so lösen:

    Code:
    String StrRomZahl = "MDCCCCLXXXIIII"; // römische Zahl (als AnsiString)
    int iRomWert = 0; // hier addierst du die Summe der Zahlen
    
    // Schleife mit der du jede Position des AnsiString abfragen kannst
    for (int i = 1; i <= StrRomZahl.Length(); ++i)
    {
     if (StrRomZahl[i] == 'I') iRomWert++; // +1
     else if (StrRomZahl[i] == 'X') iRomWert += 10; // +10
     [B]... etc. [/B]
    }
    
    Hoffe das hilft dir weiter!
     
  5. 17. November 2009
    AW: Römische Zahlen in Dezimal

    Wie Bonsai schon sagte:
    Du hast einen String, in dem die Zahl steht und ein integer, in den das Ergebnis soll. Dann iterierst du durch den String (Buchstabe für Buchstabe) und addierst dann den Wert, der dem Buchstaben entspricht. Anstatt mit vielen if's würde ich es mit switch lösen, aber das ist Ansichtssache.

    Am besten definierst du am Anfang der Datei ein Array oder mit den ganzen Werten; oder du packst ein paar Präprozessor #define's rein. Dann gehts fix.

    greez
     
  6. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Musst du das denn mit oder ohne substraktionregel machen?

    Ansonsten ist z.B. IV = 4
    in den code beispielen währe es aber = 6

    Sonst musst du halt beachten in welcher Reihenfolge zeichen auftreten...

    Tipp: Bei der Substraktionsregel gibt es immer nur EIN subtrahierendes Zeichen! d.h. IIV geht nicht..

    mfg
    Joker
     
  7. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Ja, guter Gedankengang.
    Schreibt man z.B. als römische Zahl MMIX sollte 2009 rauskommen, tatsächlich kommt halt 2011 raus.

    Bin auch noch relativ neu in C/C++, wie würde man das lösen, dass man diese Problem nicht hat?

    MfG
     
  8. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Code:
    String StrRomZahl = "MDCCCCLXXXIIII"; // römische Zahl (als AnsiString)
    int iRomWert = 0; // hier addierst du die Summe der Zahlen
    
    // Schleife mit der du jede Position des AnsiString abfragen kannst
    for (int i = 1; i <= StrRomZahl.Length() [COLOR="Red"]- 1[/COLOR]; ++i)
    {
     if (StrRomZahl[i] == 'I' && StrRomZahl[i[COLOR="Red"]+1[/COLOR]] != 'V')
     {
     iRomWert++; // +1
     }
     else if (StrRomZahl[i] == 'I' && StrRomZahl[i[COLOR="Red"]+1[/COLOR]] == 'V')
     {
     iRomWert += 4;
     }
     [COLOR="Blue"]... etc.[/COLOR] 
    }
    
    // und dann noch ne Abfrage für das letzte Zeichen im AnsiString
    // weil dieses sonst fehlen würde (wegen dem -1 in der Bedingung der Schleife)
    if (StrRomZahl[StrRomZahl.Length()] == 'I') iRomWert++; // +1
    [COLOR="Blue"]... etc.[/COLOR]
     
  9. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Hallo!

    In dem Zusammenhang ist ein 'switch'-Statement sehr helfreich.

    Ich wuerde das so loesen (hoffe das funktioniert ):
    Code:
    for (x = 0; x < len; x++)
    {
     switch (str[x])
     {
     case 'I':
     if (((x+1) != len) && str[(x+1)] != 'I')
     --zahl;
     else
     ++zahl;
     break;
     // ...
     }
    }
    Mfg,

    Kolazomai
     
  10. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Hey danke euch allen, ich denke mal das reicht, damit ich es in einen PAP umsetzen kann, danke
     
  11. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Vom Prinzip tut das hier.
    Bis auf die IV-Sonderfälle etc.

    Code:
    
    #include <cstdlib>
    #include <conio.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
     string sRoemischeZahl = "";
     int dArabischeZahl = 0;
     
     cout << "Geben Sie bitte Ihre roemische Zahl ohne Leerzeichen ein!\n"
     << "Erlaubt sind folgende Ziffern:\n"
     << "I - V - X - L - C - D - M\n"
     << "\n"
     << "Eingabe: ";
     
     cin >> sRoemischeZahl;
     transform(sRoemischeZahl.begin(), // Falls der String Kleinbuchstaben enthält,
     sRoemischeZahl.end(), // werden diese hier in Großbuchstaben
     sRoemischeZahl.begin(), // konvertiert
     ::toupper);
     
     for (int i = 0; i <= sRoemischeZahl.length(); i++)
     {
     if (sRoemischeZahl[i] == 'I')
     {
     dArabischeZahl += 1;
     }
     
     else if (sRoemischeZahl[i] == 'V')
     {
     dArabischeZahl += 5;
     }
     
     else if (sRoemischeZahl[i] == 'X')
     {
     dArabischeZahl += 10;
     }
     
     else if (sRoemischeZahl[i] == 'L')
     {
     dArabischeZahl += 50;
     }
     
     else if (sRoemischeZahl[i] == 'C')
     {
     dArabischeZahl += 100;
     }
     
     else if (sRoemischeZahl[i] == 'D')
     {
     dArabischeZahl += 500;
     }
     
     else if (sRoemischeZahl[i] == 'M')
     {
     dArabischeZahl += 1000;
     }
     
     
     }
     
     cout << "Ihre roemische Zahl als arabische Zahl ergibt: " << dArabischeZahl << endl;
     
     
     
     getch();
     return 0;
    }
    
    Kann mir mal jemand sagen, warum das mit einer while-Schleife bzw. do-while-Schleife nicht funktioniert?

    Code:
    
    #include <cstdlib>
    #include <conio.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
     string sRoemischeZahl = "";
     int dArabischeZahl = 0;
     
     
     cout << "Geben Sie bitte Ihre roemische Zahl ohne Leerzeichen ein!\n"
     << "Erlaubt sind folgende Ziffern:\n"
     << "I - V - X - L - C - D - M\n"
     << "\n"
     << "Eingabe: ";
     
     cin >> sRoemischeZahl;
     transform(sRoemischeZahl.begin(), // Falls der String Kleinbuchstaben enthält,
     sRoemischeZahl.end(), // werden diese hier in Großbuchstaben
     sRoemischeZahl.begin(), // konvertiert
     ::toupper);
     
     
     int i = 0;
     
     while (i <= sRoemischeZahl.length()) 
     {
     if (sRoemischeZahl[i] == 'I')
     {
     dArabischeZahl += 1;
     i++;
     }
     
     else if (sRoemischeZahl[i] == 'V')
     {
     dArabischeZahl += 5;
     i++;
     }
     
     else if (sRoemischeZahl[i] == 'X')
     {
     dArabischeZahl += 10;
     i++;
     }
     
     else if (sRoemischeZahl[i] == 'L')
     {
     dArabischeZahl += 50;
     i++;
     }
     
     else if (sRoemischeZahl[i] == 'C')
     {
     dArabischeZahl += 100;
     i++;
     }
     
     else if (sRoemischeZahl[i] == 'D')
     {
     dArabischeZahl += 500;
     i++;
     }
     
     else if (sRoemischeZahl[i] == 'M')
     {
     dArabischeZahl += 1000;
     i++;
     }
     
     
     } 
     
     cout << "Ihre roemische Zahl als arabische Zahl ergibt: " << dArabischeZahl << endl;
     
     
     
     getch();
     return 0;
    }
    
    Ich stehe gerade echt auf dem Schlauch.
    Das Programm arbeitet die Schleife einfach nicht ab :/
     
  12. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Kann man mit Switch den Strings überhaupt vergleichen??
    Dachte das geht nicht?

    mfg
    Joker
     
  13. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Mir ist gerade aufgefallen, dass wenn ich bei der while-Schleife i<=0 schreibe und nur ein Zeichen eingebe (z.B. M), dann läuft die Schleife durch.

    Der String darf nicht mehr als ein Zeichen haben und i nicht größer 0 werden.
    Woran liegt das bitte, mit der for-Schleife geht es doch ohne Probleme?!
     
  14. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Mir war gestern langweilig. C#-Code im Spoiler

    Spoiler
    Code:
    public static class Roemisch
     {
    
     private static string ziffern = "ivxlcdm";
     private static int[] werte = new int[] { 1, 5, 10, 50, 100, 500, 1000 };
     /// <summary>
     /// Wandelt einen String aus römischen Ziffern
     /// in eine arabische Zahl um.
     /// Das höchste römische Zeichen darf ein M sein!
     /// </summary>
     /// <param name="zahl">Wert in römischen Ziffern (IVXLCDM sind unterstützt)</param>
     /// <returns>Wert in arabischen Zahlen</returns>
     public static int RoemischToArabisch(string zahl)
     {
     /*
     * Zeichen I V X L C D M 
     * Wert 1 5 10 50 100 500 1000
     */
     int ergebnis = 0;
     foreach (char c in zahl)
     {
     if (!zahl.Contains(c))
     {
     throw new NotSupportedException("Ein Teil der eingegebenen Zeichen wird nicht unterstützt!");
     }
     }
    
     zahl = zahl.ToLower();
    
    
     int i, idx0 = 0, idx1 = 0;
    
     if (zahl.Length > 1)
     {
     // Wir laufen durch den Ziffernstring immer
     // im Vorausschauen; also von 0 bis x-1
     for (i = 0; i < zahl.Length - 1; i++)
     {
     // Wertigkeit der Ziffer wird
     // über die Größe des Index angegeben
     // 
     // Nun die aktuelle Wertigkeit und die
     // Wertigkeit der nachfolgenden Ziffer
     // holen
     idx0 = ziffern.IndexOf(zahl[i + 0], 0);
     idx1 = ziffern.IndexOf(zahl[i + 1], 0);
    
     if (idx0 < idx1)
     {
     // die aktuelle Ziffer ist kleiner
     // als die nachfolgende, somit abziehen
     ergebnis -= werte[idx0];
     }
     else
     {
     // die aktuelle Ziffer ist größer
     // oder gleich der nachfolgenden, somit addieren
     ergebnis += werte[idx0];
     }
     }
     // Zuletzt muss noch die letzte Ziffer (immer) draufaddiert werden
     ergebnis += werte[idx1];
     }
     else
     {
     ergebnis = werte[ziffern.IndexOf(zahl[0], 0)];
     }
     return ergebnis;
     }
    
    
    
     public static string ArabischToRoemisch(int zahl)
     {
     StringBuilder sb = new StringBuilder();
     string tmp;
     int i = 0;
     while (zahl > 0)
     {
     int digit = zahl % 10;
     zahl = zahl / 10;
    
     switch (digit)
     {
     case 1:
     sb.Insert(0, ziffern[i]);
     break;
     case 2:
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i]);
     break;
     case 3:
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i]);
     break;
     case 4:
     sb.Insert(0, ziffern[i+1]);
     sb.Insert(0, ziffern[i]);
     break;
     case 5:
     sb.Insert(0, ziffern[i + 1]);
     break;
     case 6:
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i + 1]);
     break;
     case 7:
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i+1]);
     break;
     case 8:
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i]);
     sb.Insert(0, ziffern[i + 1]);
     break;
     case 9:
     sb.Insert(0, ziffern[i+2]);
     sb.Insert(0, ziffern[i]);
     break;
     default:
     break;
     }
     i += 2;
     }
     return sb.ToString();
     }
    
    
     }
    
     
  15. 18. November 2009
    AW: Römische Zahlen in Dezimal

    Nein mit Strings geht es auch nicht. Aber wie man erkennt vergleicht diese Switch-Anweisung character (also nur einzelne Zeichen) und keine kompletten Strings (durch die einfachen Anführungszeichen in den "case 'x':" erkennbar) und funktioniert somit durchaus
     
  16. 18. November 2009
    AW: Römische Zahlen in Dezimal

    @Tanya

    Code:
    foreach (char c in zahl)
    {
     if (!zahl.Contains(c))
     {
     throw new NotSupportedException("Ein Teil der eingegebenen Zeichen wird nicht unterstützt!");
     }
    }
    die schleife ist unsinn, da alle "c"'s in "zahl" vorkommen werden, wenn du sie zuvor aus "zahl" ausliest.

    Code:
    zahl = zahl.ToLower();
    foreach (char c in zahl) {
     switch(c) {
     case 'i':
     case 'v':
     case 'x':
     case 'l':
     case 'c':
     case 'd':
     case 'm':
     break;
     default:
     throw new NotSupportedException("Ein Teil der eingegebenen Zeichen wird nicht unterstützt!");
     }
    }
    wobei das mit nem array oder nem regex vielleicht sogar schneller wäre.

    // hier meine version in java (lässt sich mit sicherheit zu c++ portieren)
    Spoiler
    Code:
    import java.util.HashMap;
    
    public class Rom
    {
     public static void main(String[] args) 
     {
     if(args.length == 0) {
     System.out.println("bitte zahl als argument angeben: java Rom __ZAHL__");
     System.exit(0);
     }
     
     String num = args[0].toLowerCase(); 
     HashMap assoc = new HashMap();
     assoc.put('i', 1);
     assoc.put('v', 5);
     assoc.put('x', 10);
     assoc.put('l', 50);
     assoc.put('c', 100);
     assoc.put('d', 500);
     assoc.put('m', 1000);
     
     char index;
     int sum = 0, item, prev = 0;
     for(int i = 0, to = num.length(); i < to; ++i) {
     index = num.charAt(i);
     if(!assoc.containsKey(index)) {
     System.out.print((new StringBuilder())
     .append("invalides zeichen in zahl gefunden: \"")
     .append(index)
     .append("\"")
     .toString()
     );
     System.exit(1);
     }
     
     item = (Integer) assoc.get(index);
     sum += item;
     
     if(prev > 0 && item > prev)
     sum -= prev * 2;
     
     prev = item;
     }
     
     System.out.print("Dezimalwert von \"" + num + "\" ist ");
     System.out.print(sum);
     System.exit(0);
     }
    }
    

    //edit und hier in c++
    Spoiler
    Code:
    #include <iostream>
    #include <string>
    #include <map> 
    
    int main(int argc, char *argv[]) 
    {
     if(argc == 1) {
     std::cout << "bitte zahl als argument angeben: rom __ZAHL__";
     return 0;
     }
     
     std::string num = argv[1];
     std::transform(num.begin(), num.end(), num.begin(), &tolower);
     
     std::map<char, int> assoc;
     assoc['i'] = 1;
     assoc['v'] = 5;
     assoc['x'] = 10;
     assoc['l'] = 50;
     assoc['c'] = 100;
     assoc['d'] = 500;
     assoc['m'] = 1000;
     
     char index;
     int sum = 0, item, prev = 0;
     for(int i = 0, to = num.length(); i < to; ++i) {
     index = num[i];
     if(!assoc[index]) {
     std::cout << "invalides zeichen in zahl gefunden: \"" << index << "\"";
     return 1;
     }
     
     item = (int) assoc[index];
     sum += item;
     
     if(prev > 0 && item > prev) 
     sum -= prev * 2;
     
     prev = item;
     }
     
     std::cout << "Dezimalwert von \"" << num << "\" ist " << sum;
     return 0;
    }
    
    //eof
    
     
  17. 19. November 2009
    AW: Römische Zahlen in Dezimal

    Argh xD Hab ich doch glatt übersehen! ;-)

    An den Threadersteller, wie liefs denn jetzt mit dem PAP?

    mfg
    Joker
     
  18. 19. November 2009
    AW: Römische Zahlen in Dezimal

    Muss das erst zur näcshten Woche machen, werd mich am we hin setzen, und mal versuchen, aus den ganzen Hilfen hier nen PAP zu basteln =)

    //
    Wir arbeiten hier in der Schule nur mit C, also mit printf und scanf und sowas
    Und die Quellcodes stehen hier nur in C# oder Java oder so.

    Hat jemand zufällig den Code in normalen C ^^
     
  19. 19. November 2009
    AW: Römische Zahlen in Dezimal

    du kannst dir aus funktionerenden c#, java und c++ codes immer noch nicht alleine was zusammenbauen?

    sorry, aber für mich sieht das so aus als hättest du keinen bock.

    //da in c, viel spaß ...
    Spoiler
    Code:
    #include <stdio.h>
    
    int rchr2int(char chr)
    {
     switch(tolower(chr)) {
     case 'i': return 1;
     case 'v': return 5;
     case 'x': return 10;
     case 'l': return 50;
     case 'c': return 100;
     case 'd': return 500;
     case 'm': return 1000;
     default: return 0;
     }
    }
    
    int main(int argc, char *argv[])
    {
     if(argc == 1) {
     printf("bitte zahl als argument angeben: rom __ZAHL__");
     return 0;
     }
     
     char index;
     int sum = 0, item, prev = 0;
     while((index = argv[1][i++])) {
     item = rchr2int(index);
     if(item == 0) {
     printf("invalides zeichen in zahl gefunden: %c", index);
     return 1;
     }
     
     sum += item;
     if(prev > 0 && item > prev)
     sum -= prev * 2;
     
     prev = item;
     }
     
     printf("dezimalwert von \"%s\" ist %d", argv[1], sum);
     return 0;
    }
    
    //eof
     
  20. 19. November 2009
    AW: Römische Zahlen in Dezimal

    Mhh, ich habe das Fach erst seit 3 Monaten :>
    Bin da noch nich so der Pro, aber danke an alle
    close
     
  21. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.