给定字典,查找给定单词是否可以由字典中的两个单词组成。
注意:字典中的单词必须唯一,并且要形成的单词不应与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个或更多词典单词的串联来形成给定单词。编写通用版本的代码。