Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:如何比较两个字符串以获得它们不同的部分?_Java_String_String Comparison - Fatal编程技术网

Java:如何比较两个字符串以获得它们不同的部分?

Java:如何比较两个字符串以获得它们不同的部分?,java,string,string-comparison,Java,String,String Comparison,我想学习一种获得两个字符串不同部分的方法 假设我有两个字符串: String s1 = "x4.printString(\"Bianca.()\").y1();"; String s2 = "sb.printString(\"Bianca.()\").length();"; String s1 = "while (x1 < 5)" String s2 = "while (j < 5)" 我想要这个输出:[“x4”、“y1”、“sb”、“length”]来自一个接收s1和s2作为参

我想学习一种获得两个字符串不同部分的方法

假设我有两个字符串:

String s1 = "x4.printString(\"Bianca.()\").y1();";
String s2 = "sb.printString(\"Bianca.()\").length();";
String s1 = "while (x1 < 5)"
String s2 = "while (j < 5)"
我想要这个输出:
[“x4”、“y1”、“sb”、“length”]
来自一个接收
s1
s2
作为参数的方法

我在其他帖子中也找过类似的东西,但我只找到了到的链接

但此方法从索引返回第二个字符串,该字符串开始与第一个字符串不同。
我真的不知道从哪里开始,任何建议都将不胜感激

更新 按照@aUserHimself的建议,我成功地获得了两个字符串中的所有公共子序列,但这些子序列就像一个唯一的字符串。

这是我现在的代码:

private static int[][] lcs(String s, String t) {
    int m, n;
    m = s.length();
    n = t.length();
    int[][] table = new int[m+1][n+1];
    for (int i=0; i < m+1; i++)
        for (int j=0; j<n+1; j++)
            table[i][j] = 0;
    for (int i = 1; i < m+1; i++)
        for (int j = 1; j < n+1; j++)
            if (s.charAt(i-1) == t.charAt(j-1))
                table[i][j] = table[i-1][j-1] + 1;
            else
                table[i][j] = Math.max(table[i][j-1], table[i-1][j]);
    return table;
}

private static List<String> backTrackAll(int[][]table, String s, String t, int m, int n){
    List<String> result = new ArrayList<>();
    if (m == 0 || n == 0) {
        result.add("");
        return result;
    }
    else
        if (s.charAt(m-1) == t.charAt(n-1)) {
            for (String sub : backTrackAll(table, s, t, m - 1, n - 1))
                result.add(sub + s.charAt(m - 1));
            return result;
        }
        else {
            if (table[m][n - 1] >= table[m - 1][n])
                result.addAll(backTrackAll(table, s, t, m, n - 1));
            else
                result.addAll(backTrackAll(table, s, t, m - 1, n));
            return result;
        }
}

private List<String> getAllSubsequences(String s, String t){
    return backTrackAll(lcs(s, t), s, t, s.length(), t.length());
}

我收到这个字符串:
[“while(<5)”]
不是我想要得到的
[“while(“,”<5)”]
。我不明白我哪里做错了。

在两个字符串之间找到最长的公共子序列。 之后,您可以使用indexOf在两个字符串之间获取此公共字符串的索引,并从这两个字符串中获取不常见的值

例如:

CICROSOFK
WOCROSFGT
常见的字母是

CROS
查找不同的字符串,从0到
SOFT
的索引,从
index+'SOFT'.length
str.length
我已经在上面标记了,其答案使用了两个字符串的
最长公共子序列

因此,您可以递归地应用它,并且在每个新的递归上,在找到此
LCS
的位置使用
占位符
,以便您可以标记不同的部分。最后,当不再存在常见的序列时,您必须按
占位符拆分每个字符串,并获得所需的部分

update1:
如果我现在想得更好,这个递归部分可能不会导致最佳解决方案(从总执行时间的角度来看),因为您将在字符串上迭代多次。但是可能有一种方法可以通过重用
memorization
表(一个简化版本),检查并删除,从一次迭代中检索所有序列

更新2:
我已经成功实现了递归版本(不是最佳版本),基于:

公共类最长公共序列{
私人最终字符[]firstStr;
私人最终字符[]第二字符;
专用int[][]LCS;
私有字符串[][]解决方案;
私有int max=-1,maxI=-1,maxJ=-1;
专用静态最终字符分隔符=“|”;
公共最长公共序列(char[]firstStr,char[]secondStr){
this.firstStr=firstStr;
this.secondStr=secondStr;
LCS=newint[firstStr.length+1][secondStr.length+1];
解决方案=新字符串[firstStr.length+1][secondStr.length+1];
}
公共字符串find(){
对于(int i=0;i 0){
解决方案[0][i]=''+secondStr[i-1];
}
}
对于(int i=0;i 0){
解决方案[i][0]=“+firstStr[i-1];
}
}
解决方案[0][0]=“无”;

