BrowserStack Interview Question
SDE1sCountry: India
Interview Type: Written Test
// function to expand the string
std::string expand_string(const std::string &str) {
std::string ret;
for (std::string::size_type i = 0; i < str.size(); i++) {
switch (str[i]) {
case '.':
ret += std::string(1, str[i-1]);
break;
case '+':
ret += std::string(3, str[i - 1]);
break;
case '*':
ret += std::string(4, str[i - 1]);
break;
default:
ret += str[i];
break;
}
}
return ret;
}
// iterate through the string and search for occurences of the expanded string
int count_occurences(const std::string &source, const std::string &&to_find) {
int count = 0;
std::string expanded = expand_string(to_find);
int search_size = expanded.size();
for (int i = 0; i < source.size(); i++) {
std::string sub = source.substr(i, search_size);
if (sub == expanded)
count++;
}
return count;
}
#include<iostream>
#include<string>
using namespace std;
int main() {
int tc, count = 0, j=0, i=0;
cin >> tc;
string in, regex;
cin >> in;
for(int ti=0;ti<tc;ti++) {
cin >> regex;
count = 0;
//now compare
// cout << "given regex is " << regex << endl;
for(int i1=0;i1<in.size();i1++) {
// cout << "searcihing from i1 = " << i1 << endl;
j = 0;
i = i1;
//start comparing from ith and 0th in regex until match or mismatch happens
while(i<in.size() && j < regex.size()) {
while(i<in.size() && j < regex.size() && in.at(i) == regex.at(j)) {
i++;
j++;
}
// cout << "after initial match, chars are at " << i << " " << j << endl;
if(j == regex.size()) {
// cout << "count incremented by 1 from after the initial match itself\n";
count++;
} else if(i == in.size()) {
break;
} else {
if(regex.at(j) == '.' && in.at(i) == in.at(i-1)) {
// cout << "there is a . \n";
j++;
i++;
if(j == regex.size()) {
// cout << "count incremented by 1 due to .\n";
count++;
}
}
else if(regex.at(j) == '+') {
//4 occurences
int temp = 0;
// cout << "+ with = " << i << endl;
while(i<in.size() && temp < 3 && in.at(i) == in.at(i-1)) {
i++;
temp++;
}
if(temp == 3) {
} else {
//mismatch
break;
}
j++;
if(j == regex.size()) {
// cout << "count incremented by 1 after +\n";
count++;
}
} else if(regex.at(j) == '*') {
//>5 occurences
//now if the next char of regex is the same as previous then the min occ should be incremented
int min_occ = 4;
j++;
while(j<regex.size() && regex.at(j) == regex.at(j-2)) {
switch(regex.at(j+1)) {
case '+':
min_occ += 4;
j+=2;
break;
case '.':
min_occ += 2;
j+=2;
break;
case '*':
min_occ += 5;
j+=2;
break;
default:
//another character
j+=1;
}
//j+=2;
}
//we need to ensure atleast that many occurences of in.at(i)
int k = 0;
for(k=0;k<min_occ;k++) {
if(i<in.size() && in.at(i) == in.at(i-1))
i++;
else
break;
}
if(k == min_occ) {
} else
break;
//now gotill end
while(i<in.size() && in.at(i) == in.at(i-1))
i++;
if(j == regex.size()) {
// cout << "count incremented by 1 after *\n";
count++;
}
} else {
//mismatch
break;
}
}
}
}
cout << count << endl;
}
return 0;
}
I think this should work. But I suppose there should be a neater way to do this.
Here the expansion of * could to any number of characters but the above code does it only for 5 chars. Correct me in case I am wrong.
- anon October 21, 2014