我的输入是格式编号为[string]的压缩字符串,解压缩的输出格式应为写入次数的字符串。例如:
3[abc]4[ab]c = abcabcabcababababc
2[3[a]b] = aaabaaab.
我在Java中的蛮力方法:
public class CompresnDecompresn {
public static void main(String[] args) {
String s="3[abc]4[ab]c";
for (int i = 0; i<s.length(); i++) {
if(s.charAt(i)==']') {
int j=i-1;
while(true) {
if(s.charAt(j)=='[') {
break;
}
j--;
}
int k=j-1;
while(true) {
if(k<0) {
break;
}
int m=(int)s.charAt(k);
if(m<48 || m>57) {
break;
}
k--;
}
k++;
int freq=Integer.parseInt(s.substring(k, j));
String snippet=s.substring(j+1,i);
String temp="";
for (int l = 0; l < freq; l++) {
temp+=snippet;
}
s=s.substring(0,k)+temp+s.substring(i+1);
}
}
System.out.println(s);
}
}
我能以更低的成本获得更好的方法吗?
答案 0 :(得分:2)
由于您使用Java,因此请随意使用Java提供的功能,以使解决方案更具可读性和直接性。这里使用正则表达式以及使用StringBuilder
连接字符串。
考虑输入String string ="3[abc]4[ab]c";
就个人而言,我会选择这样的事情:
首先定义持有数字字母对的Couple
类。
private static class Couple {
public int x;
public String y;
public Couple(int x, String y) {
this.x = x;
this.y = y;
}
}
我们走了:
// Regex to extract the number before '[' and the content inside of '[]'
Pattern p = Pattern.compile("(\\d+)\\[(.*?)\\]");
Matcher m = p.matcher(string);
// Coupling the number and the letters
List<Couple> couples = new ArrayList<>();
while (m.find()) {
couples.add(new Couple(Integer.parseInt(m.group(1)), m.group(2)));
}
// Concatenating String together using the for-cycle
String rest = string.substring(string.lastIndexOf("]")+1, string.length());
StringBuilder sb = new StringBuilder();
for (Couple c: couples) {
for (int i=0; i<c.x; i++) {
sb.append(c.y);
}
}
// Enjoying the result
sb.append(rest);
System.out.println(sb.toString());
请记住,对于您的问题,这只是一个愚蠢的天真解决方案,以防始终存在格式为
的输入字符串number[string]number[string]number[string]rest // more of number[string] pairs
你必须广泛思考是否有地方需要注意失败的代码。如果没有rest
怎么办?如果用户的输入格式不同(永远不要信任用户的输入)怎么办 - 所以不值得对Regex进行验证吗?你必须向自己提出问题,然后开始如果发生了什么。
无论如何,您可以从我的实施开始,然后根据需要继续。
答案 1 :(得分:0)
我们实际上希望在return (T)(object) new Series<float>();
中找到字符串并重复[]
之前指定的n
次。但问题是这些字符串是嵌套的。
因此,当我们调用在[]
中读取字符串的函数时,它应该在遇到新的[]
时再次调用自身。因此,这会导致递归解决方案,我们只在输入字符串中循环一次。
[]
答案 2 :(得分:0)
通过递归解决问题将是方便的解决方案。跟踪嵌套[]
的一种更简单方法是,每次遇到open
时递增[
变量,并在遇到]
时递减它,并递归调用deCompress()
当你遇到]
时。
public String deCompress(int times, String ip) {
String op = "";
int open = 0;
char a;
int start = 0;
int t=0;
String expand = "";
for (int i = 0; i < ip.length(); i++) {
a = ip.charAt(i);
if (Character.isDigit(a) && open == 0) {
//Calculates times
t = t * 10 + Integer.parseInt(""+a);
//We want to expand and append to the output
if (expand != "") {
op += expand;
expand = "";
}
}
else if(a == '[') {
//start index for substring : Recursive solution
if(open == 0) {
start = i + 1;
}
open++;
continue;
}
else if(a == ']') {
//Recursive solution for nested compression
open--;
if(open == 0) {
expand = deCompress(t, ip.substring(start, i));
t = 0;
}
continue;
}
else {
if (open == 0) {
expand += a;
}
}
}
//Append the expanded string to the output for strings with 0 times
if(times == 0) {
op += expand;
}
//Expand string x times
for (int j = 1; j<=times; j++) {
op += expand;
}
return op;
}
只需调用此函数 -
deCompress(0, "3[abc]4[ab]c2[3[a]b]")
答案 3 :(得分:0)
我已经使用堆栈来解决问题。
from collections import deque
st=input("Enter a compressed string: ")
myStack=deque()
numstring=""
alphastring=""
for i in range(len(st)):
ch=st[i]
print(myStack)
if ch.isdigit():
numstring+=ch
if alphastring!="":
myStack.append(alphastring)
alphastring=""
elif ch=='[':
myStack.append(numstring)
numstring=""
elif ch.isalpha():
alphastring+=ch
elif ch==']':
top=myStack.pop()
if top.isnumeric():
check=""
m=int(top)
word=alphastring*m
if len(myStack)>0:
check=myStack.pop()
if(check.isalpha()):
word=check+word
else:
myStack.append(check)
myStack.append(word)
alphastring=""
else:
m=int(myStack.pop())
myStack.append((top+alphastring)*m)
alphastring=""
solution=alphastring
while(len(myStack)>0):
solution=myStack.pop()+solution
print("Decompressed : ",solution)
答案 4 :(得分:0)
@Test()
public void googleProblemSolve() {
String mainString = "3[abc]4[ab]c10[a]9[x]15[d]";
// Split the string using end bracket
String sep[] = mainString.split("\\]");
for (int i = 0; i < sep.length; i++) {
// remove start bracket from the each index to get iteration count
String[] subSep = sep[i].split("\\[");
/* before part of the split string would be iteration count and second part
would be the actual string*/
repeatWords(subSep[0], subSep[1]);
}
}
private void repeatWords(String iteration, String str) {
int ite = 0;
String newStr = str;
// iteration value can throw exception if the string is like i.e. c10
try {
ite = Integer.parseInt(iteration);
} catch (NumberFormatException e) {
/*
* consider the first char in the string would be the alphabet with no
* repeatation
*/
newStr = Character.toString(iteration.charAt(0));
// check the length of the string;
// if its three means iteration count is in 2 digit
if (iteration.length() == 3) {
ite = Character.getNumericValue(iteration.charAt(1) + iteration.charAt(2));
} else {
ite = Integer.parseInt(String.valueOf(iteration.charAt(1)));
}
}
for (int i = 0; i < ite - 1; i++) {
newStr = newStr + str;
}
System.out.print(newStr);
}
我想这可能是这个问题的最佳解决方案。请分享您的想法。