【问题标题】:Sort or reorder list alternately in C#在 C# 中交替排序或重新排序列表
【发布时间】:2016-01-26 12:05:55
【问题描述】:

我有一个数字 1 和 0 的列表,只有固定大小为 25。

例子:

List<int>() { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

我需要将列表重新排序或排序到:

模式 A:

List<int>() { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };

模式 B:

List<int>() { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 };

列表中“1”的最大数量始终小于 13。如果当前索引为“0”,列表将循环并搜索最近的“1”并替换为当前索引(仅从左或右开始) .

这是我生成上述两种模式的代码 sn-ps:

List SlotMapLP1 = new List() { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 , 0, 0, 0, 0, 0 };

int i = 0, j = 0, k = 0, waferCount = 0, loopCtr = 0;
for (i = 0; i < SlotMapLP1.Count; i++ )
{
    if (SlotMapLP1[i] == 1)
        waferCount++;
}

List<int> ptnOne = new List<int>(SlotMapLP1);
List<int> ptnTwo = new List<int>(SlotMapLP1);

j = ptnOne.Count - 1;
while (j >= 0 && loopCtr <= waferCount) //list will start to traverse from right to left
{
    if ((ptnOne[j] == 0 && (j + 1) % 2 > 0))
    {
        k = j - 1;
        while (k >= 0)
        {
            if (ptnOne[k] == 1 && (ptnOne[k] != ptnOne[j]))
            {
                ExtensionMethods.Swap(ptnOne, k, j); //swap the two items
                loopCtr++;
                break;
            }
            k--;
        }
    }
    else
    {
        if (j == 0 || j + 1 == ptnOne.Count) break;
        if (ptnOne[j - 1] == 0 && ptnOne[j + 1] == 1)
        {
            k = j - 1;
            while (k >= 0)
            {
                if (ptnOne[k] == 0 && (ptnOne[k] != ptnOne[j]))
                {
                    ExtensionMethods.Swap(ptnOne, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k--;
            }
        }
        else
        {
            k = j - 1;
            while (k >= 0)
            {
                if (ptnOne[k] == 1 && (ptnOne[k] != ptnOne[j]))
                {
                    ExtensionMethods.Swap(ptnOne, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k--;
            }
        }
    }
    j--;
}

loopCtr = 0; j = 0; k = 0;
while (j < ptnTwo.Count && loopCtr <= waferCount)//list will start to traverse from left to right
{
    if (ptnTwo[j] == 0 && (j + 1) % 2 > 0)
    {
        k = j + 1;
        while (k < ptnTwo.Count)
        {
            if (ptnTwo[k] == 1 && (ptnTwo[k] != ptnTwo[j]))
            {
                ExtensionMethods.Swap(ptnTwo, j, k); //swap the two items
                loopCtr++;
                break;
            }
            k++;
        }
    }
    else
    {
        if (j == 0 || j + 1 == ptnOne.Count) break;
        if (ptnTwo[j + 1] == 0 && ptnTwo[j - 1] == 1)
        {
            k = j + 1;
            while (k < ptnTwo.Count)
            {
                if (ptnTwo[k] == 0 && (ptnTwo[k] != ptnTwo[j]))
                {
                    ExtensionMethods.Swap(ptnTwo, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k++;
            }
        }
        else
        {
            k = j + 1;
            while (k < ptnTwo.Count)
            {
                if (ptnTwo[k] == 1 && (ptnTwo[k] != ptnTwo[j]))
                {
                    ExtensionMethods.Swap(ptnTwo, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k++;
            }
        }
    }
    j++;
}

但是,我确实面临一些问题。如果我使用此方法,并非所有列表输入都可以交替排序或重新排序。

有没有更好的方法或方法来执行这种类型的排序?

【问题讨论】:

  • 考虑使用这样的算法:遍历列表,如果第一个元素不是 1,则继续遍历,直到找到 1 并将其与第一个交换。然后,从第二个元素开始循环遍历列表。如果第二个元素不是 0,则继续遍历,直到找到一个零并交换它。它继续这样,你明白了。如果在某一时刻你找不到更多的,这意味着只剩下零(反之亦然),你可以停下来。
  • 如果大小实际上固定为 25 个项目,我认为更容易计算 1 的数量并根据该数量构建一个新列表。也只是为了让您知道您的 ExtensionMethods 类实际上是一个 util 类而不是真正的扩展方法,真正的扩展方法会添加到 List 交换功能...
  • 您也可以为模式 B 实现一个方法,然后简单地使用 Reverse() 将其翻转为模式 A。
  • 这个任务过于复杂了……一通数一数。另一个通过重新分配值。
  • 是的,大小是固定的,但输入可能会有所不同。输入 1 到 12 个具有不同输入模式的可能性。

标签: c# list sorting swap reorderlist


【解决方案1】:

有一个解决方案不涉及交换列表中的元素。你只需要弄清楚模式。

如果只有一个1:

1000000000000000000000000

有一个“1”后跟 24 个零。

如果有 2 个:

1010000000000000000000000

有一个“101”模式,后跟 22 个零。

看到我要说的了吗?

3 个:

1010100000000000000000000

有一个“10101”模式后跟 20 个零。

所以你只需要计算一个的数量并从那里构建你的模式。那么算法就变成了:

  1. 设 n = 列表中的个数
  2. 如果没有 1,则模式 A 和 B 都只有 25 个零。
  3. 否则构建长度为 n * 2 - 1 的交替模式。
  4. 对于模式 A,连接 25 - (n * 2 - 1) 个零和交替模式。
  5. 对于模式 B,连接交替模式和 25 - (n * 2 - 1) 个零。 (或模式 A 的反面)

【讨论】:

    【解决方案2】:

    如果大小实际上固定为 25 个项目,我认为更容易计算 1 的数量并根据该数量构建一个新列表。

    【讨论】:

      【解决方案3】:

      我已经使用模式 A 和模式 B 进行了测试,但由于需要多次检查,这会使我的代码变得更长。我创建了迄今为止我测试的新模式最适合我需要移动硬件的应用程序。只是为了分享我的想法。

      模式 C:

      List() { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 , 0, 1, 0 };

      以下是代码部分:

              List<int> SlotMapLP1 = new List<int>();
      
              for (int x = 0; x < 25; x++)
              {
                  SlotMapLP1.Add(int.Parse(waferArrangement.Substring(x, 1))); //input string contains 1 and 0; where 1 should be max 12 count only
              }
      
              int i = 0, j = 0, k = 0, waferCount = 0;
              for (i = 0; i < SlotMapLP1.Count; i++ )
                  if (SlotMapLP1[i] == 1)
                      waferCount++;
      
              List<int> ptnOne = new List<int>(SlotMapLP1);
      
              for (j = 0; j < ptnOne.Count; j++ )
              {
                  if(j == 0 || j % 2 == 0)
                  {
                      if (ptnOne[j] == 1)
                      {
                          k = j + 1;
                          while (k < ptnOne.Count())
                          {
                              if (ptnOne[k] == 0)
                              {
                                  ExtensionMethods.Swap(ptnOne, k, j); //swap position
                                  break;
                              }
                              k++;
                          }
                      }
                  }
                  else
                  {
                      if (ptnOne[j] == 0)
                      {
                          k = j + 1;
                          while (k < ptnOne.Count())
                          {
      
                              if (ptnOne[k] == 1)
                              {
                                  ExtensionMethods.Swap(ptnOne, k, j); //swap position
                                  break;
                              }
                              k++;
                          }
                      }
                  }
              }
      

      我测试了几个输入,排序/重新排序功能运行良好。

      【讨论】:

        猜你喜欢
        • 2015-09-16
        • 1970-01-01
        • 2019-09-18
        • 1970-01-01
        • 2018-02-20
        • 1970-01-01
        • 2023-02-21
        • 2019-04-08
        • 2021-03-07
        相关资源
        最近更新 更多