Print Strings In Reverse Dictionary Order Using Trie


Introduction

This tutorial implements an approach to printing Strings In Reverse Dictionary Order Using Trie. Trie is a data structure with a tree representation. It is in ordered form and provides an efficient approach for string retrieval. It has nodes and edges like a tree data structure. To solve the task, initialize an array and arrange strings in reverse dictionary order using the trie. Each alphabet is used as a node in the tree. Duplicate array elements are printed only once.

Demonstration 1

arr[] = {“hello", "world", "open", "ai", "c++", "programming"”}

Output

world
programming
open 
hello
c++
ai

Explanation

In the above input array, the array is traversed to print all elements in reverse order.

Demonstration 2

arr[] = {“life”, “dog”, “is”, “good”}

Output

life
good
is 
dog 

Explanation

In the above input array, all elements are traversed to print in reverse order. Use the trie concept to reverse the string and form the tree.

C++ Library Functions

Syntax

length(): It is a string class library function that returns the length of the string in byte form.

string_name.length();

vector: it is a dynamic array in C++ and is defined in the <vector> header file. It provides efficient insertion and deletion operations.

vector<data_type> vector_name;

push_back(): It is a predefined function in the <vector> header file. It inserts or pushes an element to the end of the vector array.

vector_name.push_back(value);

sort(): This C++ library function sorts an array or vector in ascending order. It takes two parameters, where the first parameter is the starting point and the second parameter is the end element of an array.

sort(first, second);

Algorithm

  • Initialize an array.

  • Use strings (array elements) to construct a trie data structure.

  • Use the first string to create the rightmost subtree, and use the second string to create the leftmost subtree. In this way, all strings can be used to form a trie.

  • Reverse the strings and print the results.

Example 1

Here we implement an approach to print all strings in reverse dictionary order using the trie. Construct a tree using the strings in a first come first served fashion. The alphabets of strings make tree nodes.

#include <bits/stdc++.h>
using namespace std;
#define CH 26
#define MAX 100
 
// structure for trie
struct trieTree {
    trieTree* children[CH];
    bool endOfString;
};
 
// Function for trie treeL
trieTree* createTrieNode(){
//creating object 
   trieTree* t = new trieTree();
 
    t->endOfString = false;
 
    for (int x = 0; x < CH; x++){
 
        // null for all child nodes of trie
        t->children[x] = NULL;
    }
    return t;
}
 
// recursively inserting string to the trie
void insertStringRecursively(trieTree* it,string s, int l){
 
    if (l < s.length()){
        int ind = s[l] - 'a';
 
        if (it->children[ind] == NULL){
 
            // Creating new node of trie
            it->children[ind] = createTrieNode();
        }
 
        // calling function recursively
        insertStringRecursively(it->children[ind], s, l + 1);
    } else {

        it->endOfString = true;
    }
}
 
// Function to insert the string to trie
void insertString(trieTree* it, string s)
{
    //calling function
    insertStringRecursively(it, s, 0);
}
 
// Function To find trie leaf node
bool isTrieLeafNode(trieTree* r){
    return r->endOfString != false;
}
 
// Function for printing the result
void printResult(trieTree* r, char s[], int a){
 
    if (isTrieLeafNode(r)){
        //null for empty string
        s[a] = '\0';
        cout << s << endl;
    }
 
    for (int x = CH - 1; x >= 0; x--){
        if (r->children[x]){
            s[a] = x + 'a';
            printResult(r->children[x], s, a + 1);
        }
    }
}
 
// function for printing the output
void displaying(trieTree* it){
    int a = 0;
 
    char s[MAX];
 
    printResult(it, s, a);
}
 
// code controller
int main(){
    trieTree* r = createTrieNode();
//calling function to insert string to the trie
    insertString(r, "this");
    insertString(r, "car");
    insertString(r, "is");
    insertString(r, "expensive");

 //calling function to print the output
    displaying(r);
 
    return 0;
}

Output

this
is
expensive
car

Example 2

In this C++ implementation, to print the string in reverse order, we use structure to represent nodes of the trie data structure. The flag isEndWord is set to true if the node represents the end of the word. Use the createNode function to create nodes of the trie. After constructing the tree, traverse all nodes to print the strings in reverse dictionary order.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// structure for trie nodes
struct NodeOfTrie{
    NodeOfTrie* child[26]; 
    bool isEndWord;        // Flag to mark the array end 
};

// Creating trie node
NodeOfTrie* createNode(){
    NodeOfTrie* newN = new NodeOfTrie;
    newN->isEndWord = false;

    for (int x = 0; x < 26; x++){
        newN->child[x] = nullptr;
    }

    return newN;
}

// Inserting strings to trie
void insertWord(NodeOfTrie* r, const string& w){
    NodeOfTrie* current = r;

    // Traversing tree 
    for (char c : w){
        int ind = c - 'a';

        // Create a new node if the path doesn't exist
        if (current->child[ind] == nullptr){
            current->child[ind] = createNode();
        }

        // Moving next node
        current = current->child[ind];
    }

    // Marking end of the array
    current->isEndWord = true;
}

// depth first search function
void depthfirstsearch(NodeOfTrie* r, string currentWord, vector<string>& output){
    if (r == nullptr){
        return;
    }

    if (r->isEndWord){
        output.push_back(currentWord);
    }

    for (int x = 25; x >= 0; x--){
        if (r->child[x] != nullptr){
            depthfirstsearch(r->child[x], currentWord + char(x + 'a'), output);
        }
    }
}

// Function for print reverse strings
void reverseOrder(vector<string>& arr) {
    // Creating trie nodes
    NodeOfTrie* r = createNode();

    // Inserting array strings to trie
    for (const string& word : arr){
        insertWord(r, word);
    }

    // Performing dfs
    vector<string> output;
    depthfirstsearch(r, "", output);

    // Sorting strings in reverse order
    sort(output.rbegin(), output.rend());

    cout << "Strings in reverse dictionary order:\n";
    for (const string& arr : output){
        cout << arr << endl;
    }

    // creating memory space
    delete r;
}

int main(){
    vector<string> arr = {"hello", "world", "open", "ai", "c++", "programming"};

    reverseOrder(arr);

    return 0;
}

Output

Strings in reverse dictionary order:
world
programming
open
hello
aic
ai

Conclusion

We have reached the end of this tutorial and solved the problem of printing the reverse dictionary string with Trie. The Trie data structure is used in this tutorial as it is an effective approach to inserting strings into a tree form. The nodes of the tree represent the alphabets of the string. Implemented the task using two approaches, where we first constructed a trie tree and iterated the nodes of the trie tree. We then printed the strings in reverse dictionary order. Before implementing the task, we demonstrated the problem with some examples to define the logic.

Updated on: 18-Aug-2023

102 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements