combinaciones en un string
-
Amigos:
Me encuentro en el siguiente problema: tenemos un string de n caracteres p.ej:
ACTGTAMATGRATB...... Pero algunos de los caracteres deben ser traducidos
ej: M vale A o C y R = A C o T Estos caracteres llamemoslos "no validos" pueden aparecer en cualquier sitio de la cadena cualquier cantidad de veces
lo que debo obtener es todas las cadenas posibles con caracteres validos
en el ej anterior
ACTGTAAATGAATB......
ACTGTACATGAATB......
ACTGTAAATGCATB......
ACTGTACATGCATB......
ACTGTAAATGTATB......
ACTGTACATGTATB......
Si alguien puede ayudarme desde ya muchísimas gracias. -
La cadena solo debe contener A,C, G o T en caso de aparacer otra letra por ejemplo M esta es una combinacion de 2 letras A y G por ejemplo. en el caso de solo tener una letra "M" el resultado serian 2 cadenas una en la que se reemplace la M por la A y otra en la que se reemplace con la G.
De todos modos ya lo he resuelto, pero es muy entretenido el tratar de resolverlo.
Os doy algunas pistas
1- crear un array "diccionario" con las letras que no estan permitias y sus combinaciones.
$arrarDic=array("M"=>array("A", "G"), .........) //el ejemplo que he dado
2- Calcular la cantidad de combinaciones resultantes
recorremos el string y si encontramos es caracter entre las keys del arrar (array_key_exist($char, arrayDic). en ese caso vamos almacenando el producto del numero de letras que forman lacombinacion (en el ejemplo 2 (A y G) )
$cont=1;
for...
if( array_key...
$cont *=count($arrayDic[$char]);
3- volvemos a recorrer el string (convertido en un array con str_split).
volvemos a comparar el caracter con las claves del diccionario
Si no esta (es una letra valida )
for($i=0; $i<=$n_comb-1; $i++)
$combinacion[$i].=$char;
estamos trabajando un array con un elemento por combinacion posible y le vamos agregando caracter a caracter
en el caso contrario es bastante dificil explicar con palabras como siempre A ver el codigo
$prod_prev=1;
$cant_prev=1;
/7estos contadores estan antes de reccorrer el string
ahora calculo cantidad de veces a repetir el caracter para obtener todas las combinaciones en el ejemplo con solo 1 letra modificada la iteracion vale 1
supongamos que tenemos una primera letra que se reemplaza con tres y una segunda con dos
la primera sale una iteracion (cambia en cada combinacion) para obetenr la iteracion de la 2 letra multiplico la iteracion anterior por la cantidad de letras anteriores (3) lo que me dice que debo repetir durante 3 combinaciones la letra....Si hubiese una tercera letra la iteracion seria 3 * 2 = 6
Ej ACFAM //F=ACT M=AG
ACAAA
ACCAA
ACTAA
ACAAG
ACCAG
ACTAC
$iteracion=$prod_prev * $cant_prev; /
$iter=0;
$j=0;
for($i=0; $i<=$count-1; $i++){
if($iter>= $iteracion){
$count=0;
$j++;
}
if($j > (count($arrayDicc[$char])-1))
$j=0;
$combinacion[$i].=$arrayDicc[$char][$j];
$count++;
}
$prod_prev=$iteracion;
$cant_prev= count($arrayDicc[$char]);
}
}
print_r($combinacion);
Se entiende.
Igualmente gracias a todos -
Acá va otra solución. Quizás sea la misma idea, la verdad es que la explicación no la entendí mucho
.
Esta se basa en crear pares de arrays para pasarle a str_replace. Imaginemos que tenemos que reemplazar a b c d por dígitos del 0 al 9. Empezamos por [a, b, c, d] = [0, 0, 0, 0] y hacemos un reemplazo. Después incrementamos a: [a, b, c, d] = [1, 0, 0, 0] y hacemos otro reemplazo. Cuando llegamos a [a, b, c, d] = [9, 0, 0, 0], incrementamos a [a, b, c, d] = [0, 1, 0, 0]; y cuando tenemos que incrementar [a, b, c, d] = [9, 9, 9, 9] nos damos cuenta de que terminamos.
Ésa es la base. En este caso concreto, no hay dígitos sino letras, etc., etc.Código:array("A", "G", "T"), "R" => array("T", "C"), "N" => array("G", "T")); $keys = array_keys($sust); $conts = array(); foreach ($sust as $k => $v) $conts[$k] = 0; $terminado = false; while (!$terminado) { $search = array(); $replace = array(); foreach ($conts as $k => $v) { $search[] = $k; $replace[] = "" . $sust[$k][$v] . ""; } echo str_replace($search, $replace, $secuencia) . "\n"; for ($i=0; $i
