代码之家  ›  专栏  ›  技术社区  ›  Spencer Ruport

调整列大小算法

  •  1
  • Spencer Ruport  · 技术社区  · 14 年前

    我有一组宽度不同的列,我需要一个算法来重新调整它们的大小,使它们的值Y大于它们所有宽度的总和。

    我希望该算法对宽度均衡进行优先级排序。所以如果我有一个绝对巨大的值,列的最终宽度将或多或少相同。如果没有足够的空间,我希望能优先考虑较小的单元。

    有什么好主意吗?我想要一些简单的东西:

    getNewWidths(NewWidth, ColumnWidths[]) returns NewColumnWidths[]
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   Mark Ransom    14 年前

    Pseudocode:

    w = NewWidth
    n = ColumnWidths.count
    sort(ColumnWidths, ascending)
    while n > 1 and ColumnWidths[n-1] > (w/n):
        w = w - ColumnWidths[n-1]
        n = n - 1
    for i = 0 to n-1:
        ColumnWidths[i] = w / n
    

    您需要添加一些代码来重新分布W/N计算中的任何舍入值,但我认为这会做到。

        2
  •  3
  •   Jason Orendorff    14 年前

    Mark Ransom的答案给出了正确的算法,但是如果您在弄清楚那里发生了什么事情时遇到了困难,下面是Python中的一个实际实现:

    def getNewWidths(newWidth, columnWidths):
        # First, find out how many columns we can equalize
        # without shrinking any columns.
        w = newWidth
        n = len(columnWidths)
        sortedWidths = sorted(columnWidths)   # A sorted copy of the array.
        while sortedWidths[n - 1] * n > w:
            w -= sortedWidths[n - 1]
            n -= 1
    
        # We can equalize the n narrowest columns. What is their new width?
        minWidth = w // n    # integer division
        sparePixels = w % n  # integer remainder: w == minWidth*n + sparePixels
    
        # Now produce the new array of column widths.
        cw = columnWidths[:]   # Start with a copy of the array.
        for i in range(len(cw)):
            if cw[i] <= minWidth:
                cw[i] = minWidth
                if sparePixels > 0:
                    cw[i] += 1
                    sparePixels -= 1
        return cw
    
        3
  •  0
  •   akuhn    14 年前

    我将把它分解为两个步骤,第一步决定你想要多少均衡(0到1之间),第二步将它适应新的总宽度。

    例如

    def get_new_widths new_total, widths
      max = widths.max
      f = how_much_equalizing(new_total) # return value between 0.0 and 1.0
      widths = widths.collect{|w| w*(1-f)+max*f}
      sum = widths.inject(0){|a,b|a+b}
      return widths.collect{|w| w/sum*new_total}
    end
    
    def how_much_equalizing new_total
      return [1.0, (new_total / 2000.0)].min
    end