📜  给定一系列单词,将所有字谜一起打印|套装2

📅  最后修改于: 2021-04-17 12:09:05             🧑  作者: Mango

给定一组单词,将所有字谜一起打印。例如,如果给定的数组是{“ cat”,“ dog”,“ tac”,“ god”,“ act”},则输出可能是“ cat tac act dog god”。

在上一篇文章中,我们讨论了两种不同的方法。在这篇文章中,讨论了一种更有效的解决方案。

Trie数据结构可用于更有效的解决方案。插入每个单词的排序顺序。由于所有字谜都将在同一叶节点处结束。我们可以在叶节点处开始一个链表,其中每个节点代表原始单词数组的索引。最后,遍历Trie。遍历Trie时,一次遍历每个链表。以下是详细步骤。

1)创建一个空的Trie
2)一一拿走输入序列的所有单词。每个字都要关注
a)将单词复制到缓冲区中。
b)对缓冲区进行排序
c)将排序后的缓冲区和该词的索引插入Trie。 Trie的每个叶节点都是索引列表的头。索引列表按原始顺序存储单词的索引。如果已经存在排序的buffe,我们将该单词的索引插入索引列表。
3)遍历Trie。在遍历时,如果到达叶节点,则遍历索引列表。并使用从索引列表中获得的索引打印所有单词。

C++
// An efficient program to print all anagrams together
#include 
#include 
#include 
#include 
  
#define NO_OF_CHARS 26
  
// Structure to represent list node for indexes of words in
// the given sequence. The list nodes are used to connect
// anagrams at leaf nodes of Trie
struct IndexNode
{
    int index;
    struct IndexNode* next;
};
  
// Structure to represent a Trie Node
struct TrieNode
{
    bool isEnd;  // indicates end of word
    struct TrieNode* child[NO_OF_CHARS]; // 26 slots each for 'a' to 'z'
    struct IndexNode* head; // head of the index list
};
  
  
// A utility function to create a new Trie node
struct TrieNode* newTrieNode()
{
    struct TrieNode* temp = new TrieNode;
    temp->isEnd = 0;
    temp->head = NULL;
    for (int i = 0; i < NO_OF_CHARS; ++i)
        temp->child[i] = NULL;
    return temp;
}
  
/* Following function is needed for library function qsort(). Refer
   http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */
int compare(const void* a, const void* b)
{  return *(char*)a - *(char*)b; }
  
/* A utility function to create a new linked list node */
struct IndexNode* newIndexNode(int index)
{
    struct IndexNode* temp = new IndexNode;
    temp->index = index;
    temp->next = NULL;
    return temp;
}
  
// A utility function to insert a word to Trie
void insert(struct TrieNode** root, char* word, int index)
{
    // Base case
    if (*root == NULL)
        *root = newTrieNode();
  
    if (*word != '\0')
        insert( &( (*root)->child[tolower(*word) - 'a'] ), word+1, index );
    else  // If end of the word reached
    {
        // Insert index of this word to end of index linked list
        if ((*root)->isEnd)
        {
            IndexNode* pCrawl = (*root)->head;
            while( pCrawl->next )
                pCrawl = pCrawl->next;
            pCrawl->next = newIndexNode(index);
        }
        else  // If Index list is empty
        {
            (*root)->isEnd = 1;
            (*root)->head = newIndexNode(index);
        }
    }
}
  
// This function traverses the built trie. When a leaf node is reached,
// all words connected at that leaf node are anagrams. So it traverses
// the list at leaf node and uses stored index to print original words
void printAnagramsUtil(struct TrieNode* root, char *wordArr[])
{
    if (root == NULL)
        return;
  
    // If a lead node is reached, print all anagrams using the indexes
    // stored in index linked list
    if (root->isEnd)
    {
        // traverse the list
        IndexNode* pCrawl = root->head;
        while (pCrawl != NULL)
        {
            printf( "%s ", wordArr[ pCrawl->index ] );
            pCrawl = pCrawl->next;
        }
    }
  
    for (int i = 0; i < NO_OF_CHARS; ++i)
        printAnagramsUtil(root->child[i], wordArr);
}
  
