1

我正在寻找一种有效的算法,它将为我提供最长的字符串,该字符串可以由字符串列表组成。更确切地说:

给定一个包含大量字符串的文件,从文件中显示的字符串列表中找到最长的字符串,该字符串是其他一个或多个字符串的串联。

注意:答案字符串也应该属于文件中的字符串列表。

示例输入:

The
he
There
After
ThereAfter

输出:

ThereAfter
4

3 回答 3

2

对列表中的字符串按长度降序对列表进行排序(列表中的第一个是最长的字符串)。快速排序以平均时间复杂度 O(nlogn) 进行排序。

然后,从左开始迭代列表中的字符串。

从字符串 S 开始,迭代其右侧的元素 s。如果 s 是 S 的子串,则从 S 中删除 s。继续向右迭代直到 S 为空,这意味着它是由列表中的项组成的。

public static class ListCompare implements Comparator<String> {
    public int compare(String s1, String s2) {
        if (s1.length() < s2.length())
            return 1;
        else if (s1.length() > s2.length())
            return -1;
        else
            return 0;
    }
}

public static String longestSurString(String[] ss) {
    Arrays.sort(ss, new ListCompare ());
    for (String S: ss) {
        String b = new String(s);
        for (String s: ss) {
            if (!s.equals(b) && S.contains(s)) {
                S = S.replace(s, "");
            }
        }
        if (S.length() == 0)
            return b;
    }
    return null;
}
于 2013-04-28T17:49:19.867 回答
1

让我们为字符串编号S1, S2, ..., Sn

如果我正确理解问题陈述,而不是Si成为答案的候选者,它必须等于一些 Sj_1, Sj_2, ..., Sj_kwhere forall的串联x in 1..k: i != j_x。那必须是它不是其成员Si的字符串子集的串联。

鉴于此,将所有字符串添加到 trie 中。这将找到所有前缀对,即(Si, Sj_1)上述所有。从渲染中删除Sj_1前缀Si会生成一个新字符串T,该字符串必须等于,或者可以通过在 trie 中Sj_k搜索来类似地减少。Sj_2

于 2013-04-27T16:44:19.860 回答
1

使用 Trie & HashMap 数据结构的最佳解决方案:
我们需要首先存储所有字符串,然后检查前缀哪个单词长度更大。

public class TrieNode {
private HashMap<Character, TrieNode> children;
private boolean isWord;

public TrieNode() {
    children = new HashMap<>();
    isWord = false;
}

public void add(String s) {

    HashMap<Character,TrieNode> temp_child = children;

    for(int i=0; i<s.length(); i++){
        char c = s.charAt(i);

        TrieNode trieNode;
        if(temp_child.containsKey(c)){
            trieNode = temp_child.get(c);
        }else{
            trieNode = new TrieNode();
            temp_child.put(c, trieNode);
        }

        temp_child = trieNode.children;

        //set leaf node
        if(i==s.length()-1)
            trieNode.isWord = true;
    }

}

public boolean isWord(String s) {
    TrieNode trieNode = searchNode(s);

    if(trieNode != null && trieNode.isWord)
        return true;
    else
        return false;
}

public TrieNode searchNode(String s){
    HashMap<Character, TrieNode> temp_child = children;
    TrieNode trieNode = null;
    for(int i=0; i<s.length(); i++){
        char c = s.charAt(i);
        if(temp_child.containsKey(c)){
            trieNode = temp_child.get(c);
            temp_child = trieNode.children;
        }else{
            return null;
        }
    }

    return trieNode;
}
于 2016-10-13T18:42:19.600 回答