Algorithmus Umwandlung dezimale Zahlen in römische und umgekehrt



  • Moin Leute!

    Ich habe ein kleines Problem. Ich muß fürs Studium eine Hausarbeit in C++ schreiben, und komme da nicht weiter. Ich soll ein Programm schreiben, mit dem man römische Zahlen in Dezimalzahlen (1-3999) umwandelt und umgekehrt. Das in C++ zu programmieren wäre kein Problem, nur leider habe ich bisher noch keinen passenden Algorithmus gefunden. Ich hoffe ihr könnt mir helfen.
    Danke im voraus
    MfG Steven



  • So viel ich weiss ist noch Semesterferien 😃

    Und ansonsten ist es so, dass Dir hier wahrscheinlich niemand helfen wird, wenn er/sie nicht sieht, dass Du dich bemüht hast das Programm zu schreiben.
    Ein erster Ansatz des Programmes z.B.



  • Find deine Antwort ein bisschen unpassend: Ich habe genug Kollegen, die ich jederzeit anrufen könnte, die mir das in zwei Tagen fertig programmieren können, außerdem könnte ich ja auch sofort posten: "Wer schreibt mir mein Programm." Ich will es aber selber programmieren, habe schon mehrere Stunden überlegt und bin bisher noch nicht auf die richtige Idee gekommen. Überleg bitte vorher, wenn du nächstes mal was antwortest. Du solltest eigentlich wissen, daß es kein Porblem wäre jemanden zu finden, der für einen was programmiert, aber das will ich halt nicht, sondern selber schreiben.

    MfG
    Steven



  • Dez->röm

    Teste, wie oft du die Zahl ohne Rest durch tausend teilen kannst, so oft ist das m in der Zqahl. Dann ziehst du das so oft mal 100 von der Zahl ab und machst das ganze mit dem nächst kleineren usw. Wäre ein erster Ansatz



  • Erst einmal die Frage, wo kommst Du nicht weiter ? Du sagst nur Du kommst nicht weiter.

    Hast Du bisher überhaupt kein Codefragment ?

    Noch zum Verständnis, soll der Algorithmus nur römische Zahlen in das Dezimalsystem umwandeln und umgekehrt oder soll man damit auch arithmetische Operationen durchführen können ?



  • Danke erstmal für eure Hilfe, ich werd dann nochmal ein bisschen konkreter:
    Das mit dem durch 1000 teilen hab ich mir auch schon gedacht, aber das Problem sind dann solche Sachen wie IX, MIM, XIX usw. Irgendwie muß ich einen einheitlichen Algorithums finden, der auch das mit berücksichtigt.
    Naja, zur Not kann ich jauch immer noch ein Programm von 3999 Zeilen schreiben und jede Zahl einzeln zuweisen *gg*

    MfG
    Steven



  • @ smo
    nur umwandeln, keine sonstigen funktionen
    wollte erst anfangen zu proggen wenn ich erstmal nen sprachenunabhängiges gerüst habe, damit ich ins programm ein bisschen struktur reinkriege



  • Mathematisch mag das einfach sein, aber technisch scheint es nicht so trivial zu sein, da man einen Parser brauchen wird, um die ganzen Kombinationsmöglichkeiten im römischen Zahlensystem darstellen zu können.

    Mit welchem Buchstaben wird angefangen, welche sind die nächsten Buchstaben usw.

    mal gucken, ob mir was einfällt



  • Du mußt eigentlich nur die Eingabe von Anfang an durchgehen:

    ergebnis auf ß setzen
    erstmal die für jedes m eine 1000 draufaddieren
    sobald Du einmal was niedrigeres entdeckst mußt Du die Strategie ändern:
    immer noch das nächste Zeichen mit anschauen, hat das wieder einen höhren Wert, so mußt Du (höheren-niedrigeren Wert) dazuaddieren wegen der Spezialfälle wie IX und so. wenn es der gleiche Wert wieder ist, dann einfach diesen WErt aufaddieren und mit dem nächsten Zeichen fortfahren, wenn es ein höheres Zeichen ist dann ist die Syntax falsch



  • smo schrieb:

    Mathematisch mag das einfach sein, aber technisch scheint es nicht so trivial zu sein, da man einen Parser brauchen wird, um die ganzen Kombinationsmöglichkeiten im römischen Zahlensystem darstellen zu können.

    Mit welchem Buchstaben wird angefangen, welche sind die nächsten Buchstaben usw.

    mal gucken, ob mir was einfällt

    Mit lex/yacc ganz einfach 🙂



  • Ja, ich hab die Kanone jetzt genau auf den Spatzen gerichtet... was muß ich jetzt tun? 😃



  • Danke erstmal für die Hilfe soweit, ich werd morgen mal gucken ob ich mit den Tips weiterkomme



  • Zur Kontrolle, oder falls du es trotz dieser Tipps nicht geschafft haben solltest mal meine Version... War eigentlich nicht so schwer wie einige hier befürchtet haben... Umgekehrt sollte eigentlich ähnlich einfach sein. Du musst dich nur von unten nach oben mit dem %-Operator durchhangeln...
    😉

    .
    	#include <cstring>
    	unsigned RomanAtoi(const char* input)
    	{
    		static const unsigned roman[128] = {
    			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    			0, 0, 0, 100, 500, 0, 0, 0, 0, 1, 0, 0, 50, 1000, 0, 0,
    			0, 0, 0, 0, 0, 0, 5, 0, 10, 0, 0, 0, 0, 0, 0, 0,
    			0, 0, 0, 100, 500, 0, 0, 0, 0, 1, 0, 0, 50, 1000, 0, 0,
    			0, 0, 0, 0, 0, 0, 5, 0, 10, 0, 0, 0, 0, 0, 0, 0
    		};
    
    		const char* p = input + strlen(input);
    		unsigned rval = 0, prev = 0;
    		while(input != p--) {
    			unsigned curr = roman[*p];
    			if(curr < prev)
    				rval -= curr;
    			else {
    				rval += curr;
    				prev = curr;
    			}
    		}
    		return rval;
    	}
    

    EDIT: Kleiner Fehler... 🙄 😉



  • Kannst Du die Funktion bitte erklären. Sehe keinen %.



  • Da ist ein Fehler in deiner Funktion. Du darfst prev nur im
    else-Zweig aktualisieren, ansonsten gibts Probleme mit Zahlen wie IIX:
    da kommt bei dir 10 raus 🙂

    edit: Ich find deine Idee mit dem Array ein bissl unübersichtlich
    (auch wenns vielleicht zwei, drei Takte schneller ist :p)
    Schöner fänd ich ich Extrafunktion mit nem kleinen case drin.



  • Hmm, ich habe selbiges mal in TP für mein Studium geschrieben, habe 2 Varianten hier. Es würde sich mir noch ein Frage stellen, welches Format sollen die Römischen zahlen haben? Soll es die Kurzform sein oder die lange form. Die Kurzform würde bedeuten so kurz wie möglich, die langform würde bedeuteten tausender-hunderter-zehner-einer.
    Also wenn du von TP in C++ umwandeln kannst kann ich dir gerne beide Lösungen schicken.
    Allerdings ist eine davon nicht optimiert, weil ich damals keine Teit mehr dazu hatte und danach keine Lust mehr, würde ich nur machen wenn ich das Prog nochmal benötige.

    Ansonsten guck mal hier, Beispiel 5, da ist das von ner Uni:
    http://www.hki.uni-koeln.de/teach/c++ss03/tag16/index.html
    Ansonsten hier mal weitergucken:
    http://www.google.de/search?q="C%2B%2B"+%2B"Römische+Zahlen"&ie=UTF-8&oe=UTF-8&hl=de&meta=

    Code-Hacker



  • .. schrieb:

    Kannst Du die Funktion bitte erklären. Sehe keinen %.

    Den kannst du nur im umgekehrten Fall brauchen 😉 .



  • Taurin schrieb:

    Da ist ein Fehler in deiner Funktion. Du darfst prev nur im
    else-Zweig aktualisieren, ansonsten gibts Probleme mit Zahlen wie IIX:
    da kommt bei dir 10 raus 🙂

    Kleiner Denkfehler, danke.

    Taurin schrieb:

    edit: Ich find deine Idee mit dem Array ein bissl unübersichtlich
    (auch wenns vielleicht zwei, drei Takte schneller ist :p)
    Schöner fänd ich ich Extrafunktion mit nem kleinen case drin.

    Was stört dich an dem Array? Klar, Extrafunktion geht auch gut aber meine Version finde ich besser.



  • Danke erstmal für eure bisherige Hilfe!
    Ich hab das Programm fast fertig, Allerdings noch ein kleines Problem bei der Kontrolle ob die Eingabe der Benutzer richtig ist:
    ------------------------------------------------------------

    if ((eingabe[0]>='0'&&eingabe[0]<='9')&&
    (eingabe[1]>='0'&&eingabe[1]<='9')&&
    (eingabe[2]>='0'&&eingabe[2]<='9')&&
    (eingabe[3]>='0'&&eingabe[3]<='9'))
    {fehler =1;}

    if ((eingabe[0]>='0'&&eingabe[0]<='9')&&
    (eingabe[1]>='0'&&eingabe[1]<='9')&&
    (eingabe[2]>='0'&&eingabe[2]<='9'))
    {fehler =1;}

    if ((eingabe[0]>='0'&&eingabe[0]<='9')&&
    (eingabe[1]>='0'&&eingabe[1]<='9'))
    {fehler =1;}
    if ((eingabe[0]>='0'&&eingabe[0]<='9'))
    {fehler=1;}
    if (fehler ==0 || zahl> 3999) {
    cout << "Falsche Eingabe!!" <<endl;
    return 0;
    }
    ----------------------------------------------------------------

    eingelsen hab ich über nen char array und irgendwie muß ich ja jetzt auch überprüfen ob die Zahlen verwendbar sind
    oben seht ihr ihr eine Teil des Quelltextes (nicht meckern, ich weiß das da deklarationen usw. fehlen, ist nur ein ausschnitt aus ner funktion) zur kontrolle wenn dezimale zahlen eingegeben wurden, es ist übrigens nur nen zahlenbereich von 1-3999 erlaubt, meine idee hierbei: ich überprüfe ob eine der möglichen kombinationen (1234, 123; 12; 1) vorliegt, allerdings klappt das noch nicht so ganz, vielleicht hat da ja noch jemand ne idee
    das einzige was dann noch fehlt ist die überprüfung wenn römische ziffern eingegeben werden, da fällt mir hoffentlich noch was ein
    Danke nochmals für die hilfe!
    mfg
    Steven


Anmelden zum Antworten