I want to duplicate the vowels between two consonants in a string.
Input :
informatics
Output :
infoormaatiics
I have made an attempt below:
#include<bits/stdc .h>
#define ios ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
void solution(){
string i;
cin >> i;
int n = i.size();
string vo = "aeuio";
for(int j=1; j<n-1; j ){
if(vo.find(i[j-1]) >= i.length() && vo.find(i[j]) < i.length() && vo.find(i[j 1]) >= i.length()){
i.insert(j 1 , i[j]);
}
}
cout << i << endl;
}
int main(){
ios
int t;
cin >> t;
while(t--){
solution();
}
return 0;
}
the problem in my code is in insert because the compiler give me:
insert(size_type __pos1, const basic_string& __str,
CodePudding user response:
Here's what I'd write using a regular expression:
#include <iostream>
#include <regex>
std::string solution(std::string i){
std::regex re(
"([bcdfghjklmnpqrstvxz])"
"([aeiouy])"
"([bcdfghjklmnpqrstvxz])");
return std::regex_replace(i, re, "$1$2$2$3");
}
int main(){
for (std::string i; std::cin >> i;) {
//std::cout << i << " -> " << solution(i) << "\n";
std::cout << solution(i) << "\n";
}
}
In response to @cigien's comment:
std::string solution(std::string i)
{
std::regex re(
"([bcdfghjklmnpqrstvxz])"
"([aeiouy])"
"(?=[bcdfghjklmnpqrstvxz])");
return std::regex_replace(i, re, "$1$2$2");
}
This will also take care of cases where there are "middle consonants" that fence multiple vowels.
With random tests:
(echo informatics; sort -R /etc/dictionaries-common/words | head -9) | ./sotest
infoormaatiics
niiceest
afteereeffeect
Lamaar
poortaageed
Asuunción's
viiviiseection
opaaquer
inteerruupts
Anaabaaptiist's
Review of your code
The most prominent problem was insert
not being called with a suitable set of arguments: https://en.cppreference.com/w/cpp/string/basic_string/insert
The closest would be to use overload (3):
basic_string& insert( size_type index, const CharT* s, size_type count );
So, basically
i.insert(j 1, i.data() j, 1);
Side notes are that since i
is modified, caching size()
will lead to some matches not being processed because you abandon the loop early.
for(size_t j=1; j<i.size()-1; j ){
fixes that.
std::string vo = "aeuio";
Seems pretty inefficient. Why not use a lambda - both more expressive and more efficient:
static inline bool is_vowel(char ch) {
switch (ch) {
case 'a': case 'e': case 'u': case 'i': case 'o':
case 'A': case 'E': case 'U': case 'I': case 'O': return true;
default: return false;
}
}
And then maybe:
std::string solution(std::string input)
{
auto cons_around = [&input](int index) {
return not(is_vowel(input.at(index - 1)) //
or is_vowel(input.at(index 1)));
};
for (size_t i = 1; i < input.size() - 1; i ) {
if (cons_around(i) and is_vowel(input.at(i)))
input.insert(i 1, input.data() i, 1);
}
return input;
}
Strictly speaking, this is not satisfying the requirements (even though it now recognizes uppercase vowels) because it assumes everything non-vowel is consonant (interpunction and numeric etc. exist).
But the result is closer:
http://coliru.stacked-crooked.com/a/f9db3887705a3b4c
#include<string>
#include<iostream>
static inline bool is_vowel(char ch) {
switch (ch) {
case 'a': case 'e': case 'u': case 'i': case 'o':
case 'A': case 'E': case 'U': case 'I': case 'O': return true;
default: return false;
}
}
std::string solution(std::string input)
{
auto cons_around = [&input](int index) {
return not(is_vowel(input.at(index - 1)) //
or is_vowel(input.at(index 1)));
};
for (size_t i = 1; i < input.size() - 1; i ) {
if (cons_around(i) and is_vowel(input.at(i)))
input.insert(i 1, input.data() i, 1);
}
return input;
}
int main(){
int t;
std::cin >> t;
std::string i;
while (t-- && std::cin >> i) {
std::cout << solution(i) << "\n";
}
}
Prints
foo
baar
quux