【问题标题】:Longest string that can be made out of a list of strings可以由字符串列表组成的最长字符串
【发布时间】:2013-04-21 16:22:38
【问题描述】:

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

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

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

示例输入:

The
he
There
After
ThereAfter

输出:

ThereAfter

【问题讨论】:

  • 那你有没有效率低的?
  • 按长度对字符串进行排序,并从最短开始构建前缀树。

标签: algorithm data-structures concatenation


【解决方案1】:

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

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

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

【讨论】:

    【解决方案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;
    }
    

    【讨论】:

    • ["ThereAfterThemath", "AfterThem", "There", "math", "The", "he"] 如果这是已排序的数组,您的解决方案将返回 null 而答案应该是“ThereAfterThemath”。如果我在这里遗漏了什么愚蠢的东西,请纠正我。
    【解决方案3】:

    使用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-08
      • 2012-03-13
      • 2012-05-10
      • 1970-01-01
      相关资源
      最近更新 更多