如何在两个元音相邻时省略字符串更改

huangapple go评论72阅读模式
英文:

How to omit string change when two vowels are next to eachother

问题

我正在尝试编写一段代码,通过在英语单词中的每个元音前添加“opp”来使用Oppengloppish语言。这是我目前编写的代码,但有一个问题:

#include <iostream>
#include <string>
#include <algorithm>

bool is_vowel(char c)
{
    return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
using namespace std;
int main()
{
    const string vowel_postfix = "opp"
    string word, oword;
    cin >> word;
    auto vowel_count = count_if(word.begin(), word.end(), is_vowel);
    oword.reserve(word.length() + vowel_count * 2);
    for (char c : word) {
        oword.push_back(c);
        if (is_vowel(c))
            oword.insert(oword.length() -1, vowel_postfix);
    }
    cout << oword << std::endl;
}

我想尝试在存在元音字母分组时避免添加“opp”,而只添加到第一个元音字母。

例如:score-> scopporoppe

期望行为:team-> toppeam
当前行为:team-> toppeoppam

英文:

I am trying to write a code that makes use of the language Oppengloppish by adding "opp" before each vowel in an English word. This is the code that I currently have written but I am having trouble with one thing:

#include <iostream>
#include <string>
#include <algorithm>

bool is_vowel(char c)
{
    return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
using namespace std;
int main()
{
    const string vowel_postfix = "opp";
    string word, oword;
    cin >> word;
    auto vowel_count = count_if(word.begin(), word.end(), is_vowel);
    oword.reserve(word.length() + vowel_count * 2);
    for (char c : word) {
        oword.push_back(c);
        if (is_vowel(c))
            oword.insert(oword.length() -1, vowel_postfix);
    }
    cout << oword << std::endl;
}

I would like to try to omit "opp" from being added when there is a grouping of vowels but still have it added to only the first vowel.

Example: score-> scopporoppe

Expected behavior: team-> toppeam
Current behavior: team-> toppeoppam

答案1

得分: 1

在哪里添加单词并不清楚(在元音字母组中的第一个元音字母之前还是之后)。无论如何,您要寻找的是从辅音到元音的过渡。您需要记住前一个字母,并检查它是否是辅音以及当前字母是否是元音。以下代码在第一个元音字母之前添加单词(演示):

char prev = 'b'; // 必须初始化为任意辅音,否则如果第一个字母是元音,它将不会被检测到。
for (char c : word)
{
  if (!is_vowel(prev) && is_vowel(c))
    oword += "opp"; // 检测到过渡
  oword += prev = c;
}

另一个不太直观的解决方案是测试添加到输出单词的最后一个字母:

for (char c : word)
{
  if (is_vowel(c) && (oword.empty() || !is_vowel(oword.back())))
    oword += "opp";
  oword += c;
}

请注意,您还应该测试大写字母。

英文:

It is not clear where you want to add the word (before or after the first vowel in the vowels group). In any case, what you are looking for is the transition from a consonant to a vowel. You need to remember the previous letter and see if it is a consonant and if the current letter is a vowel. The following code adds the word before the first vowel (demo):

char prev = 'b'; // must be initialized to an arbitrary consonant, otherwise if the first letter is a vowel, it won't be detected.
for (char c : word)
{
  if (!is_vowel(prev) && is_vowel(c))
    oword += "opp"; // transition detected
  oword += prev = c;
}

A less intuitive solution would be to test the last letter added to the output word:

for (char c : word)
{
  if (is_vowel(c) && (oword.empty() || !is_vowel(oword.back())))
    oword += "opp";
  oword += c;
}

Note that you should also test capital letters.

答案2

得分: 0

你可以:

  • 遍历输入字符串。
  • 在遍历过程中创建一个输出字符串。
  • 维护前一个字符是否是元音字母的计数。
  • 如果前一个字符不是元音字母,而当前字符是,将“oop”添加到输出字符串中。
  • 始终将当前字符添加到输出字符串中。

[演示]

#include <fmt/core.h>
#include <string>
#include <string_view>

std::string insert_opp(std::string_view text) {
    auto is_vowel = [](char c) {
        static std::string_view vowels{ "aeiouAEIOU" };
        return vowels.contains(c);
    };
    std::string ret{};
    bool is_vowel_previous_c{ false };
    for (auto c : text) {
        auto is_vowel_c{ is_vowel(c) };
        if (!is_vowel_previous_c && is_vowel_c) {
            ret += "oop";
        }
        ret += c;
        is_vowel_previous_c = is_vowel_c;
    }
    return ret;
}

int main() {
    for (auto& text : { "team", "score", "aeiou", "" }) {
        fmt::print("'{}' -> '{}'\n", text, insert_opp(text));
    }
}

// 输出:
//
// 'team' -> 'toopeam'
// 'score' -> 'scooporoope'
// 'aeiou' -> 'oopaeiou'
// '' -> ''
英文:

You could:

  • walk the input string.
  • creating an output string along the way.
  • keeping count if the previous character was a vowel or not.
  • in case the previous character was not a vowel, and the current one is, add oop to the output string.
  • always add the current character to the output string.

[Demo]

#include <fmt/core.h>
#include <string>
#include <string_view>

std::string insert_opp(std::string_view text) {
    auto is_vowel = [](char c) {
        static std::string_view vowels{ "aeiouAEIOU" };
        return vowels.contains(c);
    };
    std::string ret{};
    bool is_vowel_previous_c{ false };
    for (auto c : text) {
        auto is_vowel_c{ is_vowel(c) };
        if (!is_vowel_previous_c && is_vowel_c) {
            ret += "oop";
        }
        ret += c;
        is_vowel_previous_c = is_vowel_c;
    }
    return ret;
}

int main() {
    for (auto& text : { "team", "score", "aeiou", "" }) {
        fmt::print("'{}' -> '{}'\n", text, insert_opp(text));
    }
}

// Outputs:
//
// 'team' -> 'toopeam'
// 'score' -> 'scooporoope'
// 'aeiou' -> 'oopaeiou'
// '' -> ''

答案3

得分: 0

这个问题可以通过正则表达式替换轻松解决。首先创建一个捕获1个或多个连续元音字母的正则表达式:

std::regex vowels{"([aeiou]+)"};

然后将所有出现此模式的地方替换为 opp 后跟模式本身(模式由 $1 表示):

auto oword = std::regex_replace(word, vowels, "opp$1");

这里是一个演示

英文:

This problem can easily be solved using a regex replacement. First create a regex that captures 1 or more consecutive vowels:

std::regex vowels{"([aeiou]+)"};

and then replace all occurrences of this pattern with "opp" followed by the pattern itself (which is denoted by $1):

auto oword = std::regex_replace(word, vowels, "opp$1");

Here's a demo.

huangapple
  • 本文由 发表于 2023年2月7日 01:41:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75364756.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定