将项目均匀分配到3列的算法

时间:2009-08-07 11:53:03

标签: algorithm

我正在寻找一种能够将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 个答案:

答案 0 :(得分:11)

在这里,你用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

答案 1 :(得分:8)

这个答案现在已经过时了,因为OP在我回答之后决定简单地改变这个问题。我太懒了,不能删除它。

function getColumnItemCount(int items, int column) {
    return (int) (items / 3) + (((items % 3) >= (column + 1)) ? 1 : 0);
}

答案 2 :(得分:5)

这个问题是我发现的最接近我自己的问题,所以我会发布我想出的解决方案。在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)

答案 3 :(得分:4)

只是为了给你一个提示(这很容易,所以弄清楚自己)

将ItemCount除以3,向下舍入。这至少在每一栏都是如此。

现在你做了ItemCount%3(modulo),它是1或2(因为它可以被3分割,右边)并且你分发它。

答案 4 :(得分:3)

我需要一个C#版本,所以这就是我提出的(算法来自Richie的答案):

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

答案 5 :(得分:2)

这很简单

如果您有N个元素从0索引到N-1,而列从0索引到2,则i个元素将放在i mod 3列中(其中mod是模运算符,C,C ++和其他一些语言中的%

答案 6 :(得分:1)

您是否只想要每列中的项目数?如果你有n个项目,那么 计数将是:

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

其中“round”舍入到最接近的整数(例如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

答案 7 :(得分:0)

这是一个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:此函数要求您传入序数列号,即第一个col = 1,第二个col = 2等...