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

Gustavo72
Código PHP:
Ver original
  1. function reduce($text) {
  2.     //La función recorre la cadena comparando cada caracter con el anterior.
  3.     //Los caracteres solo se agregan al resultado final si no hay secuencia.
  4.     //Cuando una secuencia termina se agrega el caracter anterior al resultado; si la secuencia es de más de dos letras se agrega antes un guión.
  5.     $res=""; //En esta cadena construyo el resultado.
  6.     $carAnt=""; //Esta variable guardará el caracter anterior.
  7.     $codAnt=0; //Esta variable guardará el código ASCII del caracter anterior.
  8.     $secuencia=0; //Esta variable contará la cantidad de caracteres en secuencia menos 1. Su signo indicará el sentido ascendente (+) o descendente (-).
  9.     $text.=" ";
  10.     for ($a=0; $a<strlen($text); $a++) { //Recorro la cadena:
  11.         $sinSecuencia=true;
  12.         $nuevaSecuencia=0;
  13.         if (ord($text[$a])==$codAnt+1) { //Compara caracter con el anterior y detecta secuencia ascendente:
  14.             if ($secuencia<0)
  15.                 $nuevaSecuencia=1; //Se inicia secuencia ascendente en sentido contrario al actual
  16.             else {
  17.                 $secuencia++;
  18.                 $sinSecuencia=false;
  19.             }
  20.         }
  21.         elseif (ord($text[$a])==$codAnt-1) { //Compara caracter con el anterior y detecta secuencia descendente:
  22.             if ($secuencia>0)
  23.                 $nuevaSecuencia=-1; //Se inicia secuencia descendente en sentido contrario al actual
  24.             else {
  25.                 $secuencia--;
  26.                 $sinSecuencia=false;
  27.             }
  28.         }
  29.  
  30.         if ($sinSecuencia) { //No hay secuencia o se inició una en sentido opuesto:
  31.             if (abs($secuencia)==1)
  32.                 $res.=$carAnt; //Secuencia rota de solo dos letras. Agrego caracter anterior sin guión
  33.             elseif (abs($secuencia)>1)
  34.                 $res.="-$carAnt"; // Cierro secuencia de más de dos letras con guión y caracter anterior
  35.  
  36.             if (!$nuevaSecuencia) { //No se inicio nueva secuencia:
  37.                 $res.=$text[$a]; //Agrega el aactual
  38.                 $secuencia=0; //No secuencia
  39.             }
  40.             else
  41.                 $secuencia=$nuevaSecuencia; //Seteo secuencia en sentido contrario
  42.         }
  43.         $carAnt=$text[$a];
  44.         $codAnt=ord($text[$a]);
  45.     }
  46.     return trim($res);
  47. }

Otro lindo y corto script.

A diferencia de otras implementaciones, este código no hace uso de comparaciones con el siguiente carácter, o el siguiente del siguiente, etc..

Sabiendo la lógica impuesta, el uso razonable tan solo del carácter anterior de la secuencia actual es importante. Así, de una buena ves se evitan errores de undefined offset, etc..
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.