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
Find the starting indices of the substrings in string (S) which is made by concatenating all words from a list(L) in C++
Suppose we have a string, s, and we have another list with few words, these words are of same length. We have to find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
So if the input is like “wordgoodgoodgoodword” and words are ["word","good"], then the output will be [0,12]. This is because the substring starting at index 0 and 12 are “wordgood” and “goodword”.
To solve this, we will follow these steps −
Define a method called ok(), this will take string s, map wordCnt and n −
make a copy of s into temp
-
for i in range n to size of s – 1
-
if size of temp is multiple of 0, then
if when temp is not present in wordCnt, then return false
-
otherwise
if wordCnt[temp] is 1, then delete temp from wordCnt, set temp as an empty string
otherwise decrease the value of wordCnt[temp] by 1, set temp as empty string.
increase temp by s[i]
-
if temp is not in wordCnt, then return false
-
otherwise
if wordCnt[temp] is 1, then delete temp from wordCnt, set temp as an empty string
otherwise decrease the value of wordCnt[temp] by 1, set temp as empty string.
return true when size of wordCnt is 0
From the main method, do this
if size of a is 0, or size of b is 0, then return empty array
make a map wordCnt, store the frequency of strings present in b into wordCnt
make an array called ans
window := number of words x number of characters in each word
make one copy of string a into temp
-
for i in range window to size of a – 1
-
if temp size is divisible by window and call ok(temp, wordCnt, size of b[0]), then
insert i – window into ans
insert a[i] into temp
if size of temp > window, then delete substring from 0, 1
-
-
if temp size is divisible by window and call ok(temp, wordCnt, size of b[0]), then
insert size of a – window into ans
return ans
Example (C++)
Let us see the following implementation to get better understanding −
#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;
}
class Solution {
public:
bool ok(string s, unordered_map <string, int> wordCnt, int n){
string temp = "";
for(int i = 0; i < n; i++){
temp += s[i];
}
for(int i = n; i < s.size(); i++){
if(temp.size() % n == 0){
if(wordCnt.find(temp) == wordCnt.end())return false;
else{
if(wordCnt[temp] == 1){
wordCnt.erase(temp);
temp = "";
} else {
wordCnt[temp]--;
temp = "";
}
}
}
temp += s[i];
}
if(wordCnt.find(temp) == wordCnt.end())return false;
else{
if(wordCnt[temp] == 1){
wordCnt.erase(temp);
temp = "";
} else {
wordCnt[temp]--;
temp = "";
}
}
return wordCnt.size() == 0;
}
vector<int>findSubstring(string a, vector<string> &b) {
if(a.size() == 0 || b.size() == 0)return {};
unordered_map <string, int> wordCnt;
for(int i = 0; i < b.size(); i++)wordCnt[b[i]]++;
vector <int> ans;
int window = b.size() * b[0].size();
string temp ="";
for(int i = 0; i < window; i++)temp += a[i];
for(int i = window; i < a.size(); i++){
if(temp.size() % window == 0 && ok(temp, wordCnt, b[0].size())){
ans.push_back(i - window);
}
temp += a[i];
if(temp.size() > window)temp.erase(0, 1);
}
if(temp .size() % window ==0 && ok(temp, wordCnt, b[0].size()))ans.push_back(a.size() - window);
return ans;
}
};
main(){
vector<string> v = {"word","good"};
Solution ob;
print_vector(ob.findSubstring("wordgoodgoodgoodword", v));
}
Input
“wordgoodgoodgoodword”, {"word","good"}
Output
[0, 12, ]