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


Автор: bolt13 26.12.2007, 21:15
помогите пожалуйста написать скрипт !!!!!!!!!!!!!!!!!!!



Написать скрипт, заменяющий текстовое написание числительного (в любом падаже) на цифровое написание. Ограничиться двузначными числами.

Автор: Sadok 26.12.2007, 23:01
ггг. "один" и "одна" - падеж один и тот же... (это намек)

Автор: bolt13 27.12.2007, 02:09
нет вот именно что подежи могут быть разные!!!!!!!!!!!! smile 

Автор: vadiml 27.12.2007, 22:10
вообще достаточно просто подумать

вот из моих первых опытов на перле (вызывать dig2str):
Код

#!/usr/bin/perl -w
#
#    сумма прописью
#
#    vadim    17.10.2004    v.0.1

sub d2s {
    my ( $qq, $tp, $ll ) = @_;
    if ( $qq > 0 ) {
        my (%dx, %d1x, %dx0, %dx00, %d10x);

        my $lg = 'ru';
        $dx{$lg}[0] = 'ноль';
        $dx{$lg}[1][0] = 'одна';
        $dx{$lg}[1][1] = 'одна';
        $dx{$lg}[1][2] = 'один';
        $dx{$lg}[1][3] = 'один';
        $dx{$lg}[2][0] = 'две';
        $dx{$lg}[2][1] = 'две';
        $dx{$lg}[2][2] = 'два';
        $dx{$lg}[2][3] = 'два';
        $dx{$lg}[3] = 'три';
        $dx{$lg}[4] = 'четыре';
        $dx{$lg}[5] = 'пять';
        $dx{$lg}[6] = 'шесть';
        $dx{$lg}[7] = 'семь';
        $dx{$lg}[8] = 'восемь';
        $dx{$lg}[9] = 'девять';
        $d1x{$lg}[0] = 'десять';
        $d1x{$lg}[1] = 'одиннадцать';
        $d1x{$lg}[2] = 'двенадцать';
        $d1x{$lg}[3] = 'тринадцать';
        $d1x{$lg}[4] = 'четырнадцать';
        $d1x{$lg}[5] = 'пятнадцать';
        $d1x{$lg}[6] = 'шестнадцать';
        $d1x{$lg}[7] = 'семнадцать';
        $d1x{$lg}[8] = 'восемнадцать';
        $d1x{$lg}[9] = 'девятнадцать';
        $dx0{$lg}[2] = 'двадцать';
        $dx0{$lg}[3] = 'тридцать';
        $dx0{$lg}[4] = 'сорок';
        $dx0{$lg}[5] = 'пятьдесят';
        $dx0{$lg}[6] = 'шестьдесят';
        $dx0{$lg}[7] = 'семьдесят';
        $dx0{$lg}[8] = 'восемдесят';
        $dx0{$lg}[9] = 'девяносто';
        $dx00{$lg}[1] = 'сто';
        $dx00{$lg}[2] = 'двести';
        $dx00{$lg}[3] = 'триста';
        $dx00{$lg}[4] = 'четыреста';
        $dx00{$lg}[5] = 'пятсот';
        $dx00{$lg}[6] = 'шестьсот';
        $dx00{$lg}[7] = 'семьсот';
        $dx00{$lg}[8] = 'восемьсот';
        $dx00{$lg}[9] = 'девятьсот';
        $d10x{$lg}[0][0] = 'гривна';
        $d10x{$lg}[0][1] = 'гривны';
        $d10x{$lg}[0][2] = 'гривен';
        $d10x{$lg}[1][0] = 'тысяча';
        $d10x{$lg}[1][1] = 'тысячи';
        $d10x{$lg}[1][2] = 'тысяч';
        $d10x{$lg}[2][0] = 'миллион';
        $d10x{$lg}[2][1] = 'миллиона';
        $d10x{$lg}[2][2] = 'миллионов';
        $d10x{$lg}[3][0] = 'миллиард';
        $d10x{$lg}[3][1] = 'миллиарда';
        $d10x{$lg}[3][2] = 'миллиардов';

        my $ss = '';
        if ( $qq =~ /^((\d)?(\d))?(\d)$/ ) {
            my ($s3, $s2, $s1) = ($2, $3, $4);
            if ( $s3 ) {
                # сотни
                $ss .= ' '.$dx00{$ll}[$s3];
            };
            if ( $s2 ) {
                # десятки
                if ( $s2 == 1 ) {
                    $ss .= ' '.$d1x{$ll}[$s1];
                }
                else {
                    $ss .= ' '.$dx0{$ll}[$s2];
                }
            };
            # единицы
            unless ( $s2 and $s2 == 1 ) {
                if ( $s1 == 1 or $s1 == 2 ) {
                    $ss .= ' '.$dx{$ll}[$s1][$tp];
                }
                else {
                    if ( $s1 != 0 ) {
                        $ss .= ' '.$dx{$ll}[$s1];
                    };
                };
            };
            $s2 = 0 unless $s2;

            # окончание
            if ( $s1 == 1 and $s2 != 1 ) {
                $ss .= ' '.$d10x{$ll}[$tp][0];
            }
            elsif ( $s1 >= 2 and $s1 <= 4 and $s2 != 1 ) {
                $ss .= ' '.$d10x{$ll}[$tp][1];
            }
            else {
                $ss .= ' '.$d10x{$ll}[$tp][2];
            };
        };
        return $ss;
    }
    else {
        return '';
    };
};