对于(int i=1;i我的代码可能不是最紧凑的,但为了清晰起见,我这样写:

public static void main(String[] args) throws InterruptedException, FileNotFoundException, ExecutionException {

    String s1 = "x4.printString(\"Bianca.()\").y1();";
    String s2 = "sb.printString(\"Bianca.()\").length();";

    List<String> result = new ArrayList<>();
    result.addAll(getDifferences(s1, s2));
    result.addAll(getDifferences(s2, s1));

    System.out.println(result);
}

public static List<String> getDifferences(String s1, String s2){
    if(s1 == null){
        return Collections.singletonList(s2);
    }
    if(s2 == null){
        return Collections.singletonList(s1);
    }
    int minimalLength = Math.min(s1.length(),s2.length());
    List<String> result = new ArrayList<>();
    StringBuilder buffer = new StringBuilder(); // keep the consecutive differences
    for(int i = 0; i<minimalLength; i++ ){
        char c = s1.charAt(i);
        if(c == s2.charAt(i)){
            if( buffer.length() > 0){
                result.add(buffer.toString());
                buffer = new StringBuilder();
            }
        } else {
            buffer.append(c);
        }
    }
    if(s1.length() > minimalLength){
        buffer.append(s1.substring(minimalLength)); // add the rest
    }
    if(buffer.length() > 0){
        result.add(buffer.toString()); //flush buffer
    }
    return result;
}
publicstaticvoidmain(String[]args)抛出interruptedeexception、FileNotFoundException、ExecutionException{
字符串s1=“x4.printString(\”Bianca.\”).y1();”;
String s2=“sb.printString(\”Bianca.\”).length();”;
列表结果=新建ArrayList();
结果:addAll(getDifferences(s1,s2));
结果:addAll(getDifferences(s2,s1));
系统输出打印项次(结果);
}
公共静态列表getDifferences(字符串s1、字符串s2){
如果(s1==null){
返回集合。单音列表(s2);
}
if(s2==null){
返回集合。单音列表(s1);
}
int minimalength=Math.min(s1.length(),s2.length());
列表结果=新建ArrayList();
StringBuilder buffer=new StringBuilder();//保留连续的差异
对于(int i=0;i 0){
add(buffer.toString());
缓冲区=新的StringBuilder();
}
}否则{
缓冲区。附加(c);
}
}
if(s1.length()>最小长度){
buffer.append(s1.substring(minimalength));//添加其余部分
}
if(buffer.length()>0){
result.add(buffer.toString());//刷新缓冲区
}
返回结果;
}

但是,请注意,由于您没有指定要删除非单词字符,因此也会返回非单词字符(但它们不会出现在预期的输出中)。

这是我找到的解决方案,感谢@aUserHimself发布的链接

private static int[][] lcs(String s, String t) {
        int m, n;
        m = s.length();
        n = t.length();
        int[][] table = new int[m+1][n+1];
        for (int i=0; i < m+1; i++)
            for (int j=0; j<n+1; j++)
                table[i][j] = 0;
        for (int i = 1; i < m+1; i++)
            for (int j = 1; j < n+1; j++)
                if (s.charAt(i-1) == t.charAt(j-1))
                        table[i][j] = table[i-1][j-1] + 1;
                else
                    table[i][j] = Math.max(table[i][j-1], table[i-1][j]);
        return table;
    }

private static List<List<String>> getDiffs(int[][] table, String s, String t, int i, int j,
                                           int indexS, int indexT, List<List<String>> diffs){
    List<String> sList, tList;
    sList = diffs.get(0);
    tList = diffs.get(1);
    if (i > 0 && j > 0 && (s.charAt(i-1) == t.charAt(j-1)))
        return getDiffs(table, s, t, i-1, j-1, indexS, indexT, diffs);
    else if (i > 0 || j > 0) {
            if (i > 0 && (j == 0 || table[i][j-1] < table[i-1][j])){
                if (i == indexS)
                    sList.set(sList.size()-1, String.valueOf(s.charAt(i-1)) + sList.get(sList.size() - 1));
                else
                    sList.add(String.valueOf(s.charAt(i-1)));
                diffs.set(0, sList);
                return getDiffs(table, s, t, i-1, j, i-1, indexT, diffs);
            }
            else if (j > 0 && (i == 0 || table[i][j-1] >= table[i-1][j])){
                if (j == indexT)
                    tList.set(tList.size() - 1, String.valueOf(t.charAt(j-1)) + tList.get(tList.size()-1));
                else
                    tList.add(String.valueOf(t.charAt(j-1)));
                diffs.set(1, tList);
                return getDiffs(table, s, t, i, j-1, indexS, j-1, diffs);
            }
        }
    return diffs;
}