// The main function that prints all anagrams together. wordArr[] is input
// sequence of words.
void printAnagramsTogether(char* wordArr[], int size)
{
    // Create an empty Trie
    struct TrieNode* root = NULL;
  
    // Iterate through all input words
    for (int i = 0; i < size; ++i)
    {
        // Create a buffer for this word and copy the word to buffer
        int len = strlen(wordArr[i]);
        char *buffer = new char[len+1];
        strcpy(buffer, wordArr[i]);
  
        // Sort the buffer
        qsort( (void*)buffer, strlen(buffer), sizeof(char), compare );
  
        // Insert the sorted buffer and its original index to Trie
        insert(&root,  buffer, i);
    }
  
    // Traverse the built Trie and print all anagrms together
    printAnagramsUtil(root, wordArr);
}
  
  
// Driver program to test above functions
int main()
{
    char* wordArr[] = {"cat", "dog", "tac", "god", "act", "gdo"};
    int size = sizeof(wordArr) / sizeof(wordArr[0]);
    printAnagramsTogether(wordArr, size);
    return 0;
}


Java
// An efficient program to print all 
// anagrams together    
import java.util.Arrays;
import java.util.LinkedList;
  
public class GFG 
{ 
    static final int NO_OF_CHARS = 26;
      
    // Class to represent a Trie Node
    static class TrieNode
    {
        boolean isEnd;  // indicates end of word
          
        // 26 slots each for 'a' to 'z'
        TrieNode[] child = new TrieNode[NO_OF_CHARS];
          
        // head of the index list
        LinkedList head; 
          
        // constructor
        public TrieNode() 
        {
            isEnd = false;
            head = new LinkedList<>();
            for (int i = 0; i < NO_OF_CHARS; ++i)
                child[i] = null;
        }
    }
       
    // A utility function to insert a word to Trie
    static TrieNode insert(TrieNode root,String word,
                                int index, int i)
    {
        // Base case
        if (root == null)
        {
            root = new TrieNode();
        }
          
        if (i < word.length() )
        {
            int index1 = word.charAt(i) - 'a';
            root.child[index1] = insert(root.child[index1],
                                       word, index, i+1 );
        }
        else  // If end of the word reached
        {
            // Insert index of this word to end of
            // index linked list
            if (root.isEnd == true)
            {
                root.head.add(index);
            }
            else // If Index list is empty
            {
                root.isEnd = true;
                root.head.add(index);
            }
        }
        return root;
    }
  
    // This function traverses the built trie. When a leaf 
    // node is reached, all words connected at that leaf 
    // node are anagrams. So it traverses the list at leaf  
    // node and uses stored index to print original words
    static void printAnagramsUtil(TrieNode root, 
                                      String wordArr[])
    {
        if (root == null)
            return;
       
        // If a lead node is reached, print all anagrams
        // using the indexes stored in index linked list
        if (root.isEnd)
        {
            // traverse the list
            for(Integer pCrawl: root.head)
                System.out.println(wordArr[pCrawl]);
        }
       
        for (int i = 0; i < NO_OF_CHARS; ++i)
            printAnagramsUtil(root.child[i], wordArr);
    }
       
    // The main function that prints all anagrams together. 
    // wordArr[] is input sequence of words.
    static void printAnagramsTogether(String wordArr[], 
                                               int size)
    {
        // Create an empty Trie
        TrieNode root = null;
       
        // Iterate through all input words
        for (int i = 0; i < size; ++i)
        {
            // Create a buffer for this word and copy the
            // word to buffer
            char[] buffer = wordArr[i].toCharArray();
             
            // Sort the buffer
            Arrays.sort(buffer);
       
            // Insert the sorted buffer and its original
            // index to Trie
            root = insert(root, new String(buffer), i, 0);
              
        }
          
        // Traverse the built Trie and print all anagrms
        // together
        printAnagramsUtil(root, wordArr);
    }
       
