package com.konstantin ;
import java.io.BufferedReader ;
import java.io.FileInputStream ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.math.BigInteger ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.Objects ;
public class ConverterNumToWords {
private final static String PATH_FILE
= "dataName/nameUnits.txt" ; private final static int MALE_GENDER = 1 ;
private final static int FEMALE_GENDER = - 1 ;
private final static String SEPARATOR
= " " ;
private static final Map
< Integer , String
> nameTriad
= new HashMap
< Integer , String
> ( ) { { put( - 2 , "две" ) ;
put( - 1 , "одна" ) ;
put( 0 , "ноль" ) ;
put( 1 , "один" ) ;
put( 2 , "два" ) ;
put( 3 , "три" ) ;
put( 4 , "четыре" ) ;
put( 5 , "пять" ) ;
put( 6 , "шесть" ) ;
put( 7 , "семь" ) ;
put( 8 , "восемь" ) ;
put( 9 , "девять" ) ;
put( 10 , "десять" ) ;
put( 11 , "одиннадцать" ) ;
put( 12 , "двенадцать" ) ;
put( 13 , "тринадцать" ) ;
put( 14 , "четырнадцать" ) ;
put( 15 , "пятнадцать" ) ;
put( 16 , "шестнадцать" ) ;
put( 17 , "семнадцать" ) ;
put( 18 , "восемнадцать" ) ;
put( 19 , "девятнадцать" ) ;
put( 20 , "двадцать" ) ;
put( 30 , "тридцать" ) ;
put( 40 , "сорок" ) ;
put( 50 , "пятьдесят" ) ;
put( 60 , "шестьдесят" ) ;
put( 70 , "семьдесят" ) ;
put( 80 , "восемьдесят" ) ;
put( 90 , "девяносто" ) ;
put( 100 , "сто" ) ;
put( 200 , "двести" ) ;
put( 300 , "триста" ) ;
put( 400 , "четыреста" ) ;
put( 500 , "пятьсот" ) ;
put( 600 , "шестьсот" ) ;
put( 700 , "семьсот" ) ;
put( 800 , "восемьсот" ) ;
put( 900 , "девятьсот" ) ;
} } ;
private Map
< Integer , String
> nameUnits
= new HashMap
< Integer , String
> ( ) { { put( 1 , "тысяч" ) ;
} } ;
private final String [ ] [ ] endings
= { { "а" ,
"и" ,
"" } ,
{ "" ,
"а" ,
"ов" } } ;
public ConverterNumToWords( ) {
readNameUnitFromFile( ) ;
}
private void readNameUnitFromFile( ) {
while ( ( tmpLineStr = br.readLine ( ) ) != null ) {
if ( ! Objects.equals ( tmpLineStr , "" ) ) {
Units = tmpLineStr.split ( SEPARATOR) ;
nameUnits.
put ( Integer .
valueOf ( Units
[ 0 ] ) , Units
[ 1 ] ) ; }
}
}
}
int hundreds
= Character .
getNumericValue ( triad.
charAt ( 0 ) ) ; int dozens
= Character .
getNumericValue ( triad.
charAt ( 1 ) ) ; int units
= Character .
getNumericValue ( triad.
charAt ( 2 ) ) ; if ( Objects.equals ( triad, "000" ) ) return "" ;
if ( hundreds != 0 )
words += nameTriad.get ( hundreds * 100 ) + SEPARATOR;
if ( dozens == 1 && units <= 9 && units >= 0 ) //Для чисел от 10 до 19 ключи для мапа считаются отдельно
words += nameTriad.get ( dozens * 10 + units) + SEPARATOR;
else {
if ( dozens != 0 )
words += nameTriad.get ( dozens * 10 ) + SEPARATOR;
if ( units != 0 && units > 2 )
words += nameTriad.get ( units) + SEPARATOR;
else if ( units != 0 && units <= 2 )
words += nameTriad.get ( units * gender) + SEPARATOR;
}
return words;
}
/**
* Получаем номер окончания для названия из мап nameUnit, основываясь на числе n ,в массиве ending
*/
private int selectForm( int n) {
int n1 = n % 10 ;
if ( n > 10 && n < 20 ) return 2 ;
if ( n1 > 1 && n1 < 5 ) return 1 ;
if ( n1 == 1 ) return 0 ;
return 2 ;
}
if ( nameUnits.
get ( degree
) == null && degree
!= 0 ) throw new NullPointerException ( "Dont exist name " + degree + " thousands of degrees" ) ;
if ( Objects.equals ( number, "000" ) ) return "" ;
if ( degree
== 1 ) return nameUnits.
get ( degree
) + endings
[ 0 ] [ selectForm
( Integer .
parseInt ( number
) ) ] + SEPARATOR
; if ( degree
> 1 ) return nameUnits.
get ( degree
) + endings
[ 1 ] [ selectForm
( Integer .
parseInt ( number
) ) ] + SEPARATOR
; else
return "" ;
}
/**
* Конвертирует число number в запись словами
*/
String numberStr
= number.
toString ( ) ;
if ( Objects.equals ( numberStr, "0" ) ) return nameTriad.get ( 0 ) ;
if ( numberStr.charAt ( 0 ) == '-' ) {
nameNumber += "минус " ;
numberStr = numberStr.substring ( 1 ) ;
}
for ( int i = 0 ; i < numberStr.length ( ) % 3 ; i++ )
numberStr = "0" + numberStr;
for ( int i = 0 ; i < numberStr.length ( ) / 3 ; i++ ) {
int degree = numberStr.length ( ) / 3 - i - 1 ;
if ( degree == 1 )
nameNumber += convertTriad( numberStr.substring ( ( i * 3 ) , i * 3 + 3 ) , FEMALE_GENDER) +
getFormNameUnit( degree, numberStr.substring ( ( i * 3 ) , i * 3 + 3 ) ) ;
else
nameNumber += convertTriad( numberStr.substring ( ( i * 3 ) , i * 3 + 3 ) , MALE_GENDER) +
getFormNameUnit( degree, numberStr.substring ( ( i * 3 ) , i * 3 + 3 ) ) ;
}
return nameNumber.trim ( ) ;
}
}
cGFja2FnZSBjb20ua29uc3RhbnRpbjsKCgppbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CmltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwoKcHVibGljIGNsYXNzIENvbnZlcnRlck51bVRvV29yZHMgewoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBQQVRIX0ZJTEUgPSAiZGF0YU5hbWUvbmFtZVVuaXRzLnR4dCI7CiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgTUFMRV9HRU5ERVIgPSAxOwogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IEZFTUFMRV9HRU5ERVIgPSAtMTsKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBTRVBBUkFUT1IgPSAiICI7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIFN0cmluZz4gbmFtZVRyaWFkID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgU3RyaW5nPigpIHt7CiAgICAgICAgcHV0KC0yLCAi0LTQstC1Iik7CiAgICAgICAgcHV0KC0xLCAi0L7QtNC90LAiKTsKICAgICAgICBwdXQoMCwgItC90L7Qu9GMIik7CiAgICAgICAgcHV0KDEsICLQvtC00LjQvSIpOwogICAgICAgIHB1dCgyLCAi0LTQstCwIik7CiAgICAgICAgcHV0KDMsICLRgtGA0LgiKTsKICAgICAgICBwdXQoNCwgItGH0LXRgtGL0YDQtSIpOwogICAgICAgIHB1dCg1LCAi0L/Rj9GC0YwiKTsKICAgICAgICBwdXQoNiwgItGI0LXRgdGC0YwiKTsKICAgICAgICBwdXQoNywgItGB0LXQvNGMIik7CiAgICAgICAgcHV0KDgsICLQstC+0YHQtdC80YwiKTsKICAgICAgICBwdXQoOSwgItC00LXQstGP0YLRjCIpOwogICAgICAgIHB1dCgxMCwgItC00LXRgdGP0YLRjCIpOwogICAgICAgIHB1dCgxMSwgItC+0LTQuNC90L3QsNC00YbQsNGC0YwiKTsKICAgICAgICBwdXQoMTIsICLQtNCy0LXQvdCw0LTRhtCw0YLRjCIpOwogICAgICAgIHB1dCgxMywgItGC0YDQuNC90LDQtNGG0LDRgtGMIik7CiAgICAgICAgcHV0KDE0LCAi0YfQtdGC0YvRgNC90LDQtNGG0LDRgtGMIik7CiAgICAgICAgcHV0KDE1LCAi0L/Rj9GC0L3QsNC00YbQsNGC0YwiKTsKICAgICAgICBwdXQoMTYsICLRiNC10YHRgtC90LDQtNGG0LDRgtGMIik7CiAgICAgICAgcHV0KDE3LCAi0YHQtdC80L3QsNC00YbQsNGC0YwiKTsKICAgICAgICBwdXQoMTgsICLQstC+0YHQtdC80L3QsNC00YbQsNGC0YwiKTsKICAgICAgICBwdXQoMTksICLQtNC10LLRj9GC0L3QsNC00YbQsNGC0YwiKTsKICAgICAgICBwdXQoMjAsICLQtNCy0LDQtNGG0LDRgtGMIik7CiAgICAgICAgcHV0KDMwLCAi0YLRgNC40LTRhtCw0YLRjCIpOwogICAgICAgIHB1dCg0MCwgItGB0L7RgNC+0LoiKTsKICAgICAgICBwdXQoNTAsICLQv9GP0YLRjNC00LXRgdGP0YIiKTsKICAgICAgICBwdXQoNjAsICLRiNC10YHRgtGM0LTQtdGB0Y/RgiIpOwogICAgICAgIHB1dCg3MCwgItGB0LXQvNGM0LTQtdGB0Y/RgiIpOwogICAgICAgIHB1dCg4MCwgItCy0L7RgdC10LzRjNC00LXRgdGP0YIiKTsKICAgICAgICBwdXQoOTAsICLQtNC10LLRj9C90L7RgdGC0L4iKTsKICAgICAgICBwdXQoMTAwLCAi0YHRgtC+Iik7CiAgICAgICAgcHV0KDIwMCwgItC00LLQtdGB0YLQuCIpOwogICAgICAgIHB1dCgzMDAsICLRgtGA0LjRgdGC0LAiKTsKICAgICAgICBwdXQoNDAwLCAi0YfQtdGC0YvRgNC10YHRgtCwIik7CiAgICAgICAgcHV0KDUwMCwgItC/0Y/RgtGM0YHQvtGCIik7CiAgICAgICAgcHV0KDYwMCwgItGI0LXRgdGC0YzRgdC+0YIiKTsKICAgICAgICBwdXQoNzAwLCAi0YHQtdC80YzRgdC+0YIiKTsKICAgICAgICBwdXQoODAwLCAi0LLQvtGB0LXQvNGM0YHQvtGCIik7CiAgICAgICAgcHV0KDkwMCwgItC00LXQstGP0YLRjNGB0L7RgiIpOwoKICAgIH19OwoKICAgIHByaXZhdGUgTWFwPEludGVnZXIsIFN0cmluZz4gbmFtZVVuaXRzID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgU3RyaW5nPigpIHt7CiAgICAgICAgcHV0KDEsICLRgtGL0YHRj9GHIik7CiAgICB9fTsKCiAgICBwcml2YXRlIGZpbmFsIFN0cmluZ1tdW10gZW5kaW5ncyA9IHt7ItCwIiwgItC4IiwgIiJ9LCB7IiIsICLQsCIsICLQvtCyIn19OwoKCiAgICBwdWJsaWMgQ29udmVydGVyTnVtVG9Xb3JkcygpIHsKCiAgICAgICAgcmVhZE5hbWVVbml0RnJvbUZpbGUoKTsKCiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHJlYWROYW1lVW5pdEZyb21GaWxlKCkgewogICAgICAgIHRyeSAoQnVmZmVyZWRSZWFkZXIgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIoCiAgICAgICAgICAgICAgICBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlSW5wdXRTdHJlYW0oUEFUSF9GSUxFKSwgIlVURjgiKSkpIHsKICAgICAgICAgICAgU3RyaW5nIHRtcExpbmVTdHI7CiAgICAgICAgICAgIFN0cmluZyBVbml0c1tdOwogICAgICAgICAgICB3aGlsZSAoKHRtcExpbmVTdHIgPSBici5yZWFkTGluZSgpKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoIU9iamVjdHMuZXF1YWxzKHRtcExpbmVTdHIgLCAiIikpIHsKICAgICAgICAgICAgICAgICAgICBVbml0cyA9IHRtcExpbmVTdHIuc3BsaXQoU0VQQVJBVE9SKTsKICAgICAgICAgICAgICAgICAgICBuYW1lVW5pdHMucHV0KEludGVnZXIudmFsdWVPZihVbml0c1swXSksIFVuaXRzWzFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKCiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyBjb252ZXJ0VHJpYWQoU3RyaW5nIHRyaWFkLCBpbnQgZ2VuZGVyKSB7CiAgICAgICAgaW50IGh1bmRyZWRzID0gQ2hhcmFjdGVyLmdldE51bWVyaWNWYWx1ZSh0cmlhZC5jaGFyQXQoMCkpOwogICAgICAgIGludCBkb3plbnMgPSBDaGFyYWN0ZXIuZ2V0TnVtZXJpY1ZhbHVlKHRyaWFkLmNoYXJBdCgxKSk7CiAgICAgICAgaW50IHVuaXRzID0gQ2hhcmFjdGVyLmdldE51bWVyaWNWYWx1ZSh0cmlhZC5jaGFyQXQoMikpOwogICAgICAgIGlmIChPYmplY3RzLmVxdWFscyh0cmlhZCwgIjAwMCIpKSByZXR1cm4gIiI7CiAgICAgICAgU3RyaW5nIHdvcmRzID0gIiI7CiAgICAgICAgaWYgKGh1bmRyZWRzICE9IDApCiAgICAgICAgICAgIHdvcmRzICs9IG5hbWVUcmlhZC5nZXQoaHVuZHJlZHMgKiAxMDApICsgU0VQQVJBVE9SOwogICAgICAgIGlmIChkb3plbnMgPT0gMSAmJiB1bml0cyA8PSA5ICYmIHVuaXRzID49IDApICAgLy/QlNC70Y8g0YfQuNGB0LXQuyDQvtGCIDEwINC00L4gMTkg0LrQu9GO0YfQuCDQtNC70Y8g0LzQsNC/0LAg0YHRh9C40YLQsNGO0YLRgdGPINC+0YLQtNC10LvRjNC90L4KICAgICAgICAgICAgd29yZHMgKz0gbmFtZVRyaWFkLmdldChkb3plbnMgKiAxMCArIHVuaXRzKSArIFNFUEFSQVRPUjsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaWYgKGRvemVucyAhPSAwKQogICAgICAgICAgICAgICAgd29yZHMgKz0gbmFtZVRyaWFkLmdldChkb3plbnMgKiAxMCkgKyBTRVBBUkFUT1I7CiAgICAgICAgICAgIGlmICh1bml0cyAhPSAwICYmIHVuaXRzID4gMikKICAgICAgICAgICAgICAgIHdvcmRzICs9IG5hbWVUcmlhZC5nZXQodW5pdHMpICsgU0VQQVJBVE9SOwogICAgICAgICAgICBlbHNlIGlmICh1bml0cyAhPSAwICYmIHVuaXRzIDw9IDIpCiAgICAgICAgICAgICAgICB3b3JkcyArPSBuYW1lVHJpYWQuZ2V0KHVuaXRzICogZ2VuZGVyKSArIFNFUEFSQVRPUjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHdvcmRzOwogICAgfQoKICAgIC8qKgogICAgICog0J/QvtC70YPRh9Cw0LXQvCDQvdC+0LzQtdGAINC+0LrQvtC90YfQsNC90LjRjyAg0LTQu9GPINC90LDQt9Cy0LDQvdC40Y8g0LjQtyDQvNCw0L8gbmFtZVVuaXQsINC+0YHQvdC+0LLRi9Cy0LDRj9GB0Ywg0L3QsCDRh9C40YHQu9C1IG4gLNCyINC80LDRgdGB0LjQstC1IGVuZGluZwogICAgICovCiAgICBwcml2YXRlIGludCBzZWxlY3RGb3JtKGludCBuKSB7CiAgICAgICAgbiA9IE1hdGguYWJzKG4pICUgMTAwOwogICAgICAgIGludCBuMSA9IG4gJSAxMDsKICAgICAgICBpZiAobiA+IDEwICYmIG4gPCAyMCkgcmV0dXJuIDI7CiAgICAgICAgaWYgKG4xID4gMSAmJiBuMSA8IDUpIHJldHVybiAxOwogICAgICAgIGlmIChuMSA9PSAxKSByZXR1cm4gMDsKICAgICAgICByZXR1cm4gMjsKICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyBnZXRGb3JtTmFtZVVuaXQoaW50IGRlZ3JlZSwgU3RyaW5nIG51bWJlcikgewogICAgICAgIGlmIChuYW1lVW5pdHMuZ2V0KGRlZ3JlZSkgPT0gbnVsbCAmJiBkZWdyZWUgIT0gMCkgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJEb250IGV4aXN0IG5hbWUgIiArCiAgICAgICAgICAgICAgICBkZWdyZWUgKyAiIHRob3VzYW5kcyBvZiBkZWdyZWVzIik7CiAgICAgICAgaWYgKE9iamVjdHMuZXF1YWxzKG51bWJlciwgIjAwMCIpKSByZXR1cm4gIiI7CiAgICAgICAgaWYgKGRlZ3JlZSA9PSAxKSByZXR1cm4gbmFtZVVuaXRzLmdldChkZWdyZWUpICsgZW5kaW5nc1swXVtzZWxlY3RGb3JtKEludGVnZXIucGFyc2VJbnQobnVtYmVyKSldICsgU0VQQVJBVE9SOwogICAgICAgIGlmIChkZWdyZWUgPiAxKSByZXR1cm4gbmFtZVVuaXRzLmdldChkZWdyZWUpICsgZW5kaW5nc1sxXVtzZWxlY3RGb3JtKEludGVnZXIucGFyc2VJbnQobnVtYmVyKSldICsgU0VQQVJBVE9SOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgfQoKICAgIC8qKgogICAgICog0JrQvtC90LLQtdGA0YLQuNGA0YPQtdGCINGH0LjRgdC70L4gbnVtYmVyINCyINC30LDQv9C40YHRjCDRgdC70L7QstCw0LzQuAogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGNvbnZlcnROdW1iVG9Xb3JkcyhCaWdJbnRlZ2VyIG51bWJlcikgewogICAgICAgIFN0cmluZyBudW1iZXJTdHIgPSBudW1iZXIudG9TdHJpbmcoKTsKCiAgICAgICAgaWYgKE9iamVjdHMuZXF1YWxzKG51bWJlclN0ciwgIjAiKSkgcmV0dXJuIG5hbWVUcmlhZC5nZXQoMCk7CgogICAgICAgIFN0cmluZyBuYW1lTnVtYmVyID0gIiI7CgogICAgICAgIGlmIChudW1iZXJTdHIuY2hhckF0KDApID09ICctJykgewogICAgICAgICAgICBuYW1lTnVtYmVyICs9ICLQvNC40L3Rg9GBICI7CiAgICAgICAgICAgIG51bWJlclN0ciA9IG51bWJlclN0ci5zdWJzdHJpbmcoMSk7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlclN0ci5sZW5ndGgoKSAlIDM7IGkrKykKICAgICAgICAgICAgbnVtYmVyU3RyID0gIjAiICsgbnVtYmVyU3RyOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlclN0ci5sZW5ndGgoKSAvIDM7IGkrKykgewogICAgICAgICAgICBpbnQgZGVncmVlID0gbnVtYmVyU3RyLmxlbmd0aCgpIC8gMyAtIGkgLSAxOwogICAgICAgICAgICBpZiAoZGVncmVlID09IDEpCiAgICAgICAgICAgICAgICBuYW1lTnVtYmVyICs9IGNvbnZlcnRUcmlhZChudW1iZXJTdHIuc3Vic3RyaW5nKChpICogMyksIGkgKiAzICsgMyksIEZFTUFMRV9HRU5ERVIpICsKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rm9ybU5hbWVVbml0KGRlZ3JlZSwgbnVtYmVyU3RyLnN1YnN0cmluZygoaSAqIDMpLCBpICogMyArIDMpKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbmFtZU51bWJlciArPSBjb252ZXJ0VHJpYWQobnVtYmVyU3RyLnN1YnN0cmluZygoaSAqIDMpLCBpICogMyArIDMpLCBNQUxFX0dFTkRFUikgKwogICAgICAgICAgICAgICAgICAgICAgICBnZXRGb3JtTmFtZVVuaXQoZGVncmVlLCBudW1iZXJTdHIuc3Vic3RyaW5nKChpICogMyksIGkgKiAzICsgMykpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmFtZU51bWJlci50cmltKCk7CiAgICB9CgoKfQo=