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

解决方案:

  • 从输入中取出下一个字母
  • 新的解决方案基于现有的解决方案。每个新解决方案都是旧解决方案+在现有节点之一中添加的新字母,或者是新节点中添加的单个字母
  • 将新解决方案另存为现有解决方案
  • 从1开始重复,直到处理所有字母
  • 计算所有解决方案的值,并选择一个字符串最少的解决方案
  • 我添加了一个例子,正如您所看到的,解决方案的数量正在快速增加,所以它并没有完全完成所有6个字母。每个步骤表示从1开始的循环。到4,您可以看到,在每个步骤中,以前的解决方案都被用作新解决方案的基础。为每个现有解决方案创建了多个新解决方案


    此代码返回以下组合:

    • 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;
    }