Algorithmus Umwandlung dezimale Zahlen in römische und umgekehrt



  • @ 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