Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > цифры в текст


Автор: qw1mb0 27.11.2011, 20:17
Добрый день форумчане.
Решил написать программку которая бы выводила словесный эквивалент цифрам в диапазоне от 0 до 10000.
не особо пока заморачивался с вариантом если там число 20 или 923, принял за условие что такие цифры надо записывать как 0020 и 0923. 
Пока что получилось вот такое

Код

@lol = split(//, <STDIN>);
@second = (undef, "Сто","Двести","Триста","Четыреста","Пятьсот","Шестьсот","Семьсот","Восемьсот","девятьсот");
@first1 = (undef,"Одна тысяча","Две тысячи", "Три тысячи", "Четыре тысячи", "Пять тысячь", "Шесть тысячь", "Семь тысячь", "Восемь тысячь", "Девять тысяч");
@thrid = (undef, \&lol, "Двадцать","Тридцать","Сорок","пятьдесят","Шестьдесять","Семьдесят","Восемьдесят","Девяносто");
@numb = (undef, "Один","Два","три","Четыре","пять","шесть","Семь","восемь","Девять");
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print "$thrid[$lol[2]] ";
print "$numb[$lol[3]] ";


Вроде все хорошо, но есть огромное НО:
ввожу вот такую проверку 
Код

$year = <STDIN>;
if ($year>0 && $year<10000){
код
} else {print "Error";}


Почему то программа вообще ничего не выводит.

Так же при вводе таких цифр, которые заканчиваются на 10-19
выводится (например для 1210):
Одна тысяча Двести CODE(0x9722df0)

Попробывал добавить что-то типа такого:
Код

$gz = $lol[2].$lol[3];
sub lol{
    if($gz%100>9 && $gz%100<20){

if ($gz == 10){$blea = $ten[0];}
elsif($gz == 11){$blea = $ten[1];}
elsif($gz ==12){$blea=$ten[2];}
elsif($gz==13){$blea = $ten[3];}
elsif($gz==14){$blea = $ten[4];}
elsif($gz==15){$blea = $ten[5];}
elsif($gz==16){$blea = $ten[6];}
elsif($gz==17){$blea = $ten[7];}
elsif($gz==18){$blea = $ten[8];}
elsif($gz==19){$blea = $ten[9];}
else { print "Error;"}
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print $blea;
}
}


Но результат выполнеия все тот же.
Кто увидел ошибку. Укажите пожалуйста на нее и как можно решить данную задачку. Просьба не давать готовые решения, а натолкнуть на путь истинный.

Автор: arto 27.11.2011, 20:50
\&lol -- ?

Автор: qw1mb0 27.11.2011, 21:07
ну это была ссылка на подпрограмму которая приведена в 3 врезке кода.
Я думал сначала сделать как вложенный массив
Но как обойтись без проверки последней цифры, если само число заканчивается на 10-19.

Добавлено через 7 минут и 53 секунды
Разобрался с цифра 10-19.
Код

@lol = split(//, <STDIN>);
@second = (undef, "Сто","Двести","Триста","Четыреста","Пятьсот","Шестьсот","Семьсот","Восемьсот","девятьсот");
@first1 = (undef,"Одна тысяча","Две тысячи", "Три тысячи", "Четыре тысячи", "Пять тысячь", "Шесть тысячь", "Семь тысячь", "Восемь тысячь", "Девять тысяч");
@thrid = (undef, \@ten, "Двадцать","Тридцать","Сорок","пятьдесят","Шестьдесять","Семьдесят","Восемьдесят","Девяносто");
@numb = (undef, "Один","Два","три","Четыре","пять","шесть","Семь","восемь","Девять");
@ten = ("Десять","Одинадцать","Двенадцать","Тринадцать", "Четырнадцать", "Пятнадцать","Шестнадцать","Семнадцать","Восемнадцать","Девятнадцать");
$gz = $lol[2].$lol[3];
if($gz%100>9 && $gz%100<20){
    if ($gz == 10){$blea = $ten[0];}
elsif($gz == 11){$blea = $ten[1];}
elsif($gz ==12){$blea=$ten[2];}
elsif($gz==13){$blea = $ten[3];}
elsif($gz==14){$blea = $ten[4];}
elsif($gz==15){$blea = $ten[5];}
elsif($gz==16){$blea = $ten[6];}
elsif($gz==17){$blea = $ten[7];}
elsif($gz==18){$blea = $ten[8];}
elsif($gz==19){$blea = $ten[9];}
else { print "Error;"}
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print $blea;
}else {
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print "$thrid[$lol[2]] ";
print "$numb[$lol[3]] ";
print "\n";
}

Все корректно работает. Но слишком громоздко. Подскажите как можно уменьшить эти elsif.

И почему то при добавлении проверки что цифра меньше 10000 и больше 0:
Код

$year = <STDIN>;
if ($year>0 && $year<10000){
код
} else {print "Error";}

все повисает

Автор: qw1mb0 27.11.2011, 21:31
от \&lol или как в последнем варианте \@ten можно совсем избавиться, так что в данной реализации нам совсем все равно какое там значение. можно во 2 элемент массива @thrid вставить анонимный массив и в секции с проверками условий вместо $ten[i]. Вставить $thrid[1][i]. 

Лирическое отступление smile 

Автор: qw1mb0 27.11.2011, 22:32
Как можно уменьшить блок кода с проверками:
Код

if ($gz == 10){$blea = $ten[0];}
elsif($gz==11){$blea = $ten[1];}
elsif($gz==12){$blea = $ten[2];}
elsif($gz==13){$blea = $ten[3];}
elsif($gz==14){$blea = $ten[4];}
elsif($gz==15){$blea = $ten[5];}
elsif($gz==16){$blea = $ten[6];}
elsif($gz==17){$blea = $ten[7];}
elsif($gz==18){$blea = $ten[8];}
elsif($gz==19){$blea = $ten[9];}


До какого нибудь цикла ?

Автор: qw1mb0 27.11.2011, 23:29
Переделал такой пример для аналогичной задачки с годом
Код

use warnings;
@lol = split(//, <STDIN>);
@second = (undef, "Сто","Двести","Триста","Четыреста","Пятьсот","Шестьсот","Семьсот","Восемьсот","девятьсот");
@first1 = (undef,"Одна тысяча","Две тысячи", "Три тысячи", "Четыре тысячи", "Пять тысячь", "Шесть тысячь", "Семь тысячь", "Восемь тысячь", "Девять тысяч");
@thrid = (undef, \@ten, "Двадцать","Тридцать","Сорок","пятьдесят","Шестьдесять","Семьдесят","Восемьдесят","Девяносто");
@numb = (undef, "Первый","Второй","Третий","Четвертый","Пятый","Шестой","Седьмой","восьмой","Девятый");
@ten = ("Десятый","Одинадцатый","Двенадцатый","Тринадцатый", "Четырнадцатый", "Пятнадцатый","Шестнадцатый","Семнадцатый","Восемнадцатый","Девятнадцатый");
@thrid2 = (undef,"Десятый","Двадцатый","Тридцатый","Сороковой", "Пятидесятый","Шестидисятый", "Семидесятый","Восьмидесятый","Девяностый");
@second2 = (undef, "Сотый","Двухсотый","Трехсотый","Четырехсотый","Пятисотый","Шестисотый","Семисотый","Восьмисотый","Девятисотый");
@first2 = (undef, "Тысячный","Двухтысячный","Трехтысячный","Четырехтысячный","Пятитысячный","Шеститысячный","Семитысячный","Восьмитысячный","Девятитысячный");

if ($lol[1].$lol[2].$lol[3] == 000){
    print "$first2[$lol[0]] ";
    print "год";
}else{
if ($lol[2].$lol[3] ==00){
    print "$first1[$lol[0]] ";
    print "$second2[$lol[1]] ";
    print "год";
}else{
if ($lol[3] == 0){
    print "$first1[$lol[0]] ";
    print "$second[$lol[1]] ";
    print "$thrid2[$lol[2]] ";
    print "год";
}else{
$gz = $lol[2].$lol[3];
if($gz>9 && $gz<20){
if ($gz == 10){$blea = $ten[0];}
elsif($gz==11){$blea = $ten[1];}
elsif($gz==12){$blea = $ten[2];}
elsif($gz==13){$blea = $ten[3];}
elsif($gz==14){$blea = $ten[4];}
elsif($gz==15){$blea = $ten[5];}
elsif($gz==16){$blea = $ten[6];}
elsif($gz==17){$blea = $ten[7];}
elsif($gz==18){$blea = $ten[8];}
elsif($gz==19){$blea = $ten[9];}
else { print "Error;"}
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print $blea." ";
print "год";
}else {
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print "$thrid[$lol[2]] ";
print "$numb[$lol[3]] ";
print "год";
print "\n";
}}}}


Буду рад любым замечаниям по обоим кодам

Автор: qw1mb0 28.11.2011, 00:46
Код

use warnings;
@lol = split(//, <STDIN>);
@second = (undef, "Сто","Двести","Триста","Четыреста","Пятьсот","Шестьсот","Семьсот","Восемьсот","девятьсот");
@first1 = (undef,"Одна тысяча","Две тысячи", "Три тысячи", "Четыре тысячи", "Пять тысячь", "Шесть тысячь", "Семь тысячь", "Восемь тысячь", "Девять тысяч");
@thrid = (undef, "Десятый", "Двадцать","Тридцать","Сорок","пятьдесят","Шестьдесять","Семьдесят","Восемьдесят","Девяносто");
@numb = (undef, "Первый","Второй","Третий","Четвертый","Пятый","Шестой","Седьмой","восьмой","Девятый");
@ten = (undef,"Одинадцатый","Двенадцатый","Тринадцатый", "Четырнадцатый", "Пятнадцатый","Шестнадцатый","Семнадцатый","Восемнадцатый","Девятнадцатый");
@thrid2 = (undef,"Десятый","Двадцатый","Тридцатый","Сороковой", "Пятидесятый","Шестидисятый", "Семидесятый","Восьмидесятый","Девяностый");
@second2 = (undef, "Сотый","Двухсотый","Трехсотый","Четырехсотый","Пятисотый","Шестисотый","Семисотый","Восьмисотый","Девятисотый");
@first2 = (undef, "Тысячный","Двухтысячный","Трехтысячный","Четырехтысячный","Пятитысячный","Шеститысячный","Семитысячный","Восьмитысячный","Девятитысячный");
if ($lol[1].$lol[2].$lol[3] == 000){
    print "$first2[$lol[0]] ";
    print "год";
}else{
if ($lol[2].$lol[3] ==00){
    print "$first1[$lol[0]] ";
    print "$second2[$lol[1]] ";
    print "год";
}else{
if ($lol[3] == 0){
    print "$first1[$lol[0]] ";
    print "$second[$lol[1]] ";
    print "$thrid2[$lol[2]] ";
    print "год";
}else{
$gz = $lol[2].$lol[3];
if($gz>10 && $gz<20){
    print "$first1[$lol[0]] ";
    print "$second[$lol[1]] ";
    print "$ten[$lol[3]] ";
    print "год";
}else {
print "$first1[$lol[0]] ";
print "$second[$lol[1]] ";
print "$thrid[$lol[2]] ";
print "$numb[$lol[3]] ";
print "год";
print "\n";
}}}}

Избавился от уродского блока проверок.
Я конечно извиняюсь, что я так тупо посты набиваю.... просто пишу сразу как получается что-то решить.
буду рад коментариям бывалых

Автор: qw1mb0 28.11.2011, 20:30
И конечный вариант получился таким:

Код

chomp($year = <STDIN>);
if ($year =~ s/^([1-9]{1})$/000$1/){ &lol;}
elsif ($year =~ s/^([1-9][0-9]{1})$/00$1/){ &lol;}
elsif ($year =~ s/^([1-9][0-9]{2})$/0$1/){ &lol;}
elsif ($year =~ s/^([1-9][0-9]{3})$/$1/) { &lol;}
elsif ($year =~ /^\d{5,}$/) {die "Not current data";}
else {die "Your are stupid???";}
sub lol{
@lol = split(//, $year);
@second = (undef, "Сто","Двести","Триста","Четыреста","Пятьсот","Шестьсот","Семьсот","Восемьсот","девятьсот");
@first1 = (undef,"Одна тысяча","Две тысячи", "Три тысячи", "Четыре тысячи", "Пять тысячь", "Шесть тысячь", "Семь тысячь", "Восемь тысячь", "Девять тысяч");
@thrid = (undef, "Десятый", "Двадцать","Тридцать","Сорок","пятьдесят","Шестьдесять","Семьдесят","Восемьдесят","Девяносто");
@numb = (undef, "Первый","Второй","Третий","Четвертый","Пятый","Шестой","Седьмой","восьмой","Девятый");
@ten = (undef,"Одинадцатый","Двенадцатый","Тринадцатый", "Четырнадцатый", "Пятнадцатый","Шестнадцатый","Семнадцатый","Восемнадцатый","Девятнадцатый");
@thrid2 = (undef,"Десятый","Двадцатый","Тридцатый","Сороковой", "Пятидесятый","Шестидисятый", "Семидесятый","Восьмидесятый","Девяностый");
@second2 = (undef, "Сотый","Двухсотый","Трехсотый","Четырехсотый","Пятисотый","Шестисотый","Семисотый","Восьмисотый","Девятисотый");
@first2 = (undef, "Тысячный","Двухтысячный","Трехтысячный","Четырехтысячный","Пятитысячный","Шеститысячный","Семитысячный","Восьмитысячный","Девятитысячный");
if ($lol[1].$lol[2].$lol[3] == 000){
    print "$first2[$lol[0]] год";
}else{
if ($lol[2].$lol[3] ==00){
    print "$first1[$lol[0]] $second2[$lol[1]] год";
}else{
if ($lol[3] == 0){print "$first1[$lol[0]] $second[$lol[1]] $thrid2[$lol[2]] год";
}else{
$gz = $lol[2].$lol[3];
if($gz>10 && $gz<20){
    print "$first1[$lol[0]] $second[$lol[1]] $ten[$lol[3]] год";
}else {
print "$first1[$lol[0]] $second[$lol[1]] $thrid[$lol[2]] $numb[$lol[3]] год";
}}}}}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)