Ver Mensaje Individual
  #36 (permalink)  
Antiguo 10/07/2010, 15:02
Avatar de pateketrueke
pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: [Desafío PHP] Función reduce()

De_la_Cuesta_13
Código PHP:
Ver original
  1. function reduce($str){
  2.  
  3.     $str = strtolower($str);
  4.     $abc = "abcdefghijklmnopqrstuvwxyz";
  5.  
  6.     $a = str_split($abc);
  7.     $s = str_split($str);
  8.     $l_str = strlen($str);
  9.     $ult_str = $l_str - 1;
  10.     $ult_abc = strlen($abc) - 1;
  11.     $salida = "";
  12.     $m = 0;
  13.     $t = 0;
  14.  
  15.     for($i=0;$i<$l_str;$i++){
  16.  
  17.         if($m==1)
  18.             $i--;
  19.  
  20.         /*
  21.             $j me indica en que posición del abecedario ($abc) se encuentra el caracter actual ($i), así:
  22.             1. Si el caracter que sigue en $abc ($j+1) es igual al que sigue en $str ($i+1), se busca reducir en orden.
  23.             2. Si el caracter anterior en $abc ($j-1) es igual al que sigue en $str ($i+1), se busca reducir en reversa.
  24.         */
  25.         $j = strpos($abc, $str{$i});
  26.  
  27.         //busco en orden
  28.         if($i<$ult_str && $j<$ult_abc && $abc{$j+1}==$str{$i+1}){
  29.             if($m==1)
  30.                 $m=0;
  31.             else
  32.                 $salida .= $str{$i};
  33.             $j++;
  34.             $k = $i;
  35.             $i++;
  36.             //busco hasta que posición $str es igual a $abc, en orden
  37.             for($p=$i;$p<$l_str;$p++){
  38.                 if($j<=$ult_abc && $a[$j]==$s[$p]){
  39.                     $j++;
  40.                     continue;
  41.                 }
  42.                 else
  43.                     break;
  44.             }
  45.  
  46.             $p--;
  47.             $i = $p;
  48.             // se debe reducir porque hay 3 o más caracteres en orden
  49.             if(($i-$k)>=2)
  50.                 $salida .= "-".$str{$i};
  51.             else
  52.                 $salida .= $str{$i};
  53.             /*
  54.                 reviso si después del último caracter en order se debe reducir en reversa.
  55.                 $t = 1, sí
  56.                 NOTA: Si $t = 1, no se agrega el caracter a la salida en la posición $i, puesto
  57.                 que ya se ha agregado en orden.
  58.             */
  59.             $t=1;
  60.         }
  61.  
  62.         if($t==1)
  63.             $j = strpos($abc, $str{$i});
  64.  
  65.         //busco en reversa
  66.         if($i<$ult_str && $j>0 && $a{$j-1}==$str{$i+1}){
  67.             if($t!=1)
  68.                 $salida .= $str{$i};
  69.             $j--;
  70.             $k = $i;
  71.             $i++;
  72.             //busco hasta que posición $str es igual a $abc, en reversa
  73.             for($p=$i;$p<$l_str;$p++){
  74.                 if($j>=0 && $a[$j]==$s[$p]){
  75.                     $j--;
  76.                     continue;
  77.                 }
  78.                 else
  79.                     break;
  80.             }
  81.  
  82.             $p--;
  83.             $i = $p;
  84.             // se debe reducir porque hay 3 o más caracteres en reversa
  85.             if(($i-$k)>=2)
  86.                 $salida .= "-".$str{$i};
  87.             else
  88.                 $salida .= $str{$i};
  89.             /*
  90.                 reviso si después del último caracter en reversa se debe reducir en orden.
  91.                 $m = 1, sí
  92.                 NOTA: Si $m = 1, no se agrega el siguiente caracter en la posición $i, puesto
  93.                 que ya se ha agregado en reversa.
  94.             */
  95.             $j = strpos($abc, $str{$i});
  96.             if($i<$ult_str && $abc{$j+1}==$str{$i+1})
  97.                 $m=1;
  98.         }
  99.  
  100.         else{
  101.             if($t!=1)
  102.                 $salida .= $str{$i};
  103.         }
  104.         $t=0;
  105.     }
  106.  
  107.     return $salida;
  108. }

Esta es la viva imagen de que un código largo no necesariamente es lento, sino todo lo contrario.

El código ganador en velocidad bajo las pruebas actuales, el mas rápido, si... sin duda. Que al igual que otros scripts usa cadenas, arreglos auxiliares, y casi imposible de creer mas de un solo bucle.

Excelente.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.