Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Word Squares in C++
Suppose we have a set of words (all are unique), we have to find all word squares and we can build from them. Here a sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < maximum of numRows and numColumns. So as an example, the word sequence ["ball","area","lead","lady"] will construct a word square because each word reads the same both horizontally and vertically.
| b | a | l | l |
| a | r | e | a |
| l | e | a | d |
| l | a | d | y |
So, if the input is like ["area","lead","wall","lady","ball"], then the output will be [[ "wall", "area", "lead", "lady"], ["ball", "area", "lead", "lady"]]
To solve this, we will follow these steps −
Define a node structure, there will be a variable isEnd and a list of child nodes
Define one 2D array ret
Define a function insertNode(), this will take head, s,
node := head
-
for initialize i := 0, when i < size of s, update (increase i by 1), do −
x := s[i]
-
if child array of node is empty, then −
child[x] of node := new node
node := child[x] of node
isEnd of node := true
Define a function called getAllWords, this will take idx, prefixm node and temp array
-
if node is empty, then −
return
-
if isEnd of node is true, then −
insert curr at the end of temp
return
-
if idx >= size of prefix, then −
-
for each node it in child of node −
getAllWords(idx, prefix, it.second, temp, curr + it.first)
-
-
Otherwise −
x := prefix[idx]
-
if child of node is not empty, then −
return
getAllWords(idx + 1, prefix, child[x] of node, temp, curr + x)
Define a function solve(), this will take an array temp, idx, reqSize, head,
-
if idx is same as reqSize, then −
insert temp at the end of ret
return
prefix := empty string
-
for initialize i := 0, when i < size of temp, update (increase i by 1), do −
prefix := prefix + temp[i, idx]
Define an array possible
curr = head
getAllWords(0, prefix, curr, possible)
-
for initialize i := 0, when i < size of possible, update (increase i by 1), do −
s := possible[i]
insert s at the end of temp
solve(temp, idx + 1, reqSize, head)
delete last element from temp
From the main method do the following −
head = new node
-
for initialize i := 0, when i < size of words, update (increase i by 1), do −
insertNode(head, words[i])
Define an array temp
-
for initialize i := 0, when i < size of words, update (increase i by 1), do −
s := words[i]
insert s at the end of temp
solve(temp, 1, size of words[0], head)
delete last element from temp
return ret
Example
Let us see the following implementation to get a better understanding −
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<vector<auto>> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
cout << "[";
for(int j = 0; j <v[i].size(); j++){
cout << v[i][j] << ", ";
}
cout << "],";
}
cout << "]"<<endl;
}
struct Node {
bool isEnd;
map<char, Node *> child;
};
class Solution {
public:
vector<vector<string>> ret;
void insertNode(Node *head, string &s) {
Node *node = head;
for (int i = 0; i < s.size(); i++) {
char x = s[i];
if (!node->child[x]) {
node->child[x] = new Node();
}
node = node->child[x];
}
node->isEnd = true;
}
void getAllWords(int idx, string prefix, Node *node, vector<string>&temp,
string curr = "") {
if (!node)
return;
if (node->isEnd) {
temp.push_back(curr);
return;
}
if (idx >= prefix.size()) {
for (auto &it : node->child) {
getAllWords(idx, prefix, it.second, temp, curr + it.first);
}
}
else {
char x = prefix[idx];
if (!node->child[x])
return;
getAllWords(idx + 1, prefix, node->child[x], temp, curr + x);
}
}
void solve(vector<string> &temp, int idx, int reqSize, Node *head){
if (idx == reqSize) {
ret.push_back(temp);
return;
}
string prefix = "";
for (int i = 0; i < temp.size(); i++) {
prefix += temp[i][idx];
}
vector<string> possible;
Node *curr = head;
getAllWords(0, prefix, curr, possible);
for (int i = 0; i < possible.size(); i++) {
string s = possible[i];
temp.push_back(s);
solve(temp, idx + 1, reqSize, head);
temp.pop_back();
}
}
vector<vector<string>> wordSquares(vector<string> &words) {
ret.clear();
Node *head = new Node();
for (int i = 0; i < words.size(); i++) {
insertNode(head, words[i]);
}
vector<string> temp;
for (int i = 0; i < words.size(); i++) {
string s = words[i];
temp.push_back(s);
solve(temp, 1, (int)words[0].size(), head);
temp.pop_back();
}
return ret;
}
};
main() {
Solution ob;
vector<string> v = {"area", "lead", "wall", "lady", "ball"};
print_vector(ob.wordSquares(v));
}
Input
{"area", "lead", "wall", "lady", "ball"}
Output
[[wall, area, lead, lady, ],[ball, area, lead, lady, ],]