2009-08-03 1 views
2

Предположим, что у меня есть некоторые серийно пронумерованные элементы, которые имеют ширину в 1-ю единицу, которые должны отображаться в строках. Каждая строка имеет ширину м. Мне нужен некоторый псевдокод, который будет выводить строки для меня, так что ограничение m-width сохраняется. Это не проблема с рюкзаком, так как элементы должны оставаться в порядковом порядке - пустое пространство в конце строк отлично.Псевдокод для стекового хранения

Я чеканка свой хвост над этим, отчасти потому, что мне это нужно как в PHP и JQuery/JavaScript, следовательно, запрос на псевдокоде ....

ответ

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); 
} 

Хронометраж является Θ (количество позиций)

+0

Ah ha - гораздо более чистое решение, чем мой собственный ответ! Это то, что я искал ... спасибо ... – Dycey

0

Модуль - ваш друг. Я хотел бы сделать что-то вроде:

$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

Когда элементы могут иметь ширину, отличную от 1, это не сработает. – bdonlan

+0

Может быть, я плотный, но я не понимаю, почему это не сработает для элементов с шириной, отличной от 1. Если элементы - это список всех вещей, которые нужно пройти во всех строках, и вы создаете новая строка каждый раз, когда модуль отсчета против ширины строки равен нулю, у вас всегда будут строки правильного подсчета. Где это не будет работать, если есть серийные номера, которые пропущены в последовательности, если вы не добавляете пустые заполнители для этих серийных номеров или не используете какой-либо другой метод итерации по списку. – Bryan

+0

Я не вижу, где вы учли тот факт, что каждый элемент может иметь разную ширину ... – Dycey

0

Для чего это стоит, я думаю, что у меня есть то, что я искал, для PHP - но не уверен, если есть более простой способ ...

<?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

Вот альтернативный 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

Мне это нравится, меньше тестов ... – Dycey