Алгоритм равномерного распределения предметов по 3 колонкам - PullRequest
4 голосов
/ 07 августа 2009

Я ищу алгоритм, который будет равномерно распределять 1 на множество элементов в три столбца. Ни один столбец не может иметь более одного элемента, чем любой другой столбец. Я напечатал пример того, что я ищу ниже. Суммирование Col1, Col2 и Col3 должно равняться ItemCount.

Редактировать: Кроме того, элементы являются буквенно-цифровыми и должны быть упорядочены в столбце. Последний элемент в столбце должен быть меньше, чем первый элемент в следующем столбце.

Items         Col1,Col2,Col3
A             A
AB            A,B
ABC           A,B,C
ABCD          AB,C,D
ABCDE         AB,CD,E
ABCDEF        AB,CD,EF
ABCDEFG       ABC,DE,FG
ABCDEFGH      ABC,DEF,GH
ABCDEFGHI     ABC,DEF,GHI
ABCDEFHGIJ    ABCD,EFG,HIJ
ABCDEFHGIJK   ABCD,EFGH,IJK

Ответы [ 8 ]

11 голосов
/ 07 августа 2009

Вот, пожалуйста, на Python:

NumCols = 3
DATA = "ABCDEFGHIJK"

for ItemCount in range(1, 12):
    subdata = DATA[:ItemCount]

    Col1Count = (ItemCount + NumCols - 1) / NumCols
    Col2Count = (ItemCount + NumCols - 2) / NumCols
    Col3Count = (ItemCount + NumCols - 3) / NumCols

    Col1 = subdata[:Col1Count]
    Col2 = subdata[Col1Count:Col1Count+Col2Count]
    Col3 = subdata[Col1Count+Col2Count:]

    print "%2d   %5s  %5s  %5s" % (ItemCount, Col1, Col2, Col3)

# Prints:
#  1       A              
#  2       A      B       
#  3       A      B      C
#  4      AB      C      D
#  5      AB     CD      E
#  6      AB     CD     EF
#  7     ABC     DE     FG
#  8     ABC    DEF     GH
#  9     ABC    DEF    GHI
# 10    ABCD    EFG    HIJ
# 11    ABCD   EFGH    IJK
8 голосов
/ 07 августа 2009

Этот ответ теперь устарел, потому что ОП решил просто изменить вопрос после того, как я ответил на него. Мне просто лень его удалить.

function getColumnItemCount(int items, int column) {
    return (int) (items / 3) + (((items % 3) >= (column + 1)) ? 1 : 0);
}
5 голосов
/ 11 июля 2012

Этот вопрос был самым близким к моему, который я нашел, поэтому я опубликую решение, которое придумал. В JavaScript:

var items = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
var columns = [[], [], []]
for (var i=0; i<items.length; i++) {
  columns[Math.floor(i * columns.length / items.length)].push(items[i])
}
console.log(columns)
4 голосов
/ 07 августа 2009

просто чтобы дать вам подсказку (это довольно легко, так что разберитесь сами)

разделите ItemCount на 3, округляя вниз. Это то, что есть хотя бы в каждом столбце.

Теперь вы делаете ItemCount% 3 (по модулю), который равен 1 или 2 (потому что иначе он будет делиться на 3, верно), и вы распределяете это.

3 голосов
/ 10 октября 2011

Мне нужна версия C #, так что вот что я придумал (алгоритм взят из ответа Ричи):

// Start with 11 values
var data = "ABCDEFGHIJK";

// Split in 3 columns
var columnCount = 3;

// Find out how many values to display in each column
var columnCounts = new int[columnCount];
for (int i = 0; i < columnCount; i++)
    columnCounts[i] = (data.Count() + columnCount - (i + 1)) / columnCount;

// Allocate each value to the appropriate column
int iData = 0;
for (int i = 0; i < columnCount; i++)
for (int j = 0; j < columnCounts[i]; j++)
    Console.WriteLine("{0} -> Column {1}", data[iData++], i + 1);

// PRINTS:
//    A -> Column 1
//    B -> Column 1
//    C -> Column 1
//    D -> Column 1
//    E -> Column 2
//    F -> Column 2
//    G -> Column 2
//    H -> Column 2
//    I -> Column 3
//    J -> Column 3
//    K -> Column 3
2 голосов
/ 07 августа 2009

Это довольно просто

Если у вас есть N элементы, индексированные от 0 до N-1 и столбцы, индексированные от 0 до 2, i -й элемент будет помещен в столбец i mod 3 (где mod является оператором по модулю, % в C, C ++ и некоторых других языках)

1 голос
/ 07 августа 2009

Вы просто хотите, чтобы количество элементов в каждом столбце? Если у вас есть n предметов, то количество будет:

round(n/3), round(n/3), n-2*round(n/3)

где "округление" округляется до ближайшего целого числа (например, round (x) = (int) (x + 0.5))

Если вы действительно хотите поместить элементы туда, попробуйте что-то вроде этого псевдокода в стиле Python:

def columnize(items):
  i=0
  answer=[ [], [], [] ]
  for it in items:
    answer[i%3] += it
    i += 1
  return answer
0 голосов
/ 12 января 2010

Вот версия PHP, которую я взломал вместе для всех хаков PHP, таких как я (да, вина от ассоциации!)

function column_item_count($items, $column, $maxcolumns) {
    return round($items / $maxcolumns) + (($items % $maxcolumns) >= $column ? 1 : 0);
}

И ты можешь называть это так ...

$cnt = sizeof($an_array_of_data);
$col1_cnt = column_item_count($cnt,1,3);
$col2_cnt = column_item_count($cnt,2,3);
$col3_cnt = column_item_count($cnt,3,3);

Кредит на это должен идти @Bombe, который предоставил это на Java (?) Выше.

NB: Эта функция ожидает, что вы передадите порядковый номер столбца, то есть первый столбец = 1, второй столбец = 2 и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...