Java 如何找到字符串的分解?
我需要为Java 如何找到字符串的分解?,java,string,algorithm,Java,String,Algorithm,我需要为String分解创建一个算法 一些例子: ABCABCDEDEDEF-->ABC*2+DE*3+F abccabccczcz-->ABC*2+cz*2+c 测试-->测试 字符串的每一段都应该用一个+分隔,如果重复,后面跟着一个*加上它连续出现的次数 这就是我尝试过的: private static int[] prefixFunction(String source) { int n = source.length(); int[] pi = new int[n];
String
分解创建一个算法
一些例子:
-->ABCABCDEDEDEF
ABC*2+DE*3+F
-->abccabccczcz
ABC*2+cz*2+c
-->测试
测试
+
分隔,如果重复,后面跟着一个*
加上它连续出现的次数
这就是我尝试过的:
private static int[] prefixFunction(String source) {
int n = source.length();
int[] pi = new int[n];
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j > 0 && source.charAt(i) != source.charAt(j))
j = pi[j - 1];
if (source.charAt(i) == source.charAt(j))
j++;
pi[i] = j;
}
return pi;
}
private static int[]prefixFunction(字符串源){
int n=source.length();
int[]pi=新的int[n];
对于(int i=1;i0&&source.charAt(i)!=source.charAt(j))
j=pi[j-1];
if(source.charAt(i)=source.charAt(j))
j++;
pi[i]=j;
}
返回pi;
}
强力alghoritm的工作原理如下
先决条件:
- 第一个字母设置为根
- 每个可能解决方案的数据结构都是链表。每个节点的值都是要写入的文本
- 输出解决方案时,首先将所有文本值与外观数一起映射。如果它出现多次,请使用
作为乘法器*
ABC-C-ABC
,输出为ABC*2+C
解决方案:
此代码返回以下组合:
ABCABCDEDEDEF->ABC*2+DE*3+F
abccabccczcz->ABCc*2+zcz
cefabcccz->cef+ABCc*2+zcz
此解决方案保持一切有序,这意味着像
ABCABCDEDEDEF
这样的输入将返回ABC*2+DE*3+F
,或者像abdededab
这样的输入将返回ab+DE*2+ab
如果不遵守顺序,那么以后就不可能100%准确地重建字符串
public static void main(String[] args) {
String input = "ABCABCDEDEDEF";
String output = findDecomposition(input);
System.out.println("Output: " + output);
}
public static String findDecomposition(String input) {
String substring = input;
StringBuilder builder = new StringBuilder();
for (int start = 0, count = 1; start < input.length(); start++, count = 1) {
for (int end = start + 1; end < input.length(); end++) {
substring = input.substring(start, end);
while (true) {
String next = input.substring(start + substring.length(), Math.min(end + substring.length(), input.length()));
if (next.equals(substring)) {
count++;
start += substring.length();
end += substring.length();
} else
break;
}
if (count > 1) {
start += substring.length() - 1;
break;
}
}
if (count > 1) {
if (builder.length() > 0 && builder.charAt(builder.length() - 1) != '+')
builder.append('+');
builder.append(substring + "*" + count + "+");
} else
builder.append(input.charAt(start));
}
String result = builder.toString();
if (result.endsWith("+"))
return result.substring(0, result.length() - 1);
else
return result;
}
publicstaticvoidmain(字符串[]args){
字符串输入=“ABCABCDEDEDEF”;
字符串输出=findDecomposition(输入);
System.out.println(“输出:”+输出);
}
公共静态字符串findDecomposition(字符串输入){
字符串子字符串=输入;
StringBuilder=新的StringBuilder();
对于(int start=0,count=1;start1){
start+=子字符串.length()-1;
打破
}
}
如果(计数>1){
如果(builder.length()>0&&builder.charAt(builder.length()-1)!=“+”)
builder.append('+');
builder.append(子字符串+“*”+计数+“+”);
}否则
builder.append(input.charAt(start));
}
字符串结果=builder.toString();
if(result.endsWith(“+”))
返回result.substring(0,result.length()-1);
其他的
返回结果;
}
这可以通过使用KMP算法最长前缀(也是后缀)来解决
步骤:
迭代字符串“ABCABCDEDEF”并为该字符串构造lps数组。数组中的值将为
0 0 0 1 2 3 0 0 0 0 0 0 0
此lps数组给出前缀在字符串中重复的次数。
在上述情况下,仅重复一次。考虑到实际前缀次数将为2,它将变为ABC*2
取剩余字符串的子字符串,重复步骤1直到字符串结束
如果需要,我可以提供代码。最糟糕的时间复杂度是O(n2)?i、 e.(ABC*2+DEF)*3我认为不是,因为在这个问题中,我需要只对字符串使用+
和*
操作来构建输入字符串的最经济的表示形式,而不使用任何括号。你说的“占用最小空间”是什么意思?字符串是否总是按如下顺序排列:DE
、ABC
等。?多举一些例子就好了。@Daniel“占用空间最小”=最佳解决方案。另外,再加上一个例子。@SlandShow-我认为还有一个问题,您是否意识到abccabccczcz
有11个字符,而ABC*2+cz*2+c
有12个字符,这与test
基本相同,修改是不值得的。在快速阅读之后,这感觉就像我所想的:滑动窗口方法可能是保持秩序的唯一方法+1能够100%准确地重建字符串不是规定的要求之一,使用此约束可能会导致与不解决此约束的方法截然不同的结果。@。然而,我想指出它的优点
public static void main(String[] args) {
String input = "ABCABCDEDEDEF";
String output = findDecomposition(input);
System.out.println("Output: " + output);
}
public static String findDecomposition(String input) {
String substring = input;
StringBuilder builder = new StringBuilder();
for (int start = 0, count = 1; start < input.length(); start++, count = 1) {
for (int end = start + 1; end < input.length(); end++) {
substring = input.substring(start, end);
while (true) {
String next = input.substring(start + substring.length(), Math.min(end + substring.length(), input.length()));
if (next.equals(substring)) {
count++;
start += substring.length();
end += substring.length();
} else
break;
}
if (count > 1) {
start += substring.length() - 1;
break;
}
}
if (count > 1) {
if (builder.length() > 0 && builder.charAt(builder.length() - 1) != '+')
builder.append('+');
builder.append(substring + "*" + count + "+");
} else
builder.append(input.charAt(start));
}
String result = builder.toString();
if (result.endsWith("+"))
return result.substring(0, result.length() - 1);
else
return result;
}