2009-08-03 6 views
2

Supposons que certains éléments numérotés en série d'une largeur de 1 unité doivent être affichés en rangées. Chaque rangée est m unités large. J'ai besoin d'un pseudo-code qui va sortir les lignes, pour moi, de sorte que la limite m-largeur est conservée. Ce n'est pas un problème de sac à dos, car les articles doivent rester dans l'ordre des numéros de série - les espaces vides à la fin des rangées sont bien.Pseudo-code pour l'empilage en rayon

J'ai poursuivais ma queue sur cela, en partie parce que je besoin à la fois PHP et jQuery/javascript, d'où la demande de pseudo-code ....

Répondre

3
while (!items.isEmpty()) { 
    rowRemain = m; 
    rowContents = []; 
    while (!items.isEmpty() && rowRemain > items[0].width) { 
    i = items.shift(); 
    rowRemain -= i.width 
    rowContents.push(i); 
    } 
    rows.push(rowContents); 
} 

temps de fonctionnement est Θ (nombre d'articles)

+0

Ah ah - une solution beaucoup plus propre que ma propre réponse! C'est le genre de chose que je cherchais ... merci ... – Dycey

0

Modulus est votre ami. Je ferais quelque chose comme:

$items = array(/* Your list of stuff */); 
$count = 0; 
$maxUnitsPerRow = 4; // Your "m" above 

while ($item = $items[$count]) { 
if ($count % $maxUnitsPerRow == 0) { 
    $row = new row(); 
} 
$row->addItemToRow($item); 
$count++; 
} 
+0

Lorsque les éléments peuvent avoir une largeur autre que 1, cela ne fonctionnera pas. – bdonlan

+0

Peut-être que je suis dense, mais je ne comprends pas pourquoi cela ne fonctionnerait pas pour les éléments avec une largeur autre que 1. Si les éléments sont la liste de toutes les choses qui doivent aller dans toutes les lignes, et vous créez une nouvelle ligne chaque fois que le module du nombre par rapport à la largeur de ligne est zéro, vous aurez toujours des lignes du nombre de droite. Si cela ne fonctionne pas, il y a des numéros de série qui sont ignorés dans la séquence, sauf si vous ajoutez des espaces réservés vides pour ces numéros de série ou utilisez une autre méthode d'itérer dans la liste. – Bryan

+0

Je ne vois pas où vous avez pris en compte le fait que chaque objet peut avoir une largeur différente ... – Dycey

0

Pour ce que ça vaut, je pense avoir ce que je cherchais, pour PHP - mais pas sûr s'il y a un moyen plus simple ...

<?php 
// working with just a simple array of widths... 
$items  = array(1,1,1,2,1,1,2,1); 
$row_width = 0; 
$max_width = 2; 

echo "Begin\n"; // begin first row 
foreach($items as $item=>$item_width) { 
    // can we add item_width to row without going over? 
    $row_width += $item_width; 
    if($row_width < $max_width) { 
    echo "$item_width "; 
    } else if($row_width == $max_width) { 
    echo "$item_width"; 
    echo "\nEnd\nBegin\n"; // end last row, begin new row 
    $row_width = 0; 
    } else if($row_width == 2* $max_width) { 
    echo "\nEnd\nBegin\n"; // end last row, begin new row 
    echo "$item_width"; 
    echo "\nEnd\n"; // end new row 
    $row_width = 0; 
    if($item < count($items)) echo "Begin\n"; // new row 
    } else if($row_width > $max_width) { 
    echo "\nEnd\nBegin\n"; // end last row, begin new row 
    echo "$item_width"; 
    $row_width = $item_width; 
    } 
} 
echo "\nEnd\n"; // end last row 

?> 
0

Voici un autre code php ...

function arrayMaxWidthString($items, $maxWidth) { 
    $out = array(); 
    if (empty($items)) { 
     return $out; 
    } 

    $row = $maxWidth; 
    $i = 0; 

    $item = array_shift($items); 
    $row -= strlen($item); 
    $out[0] = $item; 

    foreach ($items as $item) { 
     $l = strlen($item); 
     $tmp = ($l + 1); 
     if ($row >= $tmp) { 
      $row -= $tmp; 
      $out[$i] = (($row !== $maxWidth) ? $out[$i] . ' ' : '') . $item; 
     } elseif ($row === $maxWidth) { 
      $out[$i] = $item; 
      ++$i; 
     } else { 
      ++$i; 
      $row = $maxWidth - $l; 
      $out[$i] = $item; 
     } 
    } 
    return $out; 
} 
+0

Je l'aime, moins de tests ... – Dycey

Questions connexes