Home > Back-end >  How to duplicate the vowels between two consonants in a string?
How to duplicate the vowels between two consonants in a string?

Time:11-14

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
  • Related