Friday, February 5, 2010

Numbers To Words Multi-Language On PHP

It's probably lots of them when u seacrh it. But it has some simplicity on it to add new knowledge about the spelling word of some x digits number.
To build this algorithm, it's important to recognizing the pattern of spelling words for some numbers.

212           =>   two hundred twelve
345867     =>   three hundred forty five thousand eight hundred sixty seven

By those numbers and the translation in words, It could conclude that : 
  • there is some exceptions in the pattern
    ex :    10 => ten            not    onety
             12 => twelve       not    ten two
             20 => twenty       not    twoty
    by this conclution the dictionary (knowledge) to build have to give the knowledgement about those exceptions
  • there id repetition pattern in word "hundred" before and after "thousand". For that reason, it could simplify to devide the algorithm that translate 3 digits numbers from the global algorithm that translate x digits numbers.
My implementation is write down below :



<?
//==================================================================================
// File name   : numbers2words.php
// Begin       : 2010-02-03
// Last Update : 2010-02-03
// Author      : Farid Jauhari - faridjauhari@wordpress.com,jauharifarid@blogspot.com
// Version     : 1.0
//  ---------------------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify it
//
// Description : This is a PHP class for spelling number into words. It adaptable
//    in english and indonesian (bahasa) by changging the dictionary 
//    variable. This file was suited to CI helper environtment.
// 
//=================================================================================
 class numbers2words{
 /*
 * var dictionary 
 */
 var $dictionary;
 
 /*
 * the constructor
 * action : load the dictionary file, "dictionary/id.php" by default.
 */
 function numbers2words($src="dictionary/id.php"){
    require_once("$src");
    dictionary = $dictionary;
 }

 /*
 * method spell3digit
 * input : - 3 digit number
 * action : - build words from the input numbers
 */
 function spell3digit($number3digit=""){
  $number3digit=trim($number3digit);
  $number3digit/=1;
  $digits = strlen($number3digit);
  if($digits> 3) return "digit angka yang anda masukkan lebih dari 3";
  else if($digits==1) return $this->dictionary[1][$number3digit];
  else if($this->dictionary[$digits]['except'][$number3digit]) 
   return ($number3digit/2!=0?$this->dictionary[$digits]['except'][$number3digit]:"");
  else if($this->dictionary[$digits]['except'][substr($number3digit,0,1)]) 
   return $this->dictionary[$digits]['except'][substr($number3digit,0,1)]." ".
     (substr($number3digit,1)/2!=0?
      $this->spell3digit(substr($number3digit,1)):"");
  else return $this->dictionary[1][substr($number3digit,0,1)].
     $this->dictionary[$digits]["default"]." ".
     (substr($number3digit,1)/2!=0?
     $this->spell3digit(substr($number3digit,1)):"");
 }
 
 /*
 * method spell3digit
 * input : - x digit numbers ( x is depend on the dictionary)
 *     - a sign to descibe fractions 
 * action : - build words from the input numbers
 */   
 function spell($number="",$delim=""){
  if(!$delim)$delim=".";
  $number = trim($number);
  $word1="";$word2="";
  $number1="";$number2="";
  
  if($number=="")
   return "kosong";
  else {
   $delim_pos = strpos($number,$delim);
   $number1 = $number;
   if($delim_pos){
    $number1 = substr($number,0,$delim_pos);
    $number2 = substr($number,$delim_pos+1);
   }  
   else if($delim_pos===0){
    $number2 = substr($number,$delim_pos+1);
    $number1 = "";
   } 
   
   if($number2){
    if(strlen($number2)>1){
     $tmp = str_split($number2);
     foreach($tmp as $value){
      $word2 .= $this->dictionary[1][$value]." ";
     }
    }
    else{
     $word2 = $this->dictionary[1][$number2];
    }
   }
   
   if($number1){
    if(strlen($number1)>1){
     $digits = strlen($number1);
     if($digits>$this->dictionary["max"]) return "Angka yang dimasukkan terlalu besar, belum dapat diterjemahkan";
      
     $digit_div = floor($digits/3); 
     $digit_mod = $digits % 3;
     if($digit_mod>0){
      $tmp = $digit_div*3+1;
      $tmp_num =substr($number1,0,$digit_mod);
      if($tmp_num/1)
      $word1 = $this->spell3digit($tmp_num).
            ($this->dictionary[$tmp]["default"]?$this->dictionary[$tmp]["default"]." ":"");
     }
     $digit_div--;
     $i=0;
     while($digit_div>=0){
      $tmp = $digit_div*3+1;
      $tmp_num =substr($number1,$i*3+$digit_mod,3);
      if($tmp_num/1)
      $word1 .=  $this->spell3digit($tmp_num)." ".
        ($this->dictionary[$tmp]["default"]?$this->dictionary[$tmp]["default"]." ":"");
      $i++;
      $digit_div--;
     }
    }
    else{
     $word1 = $this->dictionary[1][$number2];
    }
   }
   
   $word = $word1;
   if($word2)
    $word = ($word1?$word1:$this->dictionary[1][0]." ").$this->dictionary["delim"]." ".$word2;
   return $word;
  }
 }
}
?>

the dictionary files :
<?
/*** filename : en.php ***/
$dictionary  =  array( 
    //max is the max of initialize digit number in this dictionary +2
    'max'  => 12,
    'delim' => 'point', 
    1 => array(
       0 => "zero",
       1 => "one",
       2 => "two",
       3 => "three",
       4 => "four",
       5 => "five",
       6 => "six",
       7 => "seven",
       8 => "eight",
       9 => "nine",
       "default" => ""
      ),
    2 => array(
       "default" => "ty", 
       "except" =>array(
            2  => "twenty",
            3  => "thirty",
            4  => "forty",
            5  => "fifty",
            8  => "eighty",
            10 => "ten",
            11 => "eleven",
            12 => "twelve",
            13 => "thirteen",
            14 => "fourteen",
            15 => "fifteen",
            16 => "sixteen",
            17 => "seventeen",
            18 => "eighteen",
            19 => "nineteen"
           )
       ),
    3 => array( 
       "default" => " hundred"
       ),
    4 => array(
       "default" => " thousand"
       ),
    7 => array(
       "default" => " million"
       ),
    10 => array(
       "default" => " billion"
       )
   );
?>

<?
/*** filename : id.php ***/
$dictionary  =  array( 
    'max'  => 12,
    'delim' => 'koma', 
    1 => array(
       0 => "nol",
       1 => "satu",
       2 => "dua",
       3 => "tiga",
       4 => "empat",
       5 => "lima",
       6 => "enam",
       7 => "tujuh",
       8 => "delapan",
       9 => "sembilan",
       "default" => ""
      ),
    2 => array(
       "default" => " puluh", 
       "except" =>array(
            10 => "sepuluh",
            11 => "sebelas",
            12 => "dua belas",
            13 => "tiga belas",
            14 => "empat belas",
            15 => "lima belas",
            16 => "enam belas",
            17 => "tujuh belas",
            18 => "delapan belas",
            19 => "sembilan belas"
           )
       ),
    3 => array( 
       "default" => " ratus",
       "except" =>array(
            1 => "seratus"
           )
       ),
    4 => array(
       "default" => " ribu",
       "except" =>array(
            1 => "seribu"
           )
       ),
    7 => array(
       "default" => " juta"
       ),
    10 => array(
       "default" => " milyar"
       )
   );
?>

I hope it was worthwhile...

1 comment:

  1. tambah sip ae wong iki rek.. inggrisan maneh.. :two tumbhs:

    ReplyDelete