如何在2个相同列数的网格中排列2个列表?

时间:2016-05-06 09:11:23

标签: algorithm user-interface

我有2个图标列表,需要按2个网格排列。

如何计算网格的列数,以便

    每个网格中的
  1. 都有相同数量的列。
  2. 行数无关紧要。
  3. 列不应超过最大值(例如6列)
  4. 显示器是一个宽大的桌面显示器,因此宽网格比长网格更受欢迎(参见下面的示例)
  5. 示例1

    • list1:7件
    • list2:4项
    • =>使用4列,
    • list1 2行4列(第2行仅部分填充),
    • list2 1行4列 7 and 4 items

    示例2

    • list1:100件
    • list2:5件
    • =>使用5列,
    • list1:20行乘5
    • list2:1行乘5列

    示例3(宽网格与长网格)

    • list1:2件
    • list2:8件
    • =>
    • 长网格:每个网格中有2列(不是首选)
    • 宽网格:例如每个网格中有4列(首选) preferred vs not preferred

    这是我在C#中的尝试。代码中有注释,但基本上有3个步骤。

    1. 对于每个图标列表,获取所有可能列的列表(即1到最短图标列表的长度)

    2. 在两个列表中找到最佳列(即列之间的差异最小)

    3. 因为可能有多个最佳列,所以找到最佳列

      public int GetIdealNumColumns(int s1, int s2)
      {
          const int maxCol = 6; //maximum number of columns
          if (s1 == s2) { return maxCol; }
      
          //STEP 1 -------------------------------------------------
          //get all possible columns for both lists
          int gcd = GCD(s1, s2);
          int range = Math.Min(Math.Min(s1, s2),maxCol);
          var cols1 = Enumerable.Range(1, range).ToList();
          var cols2 = Enumerable.Range(1, range).ToList();
          // -------------------------------------------------
      
          //STEP 2 -------------------------------------------------
          //go through both lists and find the best #columns -> this is N^2            
          int bestDiff = int.MaxValue;
          //there could be multiple equal column numbers between the 2 lists
          //so use 2 lists to store the results
          List<int> bestCols1 = new List<int>();
          List<int> bestCols2 = new List<int>();
          for (int i1 = 0; i1 < cols1.Count; i1++)
          {
              for (int i2 = 0; i2 < cols2.Count; i2++)
              {
      
                  //difference between the number of columns
                  int diff = Math.Abs(cols1[i1] - cols2[i2]);
      
                  //the smaller the difference the better
                  if (diff < bestDiff)
                  {
                      bestDiff = diff;
      
                      //reset the lists
                      bestCols1 = new List<int>();
                      bestCols2 = new List<int>();
      
                      bestCols1.Add(i1);
                      bestCols2.Add(i2);
                  }
                  else if (diff == bestDiff) //difference equal => store
                  {
                      bestCols1.Add(i1);
                      bestCols2.Add(i2);
                  }
              }
          }
          // -------------------------------------------------
      
          //STEP 3 -------------------------------------------------
          //now go through the best results and find the result that
          //is closest to the max-number-of-columns
          bestDiff = int.MaxValue;
          int best = 0;
          if (bestCols1.Count > 1)
          {
              for (int i = 0; i < bestCols1.Count; i++)
              {
                  //get average value
                  int avg = (cols1[bestCols1[i]] + cols2[bestCols2[i]]) / 2;
      
                  //check how close the maxCol
                  int diff = Math.Abs(avg - maxCol);
                  if (diff < bestDiff)
                  {
                      bestDiff = diff;
                      best = cols1[bestCols1[i]]; //not sure if I should take avg?
                  }
              }
          }
          // -------------------------------------------------
      
          return best == 0 ? maxCol : best;
      
      }
      

0 个答案:

没有答案