sub dig2str {
    my ( $dig, $ll ) = @_;

    my $str = '';

    if ( $dig =~ /^(\d+)(.(\d{1,2}))?$/ ) {
        my $sm1 = $1;
        my $sm2 = $3;
        $sm2 *= 10 if ( $sm2 =~ /^\d$/ );
        $sm2 = 0 unless $sm2;

        my $i = 0;
        while ( $sm1 > 0 ) {
            if ( $sm1 =~ /^\d+(\d{3})$/ ) {
                $str = d2s($1, $i++, $ll).$str;
                $sm1 = int($sm1/1000);
            }
            else {
                $str = d2s($sm1, $i++, $ll).$str;
                $sm1 = 0;
            };
        };
        if ( $sm1 == 0 and $i == 0 ) {
            $str = ' ноль гривен';
        };

        return $str.' '.$sm2.' копеек';
    }
    else {
        return ' ноль гривен 0 копеек' ;
    };
}

1;


при желании можно улучшить -- здесь есть куда smile

Автор: shamber 28.12.2007, 14:41
vadiml, я думаю это не понадобиться, судя по посту

Автор: WERT 27.10.2008, 15:18
Мой вариант для сумм в рублях до 20000 руб,
вызывать num2str, там мини-тест на синтаксис проверялsmile)

sub semantic
    {$ost=$_[0]; 
    $out="";
    if($ost >= 100)
        {$jkl = $ost / 100; 
        $out.=$hang[$jkl]; 
        $ost= $ost%100; 
        } 
    if($ost >= 20){ 
        $jkl = $ost / 10; 
        $out.=$des[$jkl]; 
        $ost= $ost%10; 
        }
    if($ost>0)
        {$out.=$_1_19[$ost];        
        if ($ost==1){$out.=$namerub[1];}
        elsif ($ost<5){$out.=$namerub[2];}
        else {$out.=$namerub[3];}
        }
    else {$out.=$namerub[3];}
    }

sub num2str{ 
    $L=$_[0];
    $s="";  

$_1_2[1]="одна "; 
$_1_2[2]="две "; 

$_1_19[1]="один "; 
$_1_19[2]="два "; 
$_1_19[3]="три "; 
$_1_19[4]="четыре "; 
$_1_19[5]="пять "; 
$_1_19[6]="шесть "; 
$_1_19[7]="семь "; 
$_1_19[8]="восемь "; 
$_1_19[9]="девять "; 
$_1_19[10]="десять "; 
$_1_19[11]="одиннацать "; 
$_1_19[12]="двенадцать "; 
$_1_19[13]="тринадцать "; 
$_1_19[14]="четырнадцать "; 
$_1_19[15]="пятнадцать "; 
$_1_19[16]="шестнадцать "; 
$_1_19[17]="семнадцать "; 
$_1_19[18]="восемнадцать "; 
$_1_19[19]="девятнадцать "; 

$des[2]="двадцать "; 
$des[3]="тридцать "; 
$des[4]="сорок "; 
$des[5]="пятьдесят "; 
$des[6]="шестьдесят "; 
$des[7]="семьдесят "; 
$des[8]="восемдесят "; 
$des[9]="девяносто "; 

$hang[1]="сто "; 
$hang[2]="двести "; 
$hang[3]="триста "; 
$hang[4]="четыреста "; 
$hang[5]="пятьсот "; 
$hang[6]="шестьсот "; 
$hang[7]="семьсот "; 
$hang[8]="восемьсот "; 
$hang[9]="девятьсот "; 

$namerub[1]="рубль "; 
$namerub[2]="рубля "; 
$namerub[3]="рублей "; 

$nametho[1]="тысяча "; 
$nametho[2]="тысячи "; 
$nametho[3]="тысяч "; 


    if($L >=20000){return "Сумму не удалось рассчитать, она слишком большая"}
    if($L >= 1000)
        {$ost=$L%1000;
        $L=$L/1000;
        if ($L<3){$s.=$_1_2[$L].$nametho[$L];}
        elsif ($L<5){$s.=$_1_19[$L].$nametho[2];}
        else {$s.=$_1_19[$L].$nametho[3];}
        if ($ost==0){$s.="рублей ";} 
        else {$s.=semantic($ost);}
        }
    else {$s.=semantic($L);}

    return $s."00 копеек"; 
    } 

for ($i=0;$i<20;$i++)
    {$per=int(rand(9999));
    print $per."!!".num2str($per)."\n";
    }

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