
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 Abbreviation in C++
Suppose we have an array of n unique strings, We have to generate minimal possible abbreviations for every word following rules below.
Starting with the first character and then the number of characters abbreviated, which followed by the last character.
If we find any conflict and that is more than one words share the same abbreviation, a longer prefix can be used instead of only the first character until making the map from word to abbreviation become unique.
When the abbreviation doesn't make the word shorter, then keep it as original.
So, if the input is like ["like", "god", "internal", "me", "internet", "interval", "intension", "face", "intrusion"], then the output will be
["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]
To solve this, we will follow these steps −
Define a node structure, it has cnt and an array of 26 child nodes, initially all are empty.
Define a function freeNode(), this will take head,
-
if head null, then −
return
-
for initialize i := 0, when i < 26, update (increase i by 1), do
freeNode(child[i] of head)
delete head
Define a function insertNode(), this will take node, s,
curr = node
-
for initialize i := 0, when i < size of s, update (increase i by 1), do −
x := s[i]
-
if child[x - 'a'] of node is not null, then
child[x - 'a'] of node := a new node
node := child[x - 'a'] of node
increase cnt of node by 1
Define a function abbreviate(), this will take node, s,
ret := blank string
curr = node
-
for initialize i := 0, when i < size of s, update (increase i by 1), do −
x := s[i]
curr := child[x - 'a'] of curr
-
if cnt of curr is same as 1, then −
rem := size of s
ret := (if rem <= 1, then s, otherwise substring of s from index 0 to i concatenate rem as string concatenate last element of s
Come out from the loop
return ret
Define a function wordsAbbreviation(), this will take an array dict,
n := size of dict
Define an array ret of size n
Define one mapm
-
for initialize i := 0, when i < n, update (increase i by 1), do −
word := dict[i]
rem := size of word - 2
x := (if rem <= 1, then word, otherwise first element of word concatenate rem concatenate last element of word)
insert i at the end of m[x]
ret[i] := x
-
for each key-value pair it in m, do −
-
if size of value of it is <= 1, then −
(increase it by 1)
Ignore following part, skip to the next iteration
head := a new node
-
for initialize i := 0, when i < size of value of it, update (increase i by 1), do −
idx := value[i] of it
insertNode(head, dict[idx])
-
for initialize i := 0, when i < size of value of it, update (increase i by 1), do −
idx := value[i] of it
ret[idx] := abbreviate(head, dict[idx])
freeNode(head)
(increase it by 1)
-
return ret
Let us see the following implementation to get better understanding −
Example
#include <bits/stdc++.h> using namespace std; void print_vector(vector<auto> v){ cout << "["; for(int i = 0; i<v.size(); i++){ cout << v[i] << ", "; } cout << "]"<<endl; } struct Node{ int cnt; Node* child[26]; Node(){ cnt = 0; for(int i = 0; i < 26; i++)child[i] = NULL; } }; class Solution { public: void freeNode(Node* head){ if (!head) return; for (int i = 0; i < 26; i++) { freeNode(head->child[i]); } delete head; } void insertNode(Node* node, string s){ Node* curr = node; for (int i = 0; i < s.size(); i++) { char x = s[i]; if (!node->child[x - 'a']) { node->child[x - 'a'] = new Node(); } node = node->child[x - 'a']; node->cnt++; } } string abbreviate(Node* node, string s){ string ret = ""; Node* curr = node; for (int i = 0; i < s.size(); i++) { char x = s[i]; curr = curr->child[x - 'a']; if (curr->cnt == 1) { int rem = s.size() - (i + 2); ret = rem <= 1 ? s : s.substr(0, i + 1) + to_string(rem) + s.back(); break; } } return ret; } vector<string> wordsAbbreviation(vector<string>& dict) { int n = dict.size(); vector<string> ret(n); map<string, vector<int> > m; for (int i = 0; i < n; i++) { string word = dict[i]; int rem = word.size() - 2; string x = rem <= 1 ? word : word.front() + to_string(rem) + word.back(); m[x].push_back(i); ret[i] = x; } Node* head; map<string, vector<int> >::iterator it = m.begin(); while (it != m.end()) { if (it->second.size() <= 1) { it++; continue; } head = new Node(); for (int i = 0; i < it->second.size(); i++) { int idx = it->second[i]; insertNode(head, dict[idx]); } for (int i = 0; i < it->second.size(); i++) { int idx = it->second[i]; ret[idx] = abbreviate(head, dict[idx]); } freeNode(head); it++; } return ret; } }; main(){ Solution ob; vector<string> v = {"like","god","internal","me","internet","interval","intension","face","intrusion"}; print_vector(ob.wordsAbbreviation(v)); }
Input
{"like","god","internal","me","internet","interval","intension","face","intrusion"}
Output
[l2e, god, internal, me, i6t, interval, inte4n, f2e, intr4n, ]