📌  相关文章
📜  使用两个字典单词串联而成的单词

📅  最后修改于: 2021-04-17 10:54:34             🧑  作者: Mango

给定字典,查找给定单词是否可以由字典中的两个单词组成。

注意:字典中的单词必须唯一,并且要形成的单词不应与Trie中出现的相同单词重复。

例子:

Input : dictionary[] = {"news", "abcd", "tree", 
                              "geeks", "paper"}   
        word = "newspaper"
Output : Yes
We can form "newspaper" using "news" and "paper"

Input : dictionary[] = {"geeks", "code", "xyz", 
                           "forgeeks", "paper"}   
        word = "geeksforgeeks"
Output : Yes

Input : dictionary[] = {"geek", "code", "xyz", 
                           "forgeeks", "paper"}   
        word = "geeksforgeeks"
Output : No

这个想法是将字典中的所有单词都存储在Trie中。我们对给定的单词进行前缀搜索。找到前缀后,我们将搜索单词的其余部分。

算法 :

1- Store all the words of the dictionary in a Trie.
2- Start searching for the given word in Trie.
   If it partially matched then split it into two
   parts and then search for the second part in
   the Trie.
3- If both found, then return true.
4- Otherwise return false.

以下是上述想法的实现。

C++
// C++ program to check if a string can be
// formed by concatenating two words
#include
using namespace std;
  
// Converts key current character into index
// use only 'a' through 'z'
#define char_int(c) ((int)c - (int)'a')
  
// Alphabet size
#define SIZE (26)
  
// Trie Node
struct TrieNode
{
    TrieNode *children[SIZE];
  
    // isLeaf is true if the node represents
    // end of a word
    bool isLeaf;
};
  
// Returns new trie node (initialized to NULLs)
TrieNode *getNode()
{
    TrieNode * newNode = new TrieNode;
    newNode->isLeaf = false;
    for (int i =0 ; i< SIZE ; i++)
        newNode->children[i] = NULL;
    return newNode;
}
  
// If not present, inserts key into Trie
// If the key is prefix of trie node, just
// mark leaf node
void insert(TrieNode *root, string Key)
{
    int n = Key.length();
    TrieNode * pCrawl = root;
  
    for (int i=0; ichildren[index] == NULL)
            pCrawl->children[index] = getNode();
  
        pCrawl = pCrawl->children[index];
    }
  
    // make last node as leaf node
    pCrawl->isLeaf = true;
}
  
// Searches a prefix of key. If prefix is present,
// returns its ending position in string. Else
// returns -1.
int findPrefix(struct TrieNode *root, string key)
{
    int pos = -1, level;
    struct TrieNode *pCrawl = root;
  
    for (level = 0; level < key.length(); level++)
    {
        int index = char_int(key[level]);
        if (pCrawl->isLeaf == true)
            pos = level;
        if (!pCrawl->children[index])
            return pos;
  
        pCrawl = pCrawl->children[index];
    }
    if (pCrawl != NULL && pCrawl->isLeaf)
        return level;
}
  
// Function to check if word formation is possible
// or not
bool isPossible(struct TrieNode* root, string word)
{
    // Search for the word in the trie and
    // store its position upto which it is matched
    int len = findPrefix(root, word);
  
    // print not possible if len = -1 i.e. not
    // matched in trie
    if (len == -1)
        return false;
  
    // If word is partially matched in the dictionary
    // as another word
    // search for the word made after splitting
    // the given word up to the length it is
    // already,matched
    string split_word(word, len, word.length()-(len));
    int split_len = findPrefix(root, split_word);
  
    // check if word formation is possible or not
    return (len + split_len == word.length());
}
  