private static List<List<String>> getAllDiffs(String s, String t){
    List<List<String>> diffs = new ArrayList<List<String>>();
    List<String> l1, l2;
    l1 = new ArrayList<>();
    l2 = new ArrayList<>();
    diffs.add(l1);
    diffs.add(l2);
    return getDiffs(lcs(s, t), s, t, s.length(), t.length(), 0,  0, diffs);
}
private static int[]lcs(字符串s,字符串t){
int m,n;
m=s.长度();
n=t.长度();
int[][]表=新int[m+1][n+1];
对于(int i=0;i0&&(s.charAt(i-1)=t.charAt(j-1)))
返回getdiff(表,s,t,i-1,j-1,indexS,indexT,diff);
else如果(i>0 | | j>0){
如果(i>0&(j==0 | |表[i][j-1]<表[i-1][j])){
如果(i==indexS)
sList.set(sList.size()-1,String.valueOf(s.charAt(i-1))+sList.get(sList.size()-1));
其他的
sList.add(String.valueOf(s.charAt(i-1));
差异集(0,滑动);
返回getdiff(表,s,t,i-1,j,i-1,indexT,diff);
}
else如果(j>0&(i==0 | |表[i][j-1]>=表[i-1][j])){
如果(j==indexT)
tList.set(tList.size()-1,String.valueOf(t.charAt(j-1))+tList.get(tList.size()-1));
其他的
tList.add(String.valueOf(t.charAt(j-1));
差异集(1,t列表);
返回getdiff(表,s,t,i,j-1,索引,j-1,diff);
}
}
回报差异;
}
私有静态列表GetAllDiff(字符串s、字符串t){
private static int[][] lcs(String s, String t) {
        int m, n;
        m = s.length();
        n = t.length();
        int[][] table = new int[m+1][n+1];
        for (int i=0; i < m+1; i++)
            for (int j=0; j<n+1; j++)
                table[i][j] = 0;
        for (int i = 1; i < m+1; i++)
            for (int j = 1; j < n+1; j++)
                if (s.charAt(i-1) == t.charAt(j-1))
                        table[i][j] = table[i-1][j-1] + 1;
                else
                    table[i][j] = Math.max(table[i][j-1], table[i-1][j]);
        return table;
    }

private static List<List<String>> getDiffs(int[][] table, String s, String t, int i, int j,
                                           int indexS, int indexT, List<List<String>> diffs){
    List<String> sList, tList;
    sList = diffs.get(0);
    tList = diffs.get(1);
    if (i > 0 && j > 0 && (s.charAt(i-1) == t.charAt(j-1)))
        return getDiffs(table, s, t, i-1, j-1, indexS, indexT, diffs);
    else if (i > 0 || j > 0) {
            if (i > 0 && (j == 0 || table[i][j-1] < table[i-1][j])){
                if (i == indexS)
                    sList.set(sList.size()-1, String.valueOf(s.charAt(i-1)) + sList.get(sList.size() - 1));
                else
                    sList.add(String.valueOf(s.charAt(i-1)));
                diffs.set(0, sList);
                return getDiffs(table, s, t, i-1, j, i-1, indexT, diffs);
            }
            else if (j > 0 && (i == 0 || table[i][j-1] >= table[i-1][j])){
                if (j == indexT)
                    tList.set(tList.size() - 1, String.valueOf(t.charAt(j-1)) + tList.get(tList.size()-1));
                else
                    tList.add(String.valueOf(t.charAt(j-1)));
                diffs.set(1, tList);
                return getDiffs(table, s, t, i, j-1, indexS, j-1, diffs);
            }
        }
    return diffs;
}

private static List<List<String>> getAllDiffs(String s, String t){
    List<List<String>> diffs = new ArrayList<List<String>>();
    List<String> l1, l2;
    l1 = new ArrayList<>();
    l2 = new ArrayList<>();
    diffs.add(l1);
    diffs.add(l2);
    return getDiffs(lcs(s, t), s, t, s.length(), t.length(), 0,  0, diffs);
}