Как переместить все на одно место в массиве? C # - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь создать метод, который перемещает каждый символ между первым и последним символом в массиве на одну позицию вверх.Кроме того, первый-последний символ должен «переместиться» во второе место в массиве ([1]).короче говоря, я хочу, чтобы abcdef стал aebcdf.Вот что я придумал:

                if (myArray.Length > 3)
            {
                char savechar = myArray[myArray.Length - 2];
                for (int t = 1; t < (myArray.Length - 2); t++)
                {
                    myArray[t++] = myArray[t];
                }
                myArray[1] = savechar;
            }

Проблема здесь в том, что он просто перемещает второй символ в конец, вместо того, чтобы перемещать всех персонажей на одну позицию вверх.(Я знаю, почему это происходит, я просто не знаю, как я могу это исправить) Кто-то поможет?

Ответы [ 7 ]

0 голосов
/ 23 января 2019

Использование Array.Copy:

if (myArray.Length > 3)
{
    char savechar = myArray[myArray.Length - 2];
    Array.Copy(myArray, 1, myArray, 2, myArray.Length - 3);
    myArray[1] = savechar;
}
0 голосов
/ 24 января 2019

Что бы это ни стоило, я бы, вероятно, выбрал решение Array.Copy NPCampbell , если бы это была производственная система, но ради демонстрации (и просто небольшого удовольствия от игры в гольф) вот решение с использованием Linq:

var n = myArray.Length - 1;
var newArray = myArray.Select((_, i) => myArray[i % n > 0 ? (i > 1 ? i : n) - 1 : i]).ToArray();

Это не самый производительный вариант и определенно не очень читаемый, но он работает.

0 голосов
/ 23 января 2019

Вот универсальный алгоритм смены цикла array на shiftCount элементов и пропуска skippedElements в начале и в конце array:

var array = new char[] {'a', 'b', 'c', 'd', 'e', 'f'};

var skippedElements = 1;
var shiftCount = 1;
bool shiftLeft = true;
if (shiftLeft)
{
    // shift left
    Array.Reverse(array, skippedElements, shiftCount);
    Array.Reverse(array, skippedElements + shiftCount, array.Length - skippedElements * 2 - shiftCount);
    Array.Reverse(array, skippedElements, array.Length - skippedElements - shiftCount);

}
else
{
    // shift right
    Array.Reverse(array, skippedElements, array.Length - skippedElements * 2);
    Array.Reverse(array, skippedElements + shiftCount,  array.Length - skippedElements * 2 - shiftCount);
    Array.Reverse(array, skippedElements, shiftCount);
}

Это модификация для Алгоритм разворота для вращения массива . Работает на skippedElements > 0. не требует дополнительных переменных или памяти.

0 голосов
/ 23 января 2019

это будет работать только для строк, но работает:

    var text = "abcdef";
    var shifted = text.First() + text.Substring(text.Length - 2, 1) + text.Substring(0, text.Length - 2) + text.Last();
0 голосов
/ 23 января 2019

Вот мой дубль:

for (int i = 1; i < input.Length - 1; i++)
{
  var temp = input[i];
  input[i] = input[input.Length - 2];
  input[input.Length - 2] = temp;
}
0 голосов
/ 23 января 2019

Это дает требуемый результат. Обратите внимание, что нет никаких проверок длины, так как я использую ваш пример ввода. И никаких усилий, чтобы сделать его эффективным;)

var list = "abcdef".ToCharArray().ToList();    
var item = list.ElementAt(list.Count - 2);
list.RemoveAt(list.Count - 2);
list.Insert(1, item);
var reordered = string.Join(string.Empty, list);
0 голосов
/ 23 января 2019
  1. Начинайте с конца, а не с начала, чтобы не копировать символы, которые вы уже изменили.
  2. Я не думаю, что вы намеревались использовать "++" внутри вашего цикла. Это меняет значение t и не требуется.

Вот полученный код:

if (myArray.Length > 3)
{
    char savechar = myArray[myArray.Length - 2];
    for (int t = myArray.Length - 2; t > 1; t--)
    {
        myArray[t] = myArray[t-1];
    }
    myArray[1] = savechar;
}
...