    // Driver program to test above functions
    public static void main(String args[])
    {
        String wordArr[] = {"cat", "dog", "tac", "god",
                                        "act", "gdo"};
        int size = wordArr.length;
        printAnagramsTogether(wordArr, size);
    }
}
// This code is contributed by Sumit Ghosh


C#
// An efficient C# program to print all 
// anagrams together 
using System;
using System.Collections.Generic; 
  
class GFG 
{ 
    static readonly int NO_OF_CHARS = 26; 
      
    // Class to represent a Trie Node 
    public class TrieNode 
    { 
        // indicates end of word 
        public bool isEnd; 
          
        // 26 slots each for 'a' to 'z' 
        public TrieNode[] child = new TrieNode[NO_OF_CHARS]; 
          
        // head of the index list 
        public List head; 
          
        // constructor 
        public TrieNode() 
        { 
            isEnd = false; 
            head = new List(); 
            for (int i = 0; i < NO_OF_CHARS; ++i) 
                child[i] = null; 
        } 
    } 
      
    // A utility function to insert a word to Trie 
    static TrieNode insert(TrieNode root,String word, 
                                int index, int i) 
    { 
        // Base case 
        if (root == null) 
        { 
            root = new TrieNode(); 
        } 
          
        if (i < word.Length ) 
        { 
            int index1 = word[i] - 'a'; 
            root.child[index1] = insert(root.child[index1], 
                                    word, index, i + 1 ); 
        } 
          
        // If end of the word reached 
        else 
        { 
            // Insert index of this word to end of 
            // index linked list 
            if (root.isEnd == true) 
            { 
                root.head.Add(index); 
            } 
              
            // If Index list is empty 
            else 
            { 
                root.isEnd = true; 
                root.head.Add(index); 
            } 
        } 
        return root; 
    } 
  
    // This function traverses the built trie. 
    // When a leaf node is reached, all words
    // connected at that leaf node are anagrams. 
    // So it traverses the list at leaf node
    // and uses stored index to print original words 
    static void printAnagramsUtil(TrieNode root, 
                                    String []wordArr) 
    { 
        if (root == null) 
            return; 
      
        // If a lead node is reached, 
        // print all anagrams using the
        // indexes stored in index linked list 
        if (root.isEnd) 
        { 
            // traverse the list 
            foreach(int pCrawl in root.head) 
                Console.WriteLine(wordArr[pCrawl]); 
        } 
      
        for (int i = 0; i < NO_OF_CHARS; ++i) 
            printAnagramsUtil(root.child[i], wordArr); 
    } 
      
    // The main function that prints 
    // all anagrams together. wordArr[]
    // is input sequence of words. 
    static void printAnagramsTogether(String []wordArr, 
                                            int size) 
    { 
        // Create an empty Trie 
        TrieNode root = null; 
      
        // Iterate through all input words 
        for (int i = 0; i < size; ++i) 
        { 
            // Create a buffer for this word  
            // and copy the word to buffer 
            char[] buffer = wordArr[i].ToCharArray(); 
              
            // Sort the buffer 
            Array.Sort(buffer); 
      
            // Insert the sorted buffer and  
            // its original index to Trie 
            root = insert(root, new String(buffer), i, 0); 
              
        } 
          
        // Traverse the built Trie and  
        // print all anagrms together 
        printAnagramsUtil(root, wordArr); 
    } 
      
    // Driver code 
    public static void Main(String []args) 
    { 
        String []wordArr = {"cat", "dog", "tac", "god", 
                                        "act", "gdo"}; 
        int size = wordArr.Length; 
        printAnagramsTogether(wordArr, size); 
    } 
} 
  
// This code is contributed by 29AjayKumar


输出:

cat
tac
act
dog
god
gdo