Autor |
Beitrag |
DocSol
Hält's aus hier
Beiträge: 14
|
Verfasst: Do 03.09.09 19:25
Hallo,
ich habe heute in der Schule die Aufgabe bekommen, ein Programm zu schreiben, welches ausgeschriebene Zahlen erkennt und in Dezimalwerte umwandelt...
Als Beispiel sei gennant:
Eine eingegebene "zwölf" soll vom Programm erkannt und in einer "12" umgewandelt werden. Oder auch eine "zweihundertdreiundvierzig" in eine "243".
Die Zahlen werden in ein Edit-Feld eingegeben und auf Knopfdruck sollen diese umgewandelt werden.
Gibt es da eine fertige Funktion für?
Danke schonmal für eure Hilfe. Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Do 03.09.2009 um 19:30
|
|
Webo
      
Beiträge: 577
Erhaltene Danke: 14
Win 7, Debian
C# (Visual Studio 2013), PHP, C, C++ (Eclipse, KDevelop)
|
Verfasst: Do 03.09.09 19:55
Nein, sofern ich weiss, gibt es dafür keine fertige Funktion. Doch:
Dies ist zwar die Umgekehrte Funktion, aber vllt. hilft sie dir ja, damit du den richtigen Gedankenblitz bekommst, wie du sowas realisieren könntest ...
_________________ Man kann nur das aus dem Ärmel schütteln, was man auch vorher reingesteckt hat.
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Do 03.09.09 20:03
Webo hat folgendes geschrieben : | Nein, sofern ich weiss, gibt es dafür keine fertige Funktion. Doch:
Dies ist zwar die Umgekehrte Funktion, aber vllt. hilft sie dir ja, damit du den richtigen Gedankenblitz bekommst, wie du sowas realisieren könntest ... |
Schließ mich dort an. Alternativ gibt's noch eine "Umgekehrte"-Funktion in der DP: http://www.delphipraxis.net/topic88367.html.
Grüße,
Marc
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Do 03.09.09 20:38
Hallo,
erstmal  in der EE.
eine fertige Funktion gibt es bestimmt irgendwo,
aber was nützt Dir die Funktion wenn Du den Code dann nicht erklären kannst.
- String zerlegen(! in 'hundert' ist auch ein 'und' enthalten !)
zweihundertvierundvierzig = > 'zwei' 'hundert' 'vier' 'und' 'vier' 'zig'
eintausendundelf => 'ein' 'tausend' 'und' 'elf'
- in Zahlen/Multiplikatoren umwandeln(! 'zwan' ist auch eine 2 in 'zwanzig' !)
zweihundertvierundvierzig
'zwei' -> 2
'hundert' -> * 100
'vier' -> 4
'und' -> +
'vier' -> 4
'zig' -> *10
eintausendunddreißig
'ein' -> 1
'tausend' * 1000
'und' -> +
'drei' -> 3
'ßig' * 10
- rechnen
überlass ich jetzt Dir 
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Fr 04.09.09 18:03
Hallo und danke schonmal für die nützlichen Tipps. Ich habe mir schonmal die umgekehrten Funktionen etwas angesehen. Ich hoffe, es wird nicht allzu kompliziert, diese Funktionen umzumodeln...
Mit "fertige Funktion" meinte ich eher etwas, was bei Delphi schon mit dabei ist... so ne Art StrToInt halt nur für die Wörter
Ich werd mal einfach schauen, wie weit ich da komme.
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Fr 04.09.09 18:30
wär ja etwas witzlos von deinem lehrer sowas zu verlangen und dann gibts das schon in delphi.
außerdem: Codegear müsste dann für jede sprache dieser welt diese Funktion implementieren und das wäre dann doch etwas mühsam  außerdem müsste die funktion dann noch automatisch die sprache erkennen, nem?
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Sa 05.09.09 12:16
Ja da hast du wohl recht.
Momentan verzweifel ich aber eher daran, meine ausgeschriebene Zahl zu zerlegen... Mit Pos und Copy komme ich da irgendwie nicht weiter.
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Sa 05.09.09 12:24
also ich würd es so machen, das ich mir zuerst die milliarde suche, dann alles inklusive dem milliarde aus dem ding rausschneide. dann hab ich vor dem milliarde ne zahl stehen, die mir angibt, wieviele milliarden ich hab, usw.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Sa 05.09.09 12:53
Ja genau ich wollte es so machen, wie Lannes es beschrieben hat. Aber wenn ich z.B. die erste Stelle suche (ich fange mal klein an mit der 'einhundert') habe ich das Problem, dass er mir nicht die 'ein' ausgibt.
Mal zur Veranschaulichung:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| try Result := StrToInt(zeile); except on EConvertError do begin for apos := 1 to length(zeile) do begin if (zeile[apos] = 'ein') OR (zeile[apos] = 'eins') OR (zeile[apos] = 'eine')then break else thilf := thilf + zeile[apos]; end; end; end; |
Ich möchte in thilf nun also nur ein, eins oder eine stehen haben damit ich diese dann konvertieren kann zur 1...
Aber er gibt mir immer die 'einhundert' aus...
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Sa 05.09.09 13:02
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Sa 05.09.09 13:06
Und wie kann ich dann am Besten den String nach 'ein', 'eins' oder 'eine' durchsuchen?
Ich stehe da momentan echt toal auf dem Schlach und komme nicht voran...
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Sa 05.09.09 13:08
Delphi-Quelltext 1:
| If(Pos(Zeichenkette, 'ein')>0)then vorhanden else nicht vorhanden; |
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Sa 05.09.09 13:51
Danke für deine Hilfe...
Ich habe mir nun einen weiteren Lösungsansatz überlegt bzw. mir wurde so etwas vorgeschlagen:
Ich durchsuche die ausgeschriebene Zahl zuerst nach den "Punkten" d.h. durchsuche den String nach 'millionen' und 'tausend'.
Die Zahl, die dann z.B. vor dem 'millionen' steht, konvertiere ich und multipliziere sie später einfach mit 1.000.000
Dafür habe ich mir dann folgendes ausgedacht:
Delphi-Quelltext 1: 2: 3: 4: 5:
| if (Pos(zeile, 'millionen') > 0) then begin mwert := Copy(zeile,0,Pos(zeile, 'millionen')-1); zeile := Copy(zeile,Pos(zeile, 'millionen')+8,length(zeile); end; |
Den Quellcode habe ich eben schnell aus dem Kopf geschrieben...
Wenn ich jetzt nicht total daneben liege, müsste ich in "mwert" dann den Millionenwert haben, den ich mit 1.000.000 multiplizieren kann und in "zeile" müsste der Rest der verbleibenden Zahl stehen (also die Zahl ab der Tausenderstelle) oder?
Mal als Beispiel mit der Zahl "dreihundertzwölfmillionenvierundachtzigtausendeinhundertundzwei" (312.084.102)
In der Variable "mwert" steht dann doch : "dreihundertzwölf"
und in "zeile" : "vierundachtzigtausendeinhundertundzwei"
Und genauso würde ich dann auch die Tausenderzahl "ausschneiden"...
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Sa 05.09.09 16:58
Also ich würde da ja so herangehen:
-> "eins" in "ein" und dann "ein" in "eins" umwandeln.
-> Danach (ich weiß, ist nicht EBNF):
Quelltext 1: 2: 3: 4: 5: 6: 7:
| einer = (eins, zwei, drei, vier, fünf, sechs, sieben, acht, neun) zehnfach = (zehn, zwanzig, dreisig, vierzig, fünfzig, sechzig, siebzig, achzig, neunzig) irrzehn = (elf, zwölf, dreizehn, vierzehn, fünfzehn, sechzehn, siebzehn, achzehn, neunzehn) zehner = zehner | irrzehn | einer+"und"+zehner hunderfach = einer+"hundert" | "hundert" hunderter = hundertfach + zehner | hundertfach + einer ... |
Mit entsprechenden Methoden IstZehner() usw. sollte das eigentlich gehen.
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Sa 05.09.09 18:31
Jakob ist dieser Lösungsvorschlag nicht eher dafür gedacht, aus Integerwerten ausgeschriebene Zahlen zu erstellen? So verstehe ich das jedenfalls...
Woran genau kann es eigentlich liegen, wenn ich mit dem 'Pos' Befehl innerhalb meines String das gesuchte Wort nicht finde?
Ich habe z.B. die Zahl "einemillionen" und suche mit 'Pos' nach der Zeichenfolge "millionen". Die wird allerdings nicht gefunden.
Delphi-Quelltext 1: 2: 3: 4: 5:
| if (Pos(zeile, 'millionen') > 0) then begin ShowMessage('Es sind Millionen vorhanden'); break; end; |
So siehts aus... Das 'break;' ist nur für mich da, muss also nicht beachtet werden.
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Sa 05.09.09 19:35
Hallo,
bist Du Dir sicher das Du "einemillionen" in Deinem zu durchsuchenden String hast?
Richtig geschrieben ist das:
eine Million
zwei Millionen
 Erst nach "millionen" suchen, dann nach "million"
Dein anderes Beispiel kann auch unterschiedlich geschrieben sein
"dreihundertzwölfmillionenvierundachtzigtausendeinhundert undzwei"
"dreihundertzwölf Millionen vierundachtzigtausendeinhundertzwei"
Laut Rechtschreibung werden ausgeschriebene Zahlen gößer 1.000.000 durch Leerzeichen getrennt.
Z.B. kann auch die Zahl 1987 in mehreren Varianten geschrieben sein:
eintausendneunhundertsiebenundachtzig
neunzehnhundertundsiebenundachtzig
neunzehnhundertsiebenundachtzig
Noch ein schönes Beispiel:
Duden: dreißig
aus dem Code vom Delphi-treff: dreisig
falsch geschrieben dreissig
oder wie ist es mit Umlauten
"zwölf" ist eindeutig
"zwoelf" = "zwo" und "elf"
Sind die zu verarbeitenden Zahlenstrings eindeutig oder soll Dein Programm auch solche Probleme abfangen?
Also zuerst die eindeutigen, wie schon bei der "million(en)" zuerst suchen und dann die Reststrings weiter splitten:
zwoelftausendelf
zwoelf tausendelf
zwoelf tausend elf
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
DocSol 
Hält's aus hier
Beiträge: 14
|
Verfasst: Sa 05.09.09 20:17
In den Beispielen, die bei der Aufgabenstellung dabei waren, wurden die ausgeschriebenen Zahlen zusammen geschrieben. Und ich habe in meinem String zum Testen sogar nur "einemillionen" stehen gehabt. Dennoch wurde das "millionen" nicht gefunden. Wenn ich jedoch nur das Wort "millionen" im String habe, wird es gefunden.
Ich gehe von eindeutigen Zahlenstrings aus. Also "dreihundertzwölfmillionenvierundachtzigtausendeinhundertundzwei" (mit UND) usw...
Ä, Ü und Ö gehen auch.
Zahlen wie 1987 (Neunzehnhundertsiebenundachtzig) gibt es nicht... es ist also "Eintausendneunhundertsiebenundachtzig"
Wie schon erwähnt, klappt das Suchen mit Pos nicht so, wie ich es gerne hätte... also obwohl im String das wort "millionen" vorkommt, wird es nicht gefunden.
Splitten werde ich diesen String dann in unterschiedliche Variablen, mit denen ich weiter arbeite.
|
|
FinnO
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Sa 05.09.09 21:08
dein Problem könnte groß und kleinschreibung sein, wandle den String vorher mal mit s := lowercase(s:String); um.
Dein Programm sollte neunzehnhundertundneunundneunzig eh erkennen da:
neun
* zehn
* hundert
+ (und) neun
+ (und) neun
* (zig) 10
= 1999
Achtung: dabei ist es Wichtig, dass du das zig nur auf die neun und nicht auf den Rest anwendest.
Meine allgmeine Vorgehensweise wäre also ungefähr:
Man beginnt immer mit der Zahl 1, es sei denn, das Wort beginnt mit:
"zwei"
"drei"
"vier"
...
"zwölf"
danach folgt eig. immer
"zig"
"hundert"
"tausend"
"millionen"
etc.
welches dann entsprechend multipliziert, oder bei
"zehn"
addiert wird, bzw. bei
"und"
eine Addition einleitet.
ich überlege gerade, ob man das nicht evtl. Rekursiv lösen könnte...
Man könnte sozusagen eine "expect"-Funktion einbauen, die diese Regeln "beherrscht", und beschließt, was als nächstes kommt.
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: So 06.09.09 00:26
Hallo,
FinnO hat folgendes geschrieben : |
Man beginnt immer mit der Zahl 1, es sei denn, das Wort beginnt mit:
"zwei"
"drei"
"vier"
...
"zwölf"
danach folgt eig. immer
"zig" |
eigentlich, da bleiben dann aber noch so ca. sieb enzig Ausnahmen
FinnO hat folgendes geschrieben : | ich überlege gerade, ob man das nicht evtl. Rekursiv lösen könnte... |
ja.
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
FinnO
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: So 06.09.09 10:41
@ siebenzig: siebenzig würde ja auch funktionieren. Na und? Tatsache ist, das Programm wandelt alle Zahlen um, und welche, die keine sind, recht genau auch.
Generell sollte man aber lieber Zahlen wie "Sieben" vorher schon zu "sieb" verkürzen (genau wie "zwei" zu "zwo" usw.)
|
|
|