2012-02-15 15 views
6

Me encontré con este truth table generator site, y traté de imitarlo en PHP (me doy cuenta de que el código fuente está disponible, pero sé 0 perl).Al generar una tabla de verdad en PHP

Ahora mi pregunta es no sobre la evaluación de la expresión, pero la forma de salida de la mesa para que se muestra cada combinación de T y F para las variables

Por ejemplo, con 3 variables, se vería la tabla como por ejemplo:

y con 4 variables ..

a | b | c | d 
------------- 
T | T | T | T 
T | T | T | F 
T | T | F | T 
T | T | F | F 
T | F | T | T 
T | F | T | F 
T | F | F | T 
T | F | F | F 
F | T | T | T 
F | T | T | F 
F | T | F | T 
F | T | F | F 
F | F | T | T 
F | F | T | F 
F | F | F | T 
F | F | F | F 

¿Cuál es la lógica/patrón a Cr ¿Lo comen?

+0

Usted podría simplemente usar bucles anidados, uno para cada variable? Pero estas "tablas de verdad" en realidad no significan nada; ¿Son solo una lista de todas las combinaciones posibles de T y F? –

+0

Sí. Obtener la combinación es lo que me pisó fuerte. – sqram

Respuesta

4

¿Qué tal esta función recursiva? Devuelve una matriz de 2 dimensiones donde cada 'fila' tiene $count elementos. Puedes usar esto para generar tu tabla.

function getTruthValues($count) { 
    if (1 === $count) { 
     // true and false for the first variable 
     return array(array('T'), array('F')); 
    } 

    // get 2 copies of the output for 1 less variable 
    $trues = $falses = getTruthValues(--$count); 
    for ($i = 0, $total = count($trues); $i < $total; $i++) { 
     // the true copy gets a T added to each row 
     array_unshift($trues[$i], 'T'); 
     // and the false copy gets an F 
     array_unshift($falses[$i], 'F'); 
    } 

    // combine the T and F copies to give this variable's output 
    return array_merge($trues, $falses); 
} 

function toTable(array $rows) { 
    $return = "<table>\n"; 
    $headers = range('A', chr(64 + count($rows[0]))); 
    $return .= '<tr><th>' . implode('</th><th>', $headers) . "</th></tr>\n"; 

    foreach ($rows as $row) { 
     $return .= '<tr><td>' . implode('</td><td>', $row) . "</td></tr>\n"; 
    } 

    return $return . '</table>'; 
} 

echo toTable(getTruthValues(3)); 

EDITAR: Codepad, con una función añadida para convertir la matriz a una mesa.

+1

Se crea una orden más sensata usando array_unshift en lugar de array_push: http: //codepad.org/lMlWJfRl – cmbuckley

+0

Hola. Pasé las últimas horas (alrededor de 7) estudiando este código, ya que siempre he tenido problemas con las funciones recursivas. Aunque ahora entiendo la lógica y el proceso de cómo funciona el código, mi pregunta es, en tu cabeza, ¿cuál es el patrón que tenías en tu computadora y que querías que siguiera el código? (Lo siento si la pregunta no es muy clara) – sqram

+1

Lo vi comenzar con T y F para una variable, y luego la segunda variable tomaría 2 copias de la primera salida, una para combinar con su valor T y otra con su valor F Esto continúa para cada variable. No es terriblemente eficiente, pero funciona bien. Agregaré algunos comentarios al código. – cmbuckley

1

Usted puede hacer algo como esto:

echo "<table>"; 
for($a=0; $a<=1; $a++){ 
    for($b=0; $b<=1; $b++){ 
     for($c=0; $c<=1; $c++){ 
      for($d=0; $d<=1; $d++){ 
       echo "<tr><td>$a</td><td>$b</td><td>$c</td><td>$d</td></tr>"; 
      } 
     } 
    } 
} 
echo "</table>"; 

tal vez un poco exagerado, pero funciona ...

1

primer lugar, debe calcular el número de combinaciones, por ejemplo, si tiene 4 variables a continuación, Tendrás 16 combinaciones. Para cada variable tome su índice, llámalo i. En la columna de esa variable, tendrá (n/(2^i)) veces para alternar entre los grupos T y F, donde n es la combinación total de valores posibles de las variables.

