I'm working on a problem, where given a string with substrings in paranthesis followed by values in curly brackets, the string expands by repeating the substring that number of times. So if you had (ab(d){3}){2} you'd get abdddabddd.
I feel like Im on the right track but that 1. this is pretty inefficient and 2. the tests seem to not return. Would love some help!
public class ExpandedString {
public static String expandedString(String inputStr) {
while (inputStr.contains("(")) {
for (int i = 0; i < inputStr.length(); i ) {
//check if there's something to repeat
if (inputStr.charAt(i) == '{') {
int temp = i;
//find what you need to repeat
while (inputStr.charAt(temp) != '(') {
temp--;
}
String inputStr2 = inputStr.substring(i);
int numTimes = i inputStr.indexOf("}");
//replace (blah) with blah times repeated numTimes
StringBuilder repeated = new StringBuilder();
for(int j = 0; j<numTimes;j ) {
repeated.append(inputStr.substring(temp 1, i - 1));
}
inputStr.replace(inputStr.substring(temp, i), repeated.toString());
//start again
i = 0;
}
}
}
return inputStr;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// input for inputStr
String inputStr = in .nextLine();
String result = expandedString(inputStr);
System.out.print(result);
}
}
CodePudding user response:
Here is a solution that uses a stack of StringBuilders and a current StringBuilder.
When a (
is read, the current StringBuilder is pushed onto the stack and a new StringBuilder is created.
When a )
is read, the multiplier mul
is extracted, and the value of the current StringBuilder is appended mul
times to the StringBuilder popped from the stack.
Otherwhise, append the char to the current StringBuilder.
import java.util.Stack;
public class Expand
{
public static String expand(String pattern)
{
StringBuilder sb = new StringBuilder();
Stack<StringBuilder> stack = new Stack<StringBuilder>();
int len = pattern.length();
int i = 0;
while(i<len)
{
char c = pattern.charAt(i);
if(c=='(')
{
stack.push(sb);
sb = new StringBuilder();
}
else if(c==')')
{
String s = sb.toString();
int k = pattern.indexOf('}', i);
int mul = Integer.parseInt(pattern.substring(i 2, k));
sb = stack.pop();
for(int j=0;j<mul;j )
sb.append(s);
i = k;
}
else
sb.append(c);
i ;
}
return sb.toString();
}
public static void main(String[] args)
{
System.out.println(expand("(ab(d){3}){2}"));
}
}
Output:
abdddabddd
CodePudding user response:
An alternative way of getting the desired string using regex
:
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExpandedString {
public static String expandedString(String inputStr) {
while (true) {
Pattern pattern = Pattern.compile("(\\((\\w*)\\)\\{(\\d*)\\})", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
if (!matcher.find())
break;
inputStr = matcher.replaceAll("$2".repeat(Integer.parseInt(matcher.group(3))));
}
return inputStr;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// input for inputStr
String inputStr = in.nextLine();
String result = expandedString(inputStr);
System.out.print(result);
}
}
I assume that string
consists of word
characters.