Сортировать или переупорядочивать список поочередно в C#

У меня есть список номеров 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 };

И мне нужно изменить порядок или отсортировать список:

Образец А:

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. Список будет зацикливаться и искать ближайший "1" и заменяться текущим индексом, если текущий индекс равен "0" (либо начинается слева или справа).

Вот мои фрагменты кода для создания обоих шаблонов выше:

List SlotMapLP1 = new List () {0, 1, 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++;
}

Тем не менее, я сталкиваюсь с некоторыми проблемами. Не весь список ввода может быть отсортирован или переупорядочен поочередно, если я использую этот метод.

Есть ли лучший способ или метод для выполнения этого типа сортировки?

3 ответа

Решение

Есть решение, которое не включает обмен элементов в списке. Вам нужно только выяснить шаблон.

Если есть только один 1:

1000000000000000000000000

Там стоит "1", за которым следуют 24 нуля.

Если есть 2 из них:

1010000000000000000000000

Есть шаблон "101", за которым следуют 22 нуля.

Видишь, куда я клоню?

Для 3-х:

1010100000000000000000000

Есть паттерн "10101", за которым следуют 20 нулей.

Таким образом, вам нужно только посчитать количество единиц и построить свой шаблон оттуда. Затем алгоритм становится:

  1. Пусть n = количество единиц в списке
  2. Если их нет, то оба шаблона A и B - это всего лишь 25 нулей.
  3. Еще строят чередующийся узор длиной n * 2 - 1.
  4. Для шаблона A объедините 25 - (n * 2 - 1) нулей и чередующийся шаблон.
  5. Для шаблона B объедините чередующийся шаблон и 25 - (n * 2 - 1) нулей. (Или обратный шаблон А)

Если размер фактически установлен на 25 пунктов, я думаю, что легче посчитать сумму 1 и построить новый список в соответствии с этой суммой.

У меня есть тест с шаблоном A и шаблоном B, но он увеличит мои коды из-за необходимости многократной проверки Я создал новый шаблон, который я тестирую до сих пор, является лучшим для моего приложения, которые требуют перемещения оборудования. Просто чтобы поделиться моей идеей.

Образец C:

Список () { 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++;
                    }
                }
            }
        }

Я проверил с несколькими входами, и функция сортировки / переупорядочения работает хорошо.

Другие вопросы по тегам