- Trending Categories
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
Physics
Chemistry
Biology
Mathematics
English
Economics
Psychology
Social Studies
Fashion Studies
Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Substring with Concatenation of All Words in C++
Suppose we have a string, s, and we also have a list of words, words present in the array are all of the 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 “barfoothefoobarman” and words are [“foo”, “bar”], then the output will be [0,9]. This is because the substring starting at index 0 and 9 are “barfoo” and “foobar”.
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
Let us see the following implementation to get a 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 = {"foo", "bar"}; Solution ob; print_vector(ob.findSubstring("barfoothefoobarman", v)); }
Input
1,2,3,4,5,6,7 3
Output
[0, 9, ]