【问题标题】:How to duplicate the vowels between two consonants in a string?如何复制字符串中两个辅音之间的元音?
【发布时间】:2021-12-24 23:42:04
【问题描述】:

我想复制字符串中两个辅音之间的元音。

输入:

informatics

输出:

infoormaatiics

我在下面做了一个尝试:

#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;
}

我的代码中的问题在于插入,因为编译器给了我:

插入(size_type __pos1, const basic_string& __str,

【问题讨论】:

  • 您显示的代码有什么问题?如果它不起作用,请准确指出出了什么问题。
  • 将逻辑与 IO 操作分开。然后你可以写测试:godbolt.org/z/EebW6n5sP
  • 问题在于插入编译器给我:insert(size_type __pos1, const basic_string& __str,
  • 请将所有相关详细信息以edit 的形式添加到问题中,而不是作为 cmets 中的跟进。
  • 代码无法编译:godbolt.org/z/jqo9YnxfP

标签: c++ string


【解决方案1】:

这是我使用正则表达式编写的内容:

 #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";
    }
 }

回应@cigien 的评论:

std::string solution(std::string i)
{
    std::regex re(
        "([bcdfghjklmnpqrstvxz])"
        "([aeiouy])"
        "(?=[bcdfghjklmnpqrstvxz])");

    return std::regex_replace(i, re, "$1$2$2");
}

这也将处理存在多个元音的“中间辅音”的情况。

随机测试:

(echo informatics; sort -R /etc/dictionaries-common/words | head -9) | ./sotest
infoormaatiics
niiceest
afteereeffeect
Lamaar
poortaageed
Asuunción's
viiviiseection
opaaquer
inteerruupts
Anaabaaptiist's

审查您的代码

最突出的问题是 insert 没有使用合适的参数集调用:https://en.cppreference.com/w/cpp/string/basic_string/insert

最接近的是使用重载(3):

basic_string& insert( size_type index, const CharT* s, size_type count );

所以,基本上

        i.insert(j + 1, i.data() + j, 1);

附注是,由于 i 被修改,缓存 size() 将导致一些匹配未处理,因为您提前放弃了循环。

for(size_t j=1; j<i.size()-1; j++){

解决这个问题。

std::string vo = "aeuio";

似乎效率很低。为什么不使用 lambda - 更具表现力和效率:

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;
}

严格来说,这并不能满足要求(即使它现在可以识别大写元音),因为它假定所有非元音都是辅音(存在分词和数字等)。

但结果更接近:

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";
    }
}

打印

foo
baar
quux

【讨论】:

  • @cigien 够公平的。我认为要求可以更明确。此外,我们不是为 SO 帖子编写代码,我们是在诊断问题(我扩展了答案,因为它已被取消删除)
  • @cigien 也更新了正则表达式方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 2019-12-09
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 2023-03-22
  • 2018-02-10
相关资源
最近更新 更多