<?php 
     $numberOfVariables = 5; 
     $totalCombinations = pow(2, $numberOfVariables); 

     for ($i = 0; $i < $numberOfVariables; $i++) 
     { 
      $subGroupCount = $totalCombinations/pow(2, $i); 
      $lettersPerGroup = $totalCombinations/$subGroupCount; 

      $toggler = true; 
      for($j=0; $j<$subGroupCount; $j++) 
      { 
       for($k=0; $k < $lettersPerGroup; $k++) 
        $array[$i][$j*$lettersPerGroup + $k] = ($toggler ? "T" : "F"); 
       $toggler = !$toggler; 
      } 
     } 

     echo("<table border='1' bgcolor='yellow'>"); 
     for ($k=0;$k<$totalCombinations;$k++) 
     { 
      echo("<tr>"); 
      for ($j=$numberOfVariables-1;$j>=0;$j--) 
        echo("<td>".$array[$j][$k]."</td>"); 
      echo("</tr>"); 
     } 
     echo("</table>"); 
?> 
+0

Puedo convertir esto a PHP. Pero estoy tratando de entender tu explicación ... es una buena pero no la estoy entendiendo del todo. Espera – sqram

+1

Ahora supongo que está funcionando de la manera que querías. ¿Puedes verificarlo? Esperando que ayude. – Juvanis

+0

No del todo. Pero cerca, ¡y un buen enfoque! – sqram

2
$nbBooleans = 5; // change to whatever you want 

// show header 

for($i = 0; $i < $nbBooleans ; $i++) 
{ 
    if ($i > 0) 
    echo " | "; 
    echo chr($i + 65); // 1 => A, 2 => B etc. 
} 

// separator line (dynamic size) 

echo "\n".str_repeat("-", ($nbBooleans - 1) * 3 + $nbBooleans)."\n"; 

// show combinations 

$nbInterations = pow(2, $nbBooleans); 

for($i = 0; $i < $nbInterations; $i++) 
{ 
    for ($iBit = 0; $iBit < $nbBooleans; $iBit++) 
    { 
    if ($iBit > 0) 
     echo " | "; 
    echo (($i & pow(2, $iBit)) != 0 ? 'Y' : 'N'); 
    } 
    echo "\n"; 
} 
+0

Estaba trabajando en algo así también, como una alternativa para mi mala respuesta :) +1 –

+1

9 combinaciones con 3 vars y dos valores posibles para cada var ??: -/ –

+0

borrando el último comentario ... calculé mal. ahora lo veo ¡Gracias! – sqram

1

hizo una pequeña función para la que:

function printTruth($vars) { 
$rows = array(); 
$max = pow(2, $vars); 

// Lines and Letters 
$arr = array(); 
for($i=97;$i<(97+$vars);$i++) { $arr[] = chr($i); } 

$rows[] = implode(' | ', $arr); 
$rows[] = str_repeat('-', $vars*3); 

// Variables 
for($i=0;$i<$max;$i++) { 
    $oneRow = ''; 
    for ($j=0;$j<$vars;$j++) { 
    if($j>0) 
      $oneRow .= " | "; 
    $oneRow .= (($i & pow(2,$j)) != 0 ? 'T' : 'F'); 
    } 
    $rows[] = strrev($oneRow); 
} 

return implode("<br>", $rows); 
} 

echo printTruth(3); 
+0

Narfs, parece que debería presionar F5 antes de publicar. Fue un poco lento :) Al menos tienes una función para esto ahora. –

+0

Cuanto más, mejor. Aunque no estoy tratando simplemente de copiar y pegar, también estoy tratando de obtener una comprensión profunda de la lógica/concepto, y mientras más código, mejor :) – sqram

1

Pruebe este código. generate ($ numberOfVariables) devuelve una matriz con la tabla de verdad. Cada elemento es una cadena que puede iterar sobre

<? 
function generate($var=3){ 
$number= pow(2,$var)-1; 

$array=array(); 
while($number>=0){ 
$str=decbin($number); 

$number--; 

while(strlen($str)<$var) 
{ 

$str="0".$str; 
} 
array_push($array,$str); 
} 

return $array; 
}?> 
<pre> 
<?print_r(array_reverse(generate(3))); 
?> 
</pre> 
+0

este es interesante – sqram

1

este enfoque puede ser feo, pero parece ser universal :)

$length = 3; 


for($i=0;$i<pow(2,$length);$i++){ 
     $bin = decbin($i); 
     _add($bin, $length); 
     _out($bin, $length); 
} 


function _out($str, $length){ 
     for ($i=0; $i<$length; $i++) 
       echo ($str[$i] == 0 ? 'F' : 'T')."\t"; 

     echo "\n"; 
} 

function _add(&$bin, $length){ 
     $add = ''; 
     if (strlen($bin) < $length){ 
       for($j=0;$j<($length - strlen($bin));$j++){ 
         $add.='0'; 
       } 
       $bin = $add.$bin; 
     } 
} 

la salida es la siguiente

F F F 
F F T 
F T F 
F T T 
T F F 
T F T 
T T F 
T T T