Повторение символов N количество раз (задачка)
Есть задача повторить символы внутри квадратных скобок определенное количество раз. Входные данные выглядят след образом, строка содержащая
3[a] на выходе должно получиться aaa, 3[a]2[y] = aaayy. Но запись может быть и такой 3[2[a]y] на выходе должно получится aayaayaay.
Мой исходник ниже решает проблему с 3[2[a]] но не может справится с 3[2[a]y].
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
System.out.println(DoApr(line));
}
public static String DoApr(String arg) {
char[] chars = arg.toCharArray();
String output1 = "";
for (int i = 0; i < chars.length; i++) {
if (isHasArr(chars)){
if (isNumeric(String.valueOf(chars[i]))) {
int start = i + 2;
int end = FindEnd(chars, start);
if (end != 0) {
String str = "";
String output = "";
for (int g = start; g < end + 1; g++) {
str += String.valueOf(chars[g]);
}
if (str.contains("[")){
str = DoApr(str);
}
if (!str.contains("[")){
for (int c = 0; c < Integer.parseInt(String.valueOf(chars[i])); c++) {
output1 += str.replace("]","");
}
}
}
}
}
}
return output1;
}
public static int FindEnd(char[] chars, int startIndex) {
for (int i = startIndex + 1; i < chars.length; i++) {
if (chars[i] == ']') {
return i;
}
}
return 0;
}
public static boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
public static boolean isHasArr(char[] chars){
boolean hasornot = false;
for (int i = 0 ; i < chars.length;i++){
if (String.valueOf(chars[i]).equals("[")){
hasornot = true;
}
}
return hasornot;
}
}
Есть ли тут какое нибудь решение ?
Ответы (1 шт):
Первое что бросается в глаза - нет обработки вложенных скобок. Просто так не исправить, нужно переделать всю работу.
Это задача на скобочную структуру. А где скобочная структура, там стек (или рекурсия, но у нас будет стек).
Входной поток обрабатывается посимвольно. Если встретилась открывающая скобка, то в стек помещается запись с множителем. Если - буква, то добавляем её в верхний элемент стека, тоже с множителем. Если - закрывающая скобка, то запись из стека извлекается, а текст, который получился между скобками, вставляется в следующий элемент стека, опять-таки с множителем. Цифры обрабатываются отдельно: в каждый момент времени хранится множитель для следующего элемента.
Если в стеке ничего нет, то букву печатаем на выход. И снова множитель не забываем:
import java.io.IOException;
import java.util.Stack;
public class Inflator {
private static class Item {
public final int factor;
public final StringBuilder sb;
public Item(int factor) {
this.factor = factor;
sb = new StringBuilder();
}
};
private static Stack<Item> stack = new Stack<Item>();
public static void main(String... args) {
int c = -1;
int factor = 0;
for (; ; ) {
try {
c = System.in.read();
} catch (IOException e) {
System.exit(1);
}
if (c == -1) {
break;
}
if (Character.isDigit(c)) {
factor = 10 * factor + Character.getNumericValue(c);
} else if (c == '[') {
stack.push(new Item(factor));
factor = 0;
} else if (c == ']') {
Item item = stack.pop();
String s = item.sb.toString();
append(item.factor, s);
factor = 0;
} else {
append(factor, Character.toString((char) c));
factor = 0;
}
}
}
private static void append(int factor, String s) {
int n = (factor == 0) ? 1 : factor;
for (int i = 0; i < n; ++i) {
if (stack.empty()) {
System.out.print(s);
} else {
stack.peek().sb.append(s);
}
}
}
}
$ javac Inflator.java && java Inflator 3a aaa 33a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 3[a]2[y] aaayy 3[2[a]y] aayaayaay 3[2[a]] aaaaaa 2[2[2[2[2[a]]]]] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2[2[2[2[2[2[a]]]]]] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa