Вопрос знатокам Delphi и PHP

Discussion in 'PHP' started by Joker-jar, 7 Apr 2007.

  1. Joker-jar

    Joker-jar Elder - Старейшина

    Joined:
    11 Mar 2007
    Messages:
    581
    Likes Received:
    205
    Reputations:
    37
    Есть алгоритм на делфи:
    Code:
    N1: array[0..9] of string = ('ноль',
       'один',
       'два',
       'три',
       'четыре',
       'пять',
       'шесть',
       'семь',
       'восемь',
       'девять');
    
    N1000: array[1..9] of string = ('одна',
       'две',
       'три',
       'четыре',
       'пять',
       'шесть',
       'семь',
       'восемь',
       'девять');
    
    N11: array[0..9] of string = ('десять',
       'одиннадцать',
       'двенадцать',
       'тринадцать',
       'четырнадцать',
       'пятнадцать',
       'шестнадцать',
       'семнадцать',
       'восемнадцать',
       'девятнадцать');
    
    N2: array[1..9] of string = ('десять',
       'двадцать',
       'тридцать',
       'сорок',
       'пятьдесят',
       'шестьдесят',
       'семьдесят',
       'восемьдесят',
       'девяносто');
    
    N3: array[1..9] of string = ('сто',
       'двести',
       'триста',
       'четыреста',
       'пятьсот',
       'шестьсот',
       'семьсот',
       'восемьсот',
       'девятьсот');
    
    NThousand: array[1..3] of string = ('тысяча ',
       'тысячи ',
       'тысяч ');
    
    NMillion: array[1..3] of string = ('миллион ',
    'миллиона ',
    'миллионов ');
    
    function IntToStroka(n: Integer): AnsiString;
    var
    i, j, dec, j0: Integer;
    s: string;
    degt, degm: boolean;
    buf: string;
    begin
    degt := false;
    degm := false;
    s := IntToStr(n);
    Result := '';
    for i := length(s) downto 1 do
    begin
       dec := (length(s) - i + 1); // получим разряд
       j := StrToInt(s[i]); // получим цифру
       if j = 0 then
         j0 := 0;
       if (not (j in [1..9])) and (dec <> 1) then
         Continue;
       if Dec in [1, 4, 7, 10] then
       try
         if StrToInt(s[i - 1]) = 1 then
         begin
           j0 := j;
           Continue;
         end; // подготовка к 10..19 тысяч/миллионов
       except
       end;
       if Dec in [2, 5, 8, 11] then
         if j = 1 then
         begin
           case dec of
             2: Result := N11[j0] + ' '; // если 10..19 тысяч/миллионов
             5:
               begin
                 Result := N11[j0] + ' ' + NThousand[3] + Result;
                 degt := true;
               end;
             8:
               begin
                 Result := N11[j0] + ' ' + NMillion[3] + Result;
                 degm := true;
               end;
           end;
           Continue;
         end;
       if DEC in [4..6] then
       begin
         if (j <> 0) and (not degt) then
         begin
           if dec = 4 then
             case j of
               1: buf := NThousand[1];
               2..4: buf := NThousand[2];
                 // прибавим слово тысяча если ещё не добавляли
               5..9: buf := NThousand[3];
             end
           else
             buf := NThousand[3];
           degt := true;
         end;
       end;
       if DEC in [7..9] then
       begin
         if (j <> 0) and (not degm) then
         begin
           if dec = 7 then
             case j of
               1: buf := NMillion[1];
               2..4: buf := NMillion[2];
                 // прибавим слово миллион если ещё не добавляли
               5..9: buf := NMillion[3];
             end
           else
             buf := NMillion[3];
           degm := true;
         end;
       end;
       Result := buf + Result;
       while dec > 3 do
         dec := dec - 3;
     
       case Dec of
         1: if j <> 0 then
             if degt and (not degm) then
               Result := N1000[j] + ' ' + Result
             else
               Result := N1[j] + ' ' + Result; // 3 три
         2: Result := N2[j] + ' ' + Result; // 23 двадцать три
         3: Result := N3[j] + ' ' + Result; // 123 сто двадцать три
       end;
       Buf := '';
       j0 := j;
    end;
    end;
    , нужно реализовать его на PHP. Моих мозгов хватило только на это:
    PHP:
    $N1 = Array("ноль","один","два","три","четыре","пять","шесть","семь","восемь","девять");

    $N1000 = Array("одна","две","три","четыре","пять","шесть","семь","восемь","девять");

    $N11 = Array("десять","одиннадцать","двенадцать","тринадцать","четырнадцать","пятнадцать","шестнадцать","семнадцать","восемнадцать","девятнадцать");

    $N2 = Array("десять","двадцать","тридцать","сорок","пятьдесят","шестьдесят","семьдесят","восемьдесят","девяносто");

    $N3 = Array("сто","двести","триста","четыреста","пятьсот","шестьсот","семьсот","восемьсот","девятьсот");

    $NThousand = Array("тысяча ","тысячи ","тысяч ");

    $NMillion = Array("миллион ","миллиона ","миллионов ");

    function 
    IntToStroka($n)
    {
      
    $degt false;
      
    $degm false;
      
    $s strval($n);
      
    $res "";
      for (
    $i strlen($s); $i >= 1$i--)
        {
        
    $dec = (strlen($s) - $i 1);
        
    $j intval($s[$i]);
        if (
    $j == 0)
          
    $j0 0;
        if (!
    in_array($j,range(1,9)) && ($dec != 1))
          continue;
        if (
    in_array($dec,array(1,4,7,10)))
          if (
    intval($s[$i 1]) == 1)
            {
            
    $j0 $j;
            continue;
            }

        if (
    in_array($dec,array(2,5,8,11)))
          if (
    $j == 1)
            {
            switch(
    $dec)
              {
              case 
    2$res $N11[$j0]." "; break;
              case 
    5$res $N11[$j0]." ".$NThousand[3].$res$degt true; break;
              case 
    8$res $N11[$j0]." ".$NMillion[3].$res$degm true; break;
              }
            continue;
            }

        if (
    in_array($dec,range(4,6)))
          {
          if (
    $j != && !$degt)
            {
            if (
    $dec == 4)
              switch(
    $j)
                {
                case 
    1$buf $NThousand[1]; break;
                case 
    2:
                case 
    3:
                case 
    4$buf $NThousand[2]; break;
                case 
    5:
                case 
    6:
                case 
    7:
                case 
    8:
                case 
    9$buf $NThousand[3]; break;
                default: 
    $buf $NThousand[3]; $degt true;
                }
            }
          }

        if (
    in_array($dec,range(7,9)))
          {
          if (
    $j != && !$degm)
            {
            if (
    $dec == 7)
              switch(
    $j)
                {
                case 
    1$buf $NMillion[1]; break;
                case 
    2:
                case 
    3:
                case 
    4$buf $NMillion[2]; break;
                case 
    5:
                case 
    6:
                case 
    7:
                case 
    8:
                case 
    9$buf $NMillion[3]; break;
                default: 
    $buf $NMillion[3]; $degm true;
                }
            }
          }

        
    $res $buf.$res;
        while (
    $dec 3)
          
    $dec -= 3;
        switch (
    $dec)
          {
          case 
    1: if ($j != 0) if ($degt && !$degm$res $N1000[$j]." ".$res; else $res $N1[$j]." ".$res; break;
          case 
    2$res $N2[$j]." ".$res; break;
          case 
    3$res $N3[$j]." ".$res; break;
          }
        
    $buf "";
        
    $j0 $j;
        }
      return 
    $res;
    }
    . Но не пашет. Помогите найти ошибки
     
    #1 Joker-jar, 7 Apr 2007
    Last edited by a moderator: 8 Apr 2007
  2. je0n

    je0n Elder - Старейшина

    Joined:
    14 May 2006
    Messages:
    345
    Likes Received:
    96
    Reputations:
    41
    аааааа, чувак, я не разбирался, но мне кажеться у тебя с функцией все нормально. Просто объявление своих массивов втули во внутырь функции. В пхп все что за пределами функции внутри ее не видно.



    -------Добавлено--------
    Короче смотри братец. В функции все нормально кроме одного - в делфи нумераци массивов (при этом раскладе) начиналась с 1, а в пхп с 0. Из-за этого получались косяки. Вот я тупо поменял все значения массивов на 1 меньше. И все работает. А так все осталось твоим прежним. Держи:
    PHP:

    function IntToStroka($n)
    {
        
        
    $N1 = Array("ноль","один","два","три","четыре","пять","шесть","семь","восемь","девять");

    $N1000 = Array("одна","две","три","четыре","пять","шесть","семь","восемь","девять");

    $N11 = Array("десять","одиннадцать","двенадцать","тринадцать","четырнадцать","пятнадцать","шестнадцать","семнадцать","восемнадцать","девятнадцать");

    $N2 = Array("десять","двадцать","тридцать","сорок","пятьдесят","шестьдесят","семьдесят","восемьдесят","девяносто");

    $N3 = Array("сто","двести","триста","четыреста","пятьсот","шестьсот","семьсот","восемьсот","девятьсот");

    $NThousand = Array("тысяча ","тысячи ","тысяч ");

    $NMillion = Array("миллион ","миллиона ","миллионов ");

    $degt false;
    $degm false;
    $s strval($n);
    $res "";
    $buf="";
    for(
    $i=strlen($s)-1;$i>=0;$i--)
    {
        
    $dec=strlen($s)-$i;   //получаем разряд
    //    echo $dec;
        
    $j=intval($s[$i]);
        if(
    $j==0)$j0=0;
        if (!
    in_array($j,range(1,9)) && ($dec != 1))continue;
        if (
    in_array($dec,array(1,4,7,10)))
          if (
    intval($s[$i]) == 1)
          {
            
    $j0 $j;
            continue;
          }
          
          
        if (
    in_array($dec,array(2,5,8,11)))
          if (
    $j == 1)
            {
            switch(
    $dec)
              {
              case 
    2$res $N11[$j0]." "; break;
              case 
    5$res $N11[$j0]." ".$NThousand[2].$res$degt true; break;
              case 
    8$res $N11[$j0]." ".$NMillion[2].$res$degm true; break;
              }
            continue;
            }

        if (
    in_array($dec,range(4,6)))
          {
          if (
    $j != && !$degt)
            {
            if (
    $dec == 4)
              switch(
    $j)
                {
                case 
    1$buf $NThousand[0]; break;
                case 
    2:
                case 
    3:
                case 
    4$buf $NThousand[1]; break;
                case 
    5:
                case 
    6:
                case 
    7:
                case 
    8:
                case 
    9$buf $NThousand[2]; break;
                default: 
    $buf $NThousand[2]; $degt true;
                }
            }
          }

        if (
    in_array($dec,range(7,9)))
          {
          if (
    $j != && !$degm)
            {
            if (
    $dec == 7)
              switch(
    $j)
                {
                case 
    1$buf $NMillion[0]; break;
                case 
    2:
                case 
    3:
                case 
    4$buf $NMillion[1]; break;
                case 
    5:
                case 
    6:
                case 
    7:
                case 
    8:
                case 
    9$buf $NMillion[2]; break;
                default: 
    $buf $NMillion[2]; $degm true;
                }
            }
          }

        
    $res $buf.$res;
        while (
    $dec 3)
          
    $dec -= 3;
        switch (
    $dec)
          {
          case 
    1: if ($j != 0) if ($degt && !$degm$res $N1000[$j]." ".$res; else $res $N1[$j]." ".$res; break;
          case 
    2$res $N2[$j-1]." ".$res; break;
          case 
    3$res $N3[$j-1]." ".$res; break;
          }
        
    $buf "";
        
    $j0 $j;
        }
      return 
    $res;
    }
     
    #2 je0n, 8 Apr 2007
    Last edited: 8 Apr 2007
  3. Joker-jar

    Joker-jar Elder - Старейшина

    Joined:
    11 Mar 2007
    Messages:
    581
    Likes Received:
    205
    Reputations:
    37
    Ага, именно об этом я в первую очередь и подумал (по части индексации). Да и на счет global не подумал. Спасибо тебе!