// Driver program to test above function
int main()
{
    // Let the given dictionary be following
    vector dictionary = {"geeks", "forgeeks",
                                    "quiz", "geek"};
  
    string word = "geeksquiz"; //word to be formed
  
    // root Node of trie
    TrieNode *root = getNode();
  
    // insert all words of dictionary into trie
    for (int i=0; i


Java
import java.util.ArrayList;
import java.util.List;
  
// Java program to check if a string can be 
// formed by concatenating two words 
public class GFG { 
          
    // Alphabet size 
    final static int SIZE = 26; 
      
    // Trie Node 
    static class TrieNode 
    { 
        TrieNode[] children = new TrieNode[SIZE]; 
      
        // isLeaf is true if the node represents 
        // end of a word 
        boolean isLeaf; 
          
        // constructor 
        public TrieNode() { 
            isLeaf = false; 
            for (int i =0 ; i< SIZE ; i++) 
                    children[i] = null; 
        } 
    } 
      
      
    static TrieNode root; 
      
    // If not present, inserts key into Trie 
    // If the key is prefix of trie node, just 
    // mark leaf node 
    static void insert(TrieNode root, String Key) 
    { 
        int n = Key.length(); 
        TrieNode pCrawl = root; 
      
        for (int i=0; i findPrefix(TrieNode root, String key) 
    { 
        List prefixPositions = new ArrayList();
        int level; 
        TrieNode pCrawl = root; 
      
        for (level = 0; level < key.length(); level++) 
        { 
            int index = key.charAt(level) - 'a'; 
            if (pCrawl.isLeaf == true) 
                prefixPositions.add(level); 
            if (pCrawl.children[index] == null) 
                return prefixPositions; 
      
            pCrawl = pCrawl.children[index]; 
        } 
        if (pCrawl != null && pCrawl.isLeaf) 
            prefixPositions.add(level);  
          
        return prefixPositions;  
    } 
      
    // Function to check if word formation is possible 
    // or not 
    static boolean isPossible(TrieNode root, String word) 
    { 
        // Search for the word in the trie and get its prefix positions
        // upto which there is matched 
        List prefixPositions1 = findPrefix(root, word); 
      
        // Word formation is not possible if the word did not have 
        // at least one prefix match
        if (prefixPositions1.isEmpty()) 
            return false; 
      
        // Search for rest of substring for each prefix match
        for (Integer len1 : prefixPositions1) {
            String restOfSubstring = word.substring(len1, word.length()); 
            List prefixPositions2 = findPrefix(root, restOfSubstring);
            for (Integer len2 : prefixPositions2) {
                // check if word formation is possible
                if (len1 + len2 == word.length())
                    return true;
            }
        }
          
        return false;
    } 
      
    // Driver program to test above function 
    public static void main(String args[]) 
    { 
        // Let the given dictionary be following 
        String[] dictionary = {"news", "newspa", "paper", "geek"}; 
      
        String word = "newspaper"; //word to be formed 
      
        // root Node of trie 
        root = new TrieNode(); 
      
        // insert all words of dictionary into trie 
        for (int i=0; i


C#
// C# program to check if a string can be 
// formed by concatenating two words 
using System;
using System.Collections.Generic;
  
class GFG 
{ 
          
    // Alphabet size 
    readonly public static int SIZE = 26; 
      
    // Trie Node 
    public class TrieNode 
    { 
        public TrieNode []children = new TrieNode[SIZE]; 
      
        // isLeaf is true if the node 
        // represents end of a word 
        public bool isLeaf; 
          
        // constructor 
        public TrieNode() 
        { 
            isLeaf = false; 
            for (int i = 0 ; i < SIZE ; i++) 
                    children[i] = null; 
        } 
    } 
    static TrieNode root; 
      
    // If not present, inserts key into Trie 
    // If the key is prefix of trie node, just 
    // mark leaf node 
    static void insert(TrieNode root, String Key) 
    { 
        int n = Key.Length; 
        TrieNode pCrawl = root; 
      
        for (int i = 0; i < n; i++) 
        { 
            int index = Key[i] - 'a'; 
      
            if (pCrawl.children[index] == null) 
                pCrawl.children[index] = new TrieNode(); 
      
            pCrawl = pCrawl.children[index]; 
        } 
      
        // make last node as leaf node 
        pCrawl.isLeaf = true; 
    } 
      
    // Searches a prefix of key. If prefix 
    // is present, returns its ending position 
    //  in string. Else returns -1. 
    static List findPrefix(TrieNode root, String key) 
    { 
        List prefixPositions = new List(); 
        int level; 
        TrieNode pCrawl = root; 
      
        for (level = 0; level < key.Length; level++) 
        { 
            int index = key[level] - 'a'; 
            if (pCrawl.isLeaf == true) 
                prefixPositions.Add(level); 
            if (pCrawl.children[index] == null) 
                return prefixPositions; 
      
            pCrawl = pCrawl.children[index]; 
        } 
        if (pCrawl != null && pCrawl.isLeaf) 
            prefixPositions.Add(level); 
          
        return prefixPositions; 
    } 
      
    // Function to check if word  
    // formation is possible or not 
    static bool isPossible(TrieNode root, String word) 
    { 
        // Search for the word in the trie 
        // and get its prefix positions 
        // upto which there is matched 
        List prefixPositions1 = findPrefix(root, word); 
      
        // Word formation is not possible 
        // if the word did not have 
        // at least one prefix match 
        if (prefixPositions1.Count==0) 
            return false; 
      
        // Search for rest of substring 
        // for each prefix match 
        foreach (int len1 in prefixPositions1) 
        { 
            String restOfSubstring = word.Substring(len1,
                                        word.Length-len1); 
            List prefixPositions2 = findPrefix(root,
                                        restOfSubstring); 
            foreach (int len2 in prefixPositions2) 
            { 
                  
                // check if word formation is possible 
                if (len1 + len2 == word.Length) 
                    return true; 
            } 
        } 
        return false; 
    } 
      
    // Driver code 
    public static void Main(String []args) 
    { 
        // Let the given dictionary be following 
        String[] dictionary = {"news", "newspa", "paper", "geek"}; 
      
        // word to be formed 
        String word = "newspaper"; 
      
        // root Node of trie 
        root = new TrieNode(); 
      
        // insert all words of dictionary into trie 
        for (int i = 0; i < dictionary.Length; i++) 
            insert(root, dictionary[i]); 
      
        if(isPossible(root, word)) 
            Console.WriteLine( "Yes"); 
        else
            Console.WriteLine("No"); 
    } 
} 
  
// This code is contributed by 29AjayKumar


输出:

Yes

锻炼 :
该问题的一般形式是检查是否可以使用1个或更多词典单词的串联来形成给定单词。编写通用版本的代码。