📌  相关文章
📜  数组中的字符串,不是任何其他字符串的前缀

📅  最后修改于: 2021-04-17 11:20:19             🧑  作者: Mango

给定一个字符串数组arr [] ,任务是从该数组中打印字符串,这些字符串不是同一数组中任何其他字符串的前缀。
例子:

天真的方法:对于数组的每个字符串,我们检查它是否为其他任何字符串的前缀。如果是,则不显示它。
高效的方法:我们从数组中一个接一个地挑选字符串,并将其插入到Trie中。然后有两种情况插入字符串:

  1. 在插入时,如果发现所选择的字符串是已插入字符串的前缀,则我们不会将此字符串插入到Trie中。
  2. 如果先将前缀插入到Trie中,然后再发现该字符串是某个单词的前缀,则对于该特定节点,我们只需将isEndOfWord = false即可。

构造Trie之后,我们遍历它并显示Trie中的所有单词。
下面是上述方法的实现:

CPP
// C++ implementation of the approach
#include 
using namespace std;
 
const int ALPHABET_SIZE = 26;
 
// Trie node
struct TrieNode {
    struct TrieNode* children[ALPHABET_SIZE];
 
    // isEndOfWord is true if the node represents
    // end of a word
    bool isEndOfWord;
};
 
// Returns new trie node (initialized to NULLs)
struct TrieNode* getNode(void)
{
    struct TrieNode* pNode = new TrieNode;
 
    pNode->isEndOfWord = false;
 
    for (int i = 0; i < ALPHABET_SIZE; i++)
        pNode->children[i] = NULL;
 
    return pNode;
}
 
// Function to insert a string into trie
void insert(struct TrieNode* root, string key)
{
    struct TrieNode* pCrawl = root;
 
    for (int i = 0; i < key.length(); i++) {
        int index = key[i] - 'a';
        if (!pCrawl->children[index])
            pCrawl->children[index] = getNode();
 
        // While inerting a word make
        // each isEndOfWord as false
        pCrawl->isEndOfWord = false;
        pCrawl = pCrawl->children[index];
    }
    int i;
 
    // Check if this word is prefix of
    // some already inserted word
    // If it is then don't insert this word
    for (i = 0; i < 26; i++) {
        if (pCrawl->children[i]) {
            break;
        }
    }
    // If present word is not prefix of
    // any other word then insert it
    if (i == 26) {
        pCrawl->isEndOfWord = true;
    }
}
 
// Function to display words in Trie
void display(struct TrieNode* root, char str[], int level)
{
    // If node is leaf node, it indicates end
    // of string, so a null character is added
    // and string is displayed
    if (root->isEndOfWord) {
        str[level] = '\0';
        cout << str << endl;
    }
 
    int i;
    for (i = 0; i < ALPHABET_SIZE; i++) {
 
        // If NON NULL child is found
        // add parent key to str and
        // call the display function recursively
        // for child node
        if (root->children[i]) {
            str[level] = i + 'a';
            display(root->children[i], str, level + 1);
        }
    }
}
 
// Driver code
int main()
{
    string keys[] = { "apple", "app", "there",
                      "the", "like" };
    int n = sizeof(keys) / sizeof(string);
 
    struct TrieNode* root = getNode();
 
    // Construct trie
    for (int i = 0; i < n; i++)
        insert(root, keys[i]);
 
    char str[100];
    display(root, str, 0);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.Arrays;
class GFG
{
  static final int ALPHABET_SIZE = 26;
 
  // Trie node
  static class TrieNode
  {
    TrieNode[] children;
 
    // isEndOfWord is true if the node represents
    // end of a word
    boolean isEndOfWord;
    TrieNode()
    {
      this.children = new TrieNode[ALPHABET_SIZE];
    }
  }
 
  // Returns new trie node (initialized to NULLs)
  static TrieNode getNode()
  {
    TrieNode pNode = new TrieNode();
    pNode.isEndOfWord = false;
    Arrays.fill(pNode.children, null);
    return pNode;
  }
 
  // Function to insert a String into trie
  static void insert(TrieNode root, String key)
  {
    TrieNode pCrawl = root;
 
    for (int i = 0; i < key.length(); i++)
    {
      int index = key.charAt(i) - 'a';
      if (pCrawl.children[index] == null)
        pCrawl.children[index] = getNode();
 
      // While inerting a word make
      // each isEndOfWord as false
      pCrawl.isEndOfWord = false;
      pCrawl = pCrawl.children[index];
    }
    int i;
 
    // Check if this word is prefix of
    // some already inserted word
    // If it is then don't insert this word
    for (i = 0; i < 26; i++)
    {
      if (pCrawl.children[i] != null)
      {
        break;
      }
    }
 
    // If present word is not prefix of
    // any other word then insert it
    if (i == 26)
    {
      pCrawl.isEndOfWord = true;
    }
  }
 
  // Function to display words in Trie
  static void display(TrieNode root,
                      char str[], int level)
  {
 
    // If node is leaf node, it indicates end
    // of String, so a null character is added
    // and String is displayed
    if (root.isEndOfWord)
    {
      str[level] = '\0';
      System.out.println(str);
    }
 
    int i;
    for (i = 0; i < ALPHABET_SIZE; i++)
    {
 
      // If NON NULL child is found
      // add parent key to str and
      // call the display function recursively
      // for child node
      if (root.children[i] != null)
      {
        str[level] = (char) (i + 'a');
        display(root.children[i], str, level + 1);
      }
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
 
    String keys[] = { "apple", "app", "there", "the", "like" };
    int n = keys.length;
    TrieNode root = getNode();
 
    // Conclass trie
    for (int i = 0; i < n; i++)
      insert(root, keys[i]);
    char[] str = new char[100];
    display(root, str, 0);
  }
}
 
// This code is contributed by sanjeev2552


输出:
apple
like
there