Wpisany przez Stefan Pruszkiewicz,
08 czerwca 2010 20:11
Bardzo często spotykam się na forach i w programach z problemem zamiany liczb na postać słowną. Zauważyłem że prawie nigdzie nie jest uwzględniona polska gramatyka, przykładowo liczba 112004033 wygląda co najmniej tak jed*jed*dwa*zero*zero*cztery*zero*trzy*trzy lub w najlepszym przypadku tak sto dwanascie mln. cztery tys. trzydziesci trzy.
Dla każdego rzędu wielkości w polskiej gramatyce występują trzy formy:
Algorytm bazuje na prawidłowości, że każda liczba składa się z trzy cyfrowych elementów oddzielonych rzędami wielkości. W jednym kroku będziemy zamieniać na postać po trzy cyfry jednocześnie. W tym celu zdefiniujemy następujące zmienne:
zdefiniujemy sobie następujące tablice:
jednosci[0..9] o wartościach odpowiednio '', ' jeden', ' dwa', ' trzy', ' cztery', ' piec', ' szesc', ' siedem', ' osiem', ' dziewiec'
nascie[0..9] o wartościach '', ' jedenascie', ' dwanascie', ' trzynascie', ' czternascie', ' pietnascie', ' szesnascie', ' siedemnascie', ' osiemnascie', ' dziewietnascie'
dziesiatki[0..9] o wartościach '', ' dziesiec', ' dwadziescia', ' trzydziesci', ' czterdziesci', ' piecdziesiat', ' szescdziesiat', ' siedemdziesiat', ' osiemdziesiat', ' dziewiecdziesiat'
setki[0..9] o wartościach '', ' sto', ' dwiescie', ' trzysta', ' czterysta', ' piecset', ' szescset', ' siedemset', ' osiemset', ' dziewiecset'
oraz dwu-wymiarową tablicę grupy [0..6, 0..2] o wartościach:
('' ,'' ,'')
(' tysiac' ,' tysiace' ,' tysiecy')
(' milion' ,' miliony' ,' milionow')
(' miliard',' miliardy',' miliardow')
(' bilion' ,' biliony' ,' bilionow')
(' biliard',' biliardy',' biliardow')
(' trylion',' tryliony',' trylionów')
która przechowywuje rzędy wielkości wraz z ich trzema formami.
Algorytm będzie przebiegał następująco:
wynik = ''
Jezeli liczba = 0 wynik = 'zero', koniec algorytmu.
Jeżeli liczba < 0 znak = 'minus', liczba = -liczba, w przeciwnym razie znak = ''
Zainicjuj początkowy rząd liczby: g = 0
dopóki liczba różna od 0
s = liczba mod 1000 div 100
d = liczba mod 100 div 10
j = liczba mod 10
jeżeli liczba dziesiątek d jest równa 1 oraz liczba jedności j jest większa od 0 to wówczas mamy do czynienia z nastkami czyli:
n = j
d = 0
j = 0
w przeciwnym razie nie ma nastek
n = 0
teraz musimy wybrać odpowiednią formę gramatyczną:
jeżeli j = 1 oraz s+d+n = 0 to k = 0, pierwsza forma gramatyczna
jeżeli j = 2 lub 3 lub 4 to k = 1, druga forma gramatyczna
w pozostałych przypadkach k = 2, trzecia forma gramatyczna
teraz jeżeli wartość grupy jest większa od zero s+d+n+j > 0 to do wyniku dopisujemy wynik translacji grupy:
wynik = setki[s] + dziesiaki[d] + nascie[n] + jednosci[j] + grupy[g,k] + wynik
g = g + 1
liczba = liczba div 1000
wynik = znak + wynik
liczba = 15123541
liczba jest większa od 0 zatem znak = ''
wynik = ''
g = 0
obliczamy s, d, j
s = 15123541 mod 1000 div 100 = 541 div 100 = 5
d = 15123541 mod 100 div 10 = 41 div 10 = 4
j = 15123541 mod 10 = 1
liczba dziesiątek jest równa 4 zatem n = 0
wybieramy formę, j = 1 ale s+d+n > 0 zatem wybieramy trzecią formę gramatyczną k = 2
wartość wynik = ' piecset' + ' czterdziesci' + '' + ' jeden' + '' + ''
zwiększamy rząd g = 0 + 1 = 1
przechodzimy do kolejnej grupy trzech cyfr liczba = 15123541 div 1000 = 15123
obliczamy s, d, j
s = 15123 mod 1000 div 100 = 123 div 100 = 1
d = 15123 mod 100 div 10 = 23 div 10 = 2
j = 15123 mod 10 = 3
liczba dziesiątek jest równa 2 zatem n = 0
wybieramy formę, j = 3 zatem wybieramy drugą formę gramatyczną k = 1
wartość wynik = ' sto' + ' dwadziescia' + '' + ' trzy' + ' tysiace' + ' piecset czterdziesci jeden'
zwiększamy rząd g = 1 + 1 = 2
przechodzimy do kolejnej grupy trzech cyfr liczba = 15123 div 1000 = 15
obliczamy s, d, j
s = 15 mod 1000 div 100 = 15 div 100 = 0
d = 15 mod 100 div 10 = 15 div 10 = 1
j = 15 mod 10 = 5
liczba dziesiątek jest równa 1 oraz liczba jedności jest większa od 0 zatem n = 5, d = 0, j = 0
wybieramy formę, j = 0 zatem wybieramy trzecią formę gramatyczną k = 2
wartość wynik = '' + '' + ' pietnasice' + '' + ' milionow' + ' sto dwadziescia trzy tysiace piecset czterdziesci jeden'
zwiększamy rząd g = 2 + 1 = 3
przechodzimy do kolejnej grupy trzech cyfr liczba = 15 div 1000 = 0
liczba jest rowna 0, zatem zakończyliśmy proces tłumaczenia na formę słowną, wejściowa liczba była większa od zero zatem znak = '' czyli ostateczny wynik to:
' pietnascie milionow sto dwadziescia trzy tysiace piecset czterdziesci jeden'
Dla każdego rzędu wielkości w polskiej gramatyce występują trzy formy:
tysiąc | tysiące | tysięcy |
milion | miliony | milionów |
miliard | miliardy | miliardów |
bilion | biliony | bilionów |
biliard | biliardy | biliardów |
trylion | tryliony | trylionów |
... | ... | ... |
- Pierwsza froma występuje tylko dla liczby pojedynczej (1 tysiąc, 1 milion, ...)
- Druga forma występuje dla liczb 2, 3, 4, 22, 23, 24, 32, 33, 34, ..., 102, 103, 104, 122, 123, 124, ... tysiące, miliony, ... - czyli dla wszystkich końcówek 2, 3, 4 za wyjątkiem 'nastek'
- Trzecia forma występuje w pozostałych przypadkach czyli 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 25, 26, ... tysięcy, milionów, ...
Algorytm bazuje na prawidłowości, że każda liczba składa się z trzy cyfrowych elementów oddzielonych rzędami wielkości. W jednym kroku będziemy zamieniać na postać po trzy cyfry jednocześnie. W tym celu zdefiniujemy następujące zmienne:
- s - liczba setek
- d - liczba dziesiątek
- j - liczba jedności
- n - liczba nastek
- g - rząd wielkości
- k - forma gramatyczna
zdefiniujemy sobie następujące tablice:
jednosci[0..9] o wartościach odpowiednio '', ' jeden', ' dwa', ' trzy', ' cztery', ' piec', ' szesc', ' siedem', ' osiem', ' dziewiec'
nascie[0..9] o wartościach '', ' jedenascie', ' dwanascie', ' trzynascie', ' czternascie', ' pietnascie', ' szesnascie', ' siedemnascie', ' osiemnascie', ' dziewietnascie'
dziesiatki[0..9] o wartościach '', ' dziesiec', ' dwadziescia', ' trzydziesci', ' czterdziesci', ' piecdziesiat', ' szescdziesiat', ' siedemdziesiat', ' osiemdziesiat', ' dziewiecdziesiat'
setki[0..9] o wartościach '', ' sto', ' dwiescie', ' trzysta', ' czterysta', ' piecset', ' szescset', ' siedemset', ' osiemset', ' dziewiecset'
oraz dwu-wymiarową tablicę grupy [0..6, 0..2] o wartościach:
('' ,'' ,'')
(' tysiac' ,' tysiace' ,' tysiecy')
(' milion' ,' miliony' ,' milionow')
(' miliard',' miliardy',' miliardow')
(' bilion' ,' biliony' ,' bilionow')
(' biliard',' biliardy',' biliardow')
(' trylion',' tryliony',' trylionów')
która przechowywuje rzędy wielkości wraz z ich trzema formami.
Algorytm będzie przebiegał następująco:
wynik = ''
Jezeli liczba = 0 wynik = 'zero', koniec algorytmu.
Jeżeli liczba < 0 znak = 'minus', liczba = -liczba, w przeciwnym razie znak = ''
Zainicjuj początkowy rząd liczby: g = 0
dopóki liczba różna od 0
s = liczba mod 1000 div 100
d = liczba mod 100 div 10
j = liczba mod 10
jeżeli liczba dziesiątek d jest równa 1 oraz liczba jedności j jest większa od 0 to wówczas mamy do czynienia z nastkami czyli:
n = j
d = 0
j = 0
w przeciwnym razie nie ma nastek
n = 0
teraz musimy wybrać odpowiednią formę gramatyczną:
jeżeli j = 1 oraz s+d+n = 0 to k = 0, pierwsza forma gramatyczna
jeżeli j = 2 lub 3 lub 4 to k = 1, druga forma gramatyczna
w pozostałych przypadkach k = 2, trzecia forma gramatyczna
teraz jeżeli wartość grupy jest większa od zero s+d+n+j > 0 to do wyniku dopisujemy wynik translacji grupy:
wynik = setki[s] + dziesiaki[d] + nascie[n] + jednosci[j] + grupy[g,k] + wynik
g = g + 1
liczba = liczba div 1000
wynik = znak + wynik
Przykład:
liczba = 15123541
liczba jest większa od 0 zatem znak = ''
wynik = ''
g = 0
obliczamy s, d, j
s = 15123541 mod 1000 div 100 = 541 div 100 = 5
d = 15123541 mod 100 div 10 = 41 div 10 = 4
j = 15123541 mod 10 = 1
liczba dziesiątek jest równa 4 zatem n = 0
wybieramy formę, j = 1 ale s+d+n > 0 zatem wybieramy trzecią formę gramatyczną k = 2
wartość wynik = ' piecset' + ' czterdziesci' + '' + ' jeden' + '' + ''
zwiększamy rząd g = 0 + 1 = 1
przechodzimy do kolejnej grupy trzech cyfr liczba = 15123541 div 1000 = 15123
obliczamy s, d, j
s = 15123 mod 1000 div 100 = 123 div 100 = 1
d = 15123 mod 100 div 10 = 23 div 10 = 2
j = 15123 mod 10 = 3
liczba dziesiątek jest równa 2 zatem n = 0
wybieramy formę, j = 3 zatem wybieramy drugą formę gramatyczną k = 1
wartość wynik = ' sto' + ' dwadziescia' + '' + ' trzy' + ' tysiace' + ' piecset czterdziesci jeden'
zwiększamy rząd g = 1 + 1 = 2
przechodzimy do kolejnej grupy trzech cyfr liczba = 15123 div 1000 = 15
obliczamy s, d, j
s = 15 mod 1000 div 100 = 15 div 100 = 0
d = 15 mod 100 div 10 = 15 div 10 = 1
j = 15 mod 10 = 5
liczba dziesiątek jest równa 1 oraz liczba jedności jest większa od 0 zatem n = 5, d = 0, j = 0
wybieramy formę, j = 0 zatem wybieramy trzecią formę gramatyczną k = 2
wartość wynik = '' + '' + ' pietnasice' + '' + ' milionow' + ' sto dwadziescia trzy tysiace piecset czterdziesci jeden'
zwiększamy rząd g = 2 + 1 = 3
przechodzimy do kolejnej grupy trzech cyfr liczba = 15 div 1000 = 0
liczba jest rowna 0, zatem zakończyliśmy proces tłumaczenia na formę słowną, wejściowa liczba była większa od zero zatem znak = '' czyli ostateczny wynik to:
' pietnascie milionow sto dwadziescia trzy tysiace piecset czterdziesci jeden'
Przykład w JavaScript:
Implementacje
Autor | Język programowania | Komentarz | Otwórz | Pobierz | Ocena |
Lesław Pawlaczyk | C# | .cs | .cs | ***** / 1 | |
Stefan Pruszkiewicz | Delphi/Pascal | .pas | .pas | ***** / 17 | |
Krzysztof Kranc | Java | .java | .java | ***** / 11 | |
Tomasz Lubiński | JavaScript | .js | .js | ***** / 8 | |
Karol Nowacki | Php | .php | .php | ***** / 5 | |
Stefan Pruszkiewicz | Python | .py | .py | ***** / 3 | |
Marek Madejski | Python | Implementacja w Pythonie 3, z długą i krótką skalą. | .py | .py | ***** / 3 |
Poprawiony: 15 stycznia 2020 08:16