Сортировка нечетных-четных индексных строк

Задача:

Реализовать метод, на каждой итерации которого нечетные символы строки объединяются и переносятся на ее начало, а четные переносятся на конец. "источник" Исходная строка. "count" Количество итераций.

Мой код:

        public static string ShuffleChars(string s, int count)
        {
        string res = string.Empty;
        for (int i = 0; i <= count; i++)
            {
            res = $"{string.Concat(s.Where((x, i) => i % 2 == 0))}{string.Concat(s.Where((x, i) => i % 2 != 0))}";
            }
        }
        return res;

Я отсортировал строку, но я не знаю, как я могу выполнять итерации по одному и тому же значению, я пытался использовать «для», но это не работает, помогите мне, пожалуйста.

мне нужно отсортировать так:

1. "123456789"

2."135792468" первая итерация

3."159483726" вторая итерация

4."198765432" третья итерация

но если я использую цикл, в любом случае count = 2 или count = 10 он возвращает «135792468», я не знаю, почему

Кроме того, string.Concat можно использовать вместо string.Join, если вы не соединяете предметы в коллекции с чем-либо.

Rufus L 12.12.2020 00:38

@RufusL хорошо, я просто редактирую свой вопрос в этот момент

TheWhiteFlame 12.12.2020 00:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
958
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если я правильно понимаю вашу проблему, вы в значительной степени хотите делать то, что делает ваш код; перетасовать символы в нечетных позициях в начало и четных позициях в конец.

Тем не менее, вы хотите продолжать перемешивать их, сколько раз вы проходите, count. Если вы попытаетесь просто зациклить то, что у вас есть, вы продолжите использовать исходную строку, которую вы передали, s, а затем всегда будете возвращать одно и то же значение.

Самый простой способ добиться этого — объявить выходную строку, которую вы будете продолжать назначать до тех пор, пока не выйдете из цикла. Итак, что-то вроде:

public static string ShuffleChars(string s, int count)
{
    var output = s;
    for(int i = 0; i < count; i++) {
       output = string.Join("", output.Where((v, j) => j % 2 == 0)) 
       + string.Join("", output.Where((v, j) => j % 2 != 0));
    }
    return output;
}

Ключевым моментом здесь является то, что вы объявляете новое значение output и инициализируете его строковым значением, которое вы передали. Затем для каждой итерации цикла вы переназначаете значение output новому значению. Наконец, как только вы выйдете из цикла, вы вернете окончательное значение output.

Как заявляли другие, есть и другие способы улучшить линию назначения. Лично я, вероятно, предпочитаю использовать интерполяцию строк:

output = $"{output.Where((v, j) => j % 2 == 0)}{output.Where((v, j) => j % 2 != 0)};"

Проблемы с вашим кодом:

  1. Вы return изнутри цикла. Это предотвращает завершение любой итерации, кроме первой.
  2. Вы используете <= вместо < в своем цикле. Поскольку мы начинаем с 0, это будет повторяться count + 1 раз.
  3. Вы используете то же имя переменной i для счетчика циклов, что и в предложении Where, что недопустимо, поскольку они находятся в одной области.

Чтобы решить эти проблемы (и использовать string.Concat вместо string.Join):

public static string ShuffleChars(string s, int count)
{
    for (int i = 0; i < count; i++)
    {
        s = string.Concat(s.Where((item, index) => index % 2 == 0)) +
            string.Concat(s.Where((item, index) => index % 2 != 0));
    }

    return s;
}

Проверка вывода:

static void Main()
{
    var input = "123456789";

    Console.WriteLine($"Starting input   = {input}");
    Console.WriteLine($"One iteration    = {ShuffleChars(input, 1)}");
    Console.WriteLine($"Two iterations   = {ShuffleChars(input, 2)}");
    Console.WriteLine($"Three iterations = {ShuffleChars(input, 3)}");

    GetKeyFromUser("\nDone! Press any key to exit...");
}

Выход

У меня такая же задача, но что, если value равно int.MaxValue, как мы можем оптимизировать этот код для скорости и производительности? Я тоже задавала вопрос ссылка

Linascts 17.09.2021 18:05

Вы можете преобразовать string в IEnumerable<char>, а затем применить те же преобразования LINQ count количество раз. Наконец, материализуйте IEnumerable<char> в char[] с помощью оператора ToArray, а затем преобразуйте массив обратно в string.

public static string ShuffleChars(string s, int count)
{
    IEnumerable<char> chars = s;
    foreach (var _ in Enumerable.Range(0, count))
    {
        chars = chars
            .Select((c, i) => (c, i))
            .OrderBy(e => e.i % 2)
            .Select(e => e.c);
    }
    return new String(chars.ToArray());
}

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