Как решить проблему "repeatSeparator" без al oop в Java? - PullRequest
14 голосов
/ 25 мая 2020

В CodingBat есть проблема под названием repeatSeparator .

Given two strings, word and a separator sep, return a big string made of count occurrences of the word, separated by the separator string.

repeatSeparator("Word", "X", 3) → "WordXWordXWord"
repeatSeparator("This", "And", 2) → "ThisAndThis"
repeatSeparator("This", "And", 1) → "This"

Я знаю, как это решить, но мое решение и большинство решений, которые я нахожу на inte rnet, используют al oop. Есть ли способ решить эту проблему без al oop?

Псевдокод моей потребности return (word+rep)*count;, который не работает, но есть ли способ достичь аналогичного результата?

I Я очень дорожу любым ответом.

Ответы [ 6 ]

10 голосов
/ 25 мая 2020

Один вкладыш с использованием Java 11:

String repeatSeparator(String word, String sep, int count) {
    return (word + sep).repeat(count-1) + word;
}

Один вкладыш с использованием Java 8:

String repeatSeparator(String word, String sep, int count) {
    return String.join(sep, Collections.nCopies(count, word));
}
5 голосов
/ 25 мая 2020

Если вы абсолютно хотите скрыть циклы в реализации, вы можете сделать что-то вроде этого:

public String repeatSeparator(String word, String separator, int count) {
    return IntStream.range(0, count)
        .mapToObj(i -> word)
        .collect(Collectors.joining(separator));
}

Приведенный выше код генерирует числа от 0 до count-1, заменяет каждое число заданным word и, наконец, объединяет их с заданным разделителем.

Обратите внимание, что здесь все еще используются циклы, они просто скрыты внутри потоков. Что еще хуже, это решение почти наверняка менее эффективно, чем наивный StringBuilder + для решения.

Изменить: (потенциально) более простая версия той же идеи:

public String repeatSeparator(String word, String separator, int count) {
    return Stream.generate(() -> word)
        .limit(count)
        .collect(Collectors.joining(separator));
}

Создание бесконечного поток слова, ограничьте его заданным числом, затем объедините их с помощью разделителя.

3 голосов
/ 25 мая 2020

Как указано в комментарии и в ответе @ ackdari, вы можете использовать рекурсию. Я предлагаю метод разделяй и властвуй :

static String repeatSeparator(String word, String separator, int n) {
    if (n == 1) {
        return word;
    } else {
        String s = repeatSeparator(word, separator, n / 2); // half the expected string
        String ret = s + separator + s; // concatenate both halves
        if (n % 2 == 1) {
            ret += separator + word; // if there's an odd number of words, add the last word.
        }
        return ret;
    }
}

Хотя временная сложность кажется O(lg n), это не так, если только операции со строками (копирование, объединение) не являются атомами c. И этот код, вероятно, будет медленнее, чем код других примеров.

3 голосов
/ 25 мая 2020

Одно решение с Collections.nCopies

String repeatSeparator(String word, String separator, int count) {
    return Collections.nCopies(count, word).stream()
            .collect(Collectors.joining(separator));;
}
3 голосов
/ 25 мая 2020

Вы можете сделать это путем комбинированного использования следующих методов / функций:

  1. Arrays :: fill
  2. String :: join

Демо:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println(repeatSeparator("Word", "X", 3));
        System.out.println(repeatSeparator("This", "And", 2));
        System.out.println(repeatSeparator("This", "And", 1));
    }

    static String repeatSeparator(String word, String separator, int n) {
        String[] arr = new String[n];
        Arrays.fill(arr, word);
        return String.join(separator, arr);
    }
}

Вывод:

WordXWordXWord
ThisAndThis
This

Если разрешено чтобы использовать Java11, вы можете использовать String: repeat следующим образом:

static String repeatSeparator(String word, String separator, int n) {
    return (word + separator).repeat(n - 1) + word;
}
2 голосов
/ 25 мая 2020

Если вы просто хотите избежать использования al oop, вы можете просто выполнить рекурсию. Поскольку это своего рода эксцесс, я просто вкратце обрисую решение.

Чтобы найти реальное решение проблемы, вам сначала нужно найти базовый вариант (ы). Проблема соединения строки с разделителем имеет два базовых случая.

  • повторить слово ноль раз
  • повторить слово один раз

Теперь, чтобы создать рекурсивное решение, вам нужно как-то уменьшить регистр повторить слово n раз до повторить слово m раз где m < n.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...