Конечная последовательность
Предположим, вы хотите создать конечную последовательность символов, содержащую Y
или R
, случайным образом , просто создайте некоторый метод next()
и вызывайте его повторно:
public final class SequenceGenerator {
private final String[] elements;
private final Random rnd;
public SequenceGenerator(Collection<String> elements) {
this.elements = elements.toArray(new String[elements.size()]);
rnd = new Random();
}
public String next() {
return elements[rnd.nextInt(elements.length)];
}
public String generate(int amountOfElements) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < amountOfElements; i++) {
sb.append(next());
}
return sb.toString();
}
}
Класс берет набор возможных элементов для рисования, а его методы next
выбирают один случайным образом. Метод generate
вызывает его несколько раз и добавляет нарисованные элементы.
Простое использование:
SequenceGenerator gen = new SequenceGenerator(List.of("Y", "R"));
System.out.println(gen.generate(11));
Может печатать что-то вроде:
YYRYYRYYRYY
Бесконечный поток
Вы также можете использовать API Stream
здесь для создания бесконечного потока:
SequenceGenerator gen = new SequenceGenerator(List.of("Y", "R"));
Stream<String> sequence = Stream.generate(gen::next);
Редактировать: YY
и R
Как вы сказали, вы хотите, чтобы поток начинался и заканчивался YY
, а также имел R
в каждой третьей позиции, нам нужно немного изменить next()
. Прежде всего мы добавляем поле int amount
для отслеживания звонков. Затем next()
изменяется для учета YY
в начале и R
. Точно так же generate
должен быть изменен, чтобы учесть YY
в конце. Вариант Stream может остаться неизменным, поскольку он использует измененный next()
и не должен учитывать YY
в конце, поскольку он бесконечен.
public final class SequenceGenerator {
// ...
private int amount;
public SequenceGenerator(Collection<String> elements) {
// ...
amount = 0;
}
public String next() {
// Start must be 'YY'
if (amount == 0 || amount == 1) {
amount++;
return "Y";
}
// Every third must be 'R'
if (amount % 3 == 0) {
amount++;
return "R";
}
// Pick a random element
amount++;
return elements[rnd.nextInt(elements.length)];
}
public String generate(int amountOfElements) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < amountOfElements - 2; i++) {
sb.append(next());
}
// End must be 'YY'
sb.append("YY");
return sb.toString();
}
}
На самом деле есть еще одно требование, которое мы должны учитывать. Объединение YY
в конце должно быть действительным в отношении правила, которое заставляет R
в каждой третьей позиции. Таким образом, для generate
значение amountOfElements
должно быть на два больше значения, которое делится на 3
, иначе полученное значение будет недействительным.
И мы должны учитывать крайние случаи, amountOfElements
должно быть не менее 5
, каждая меньшая последовательность недопустима. YYRYY
является первой действительной последовательностью. Модифицированный метод:
public String generate(int amountOfElements) {
if (amountOfElements < 5 || (amountOfElements - 2) % 3 != 0) {
throw new IllegalArgumentException("Invalid sequence length");
}
// ...
}