我在 c++ 中使用 pop_back() 有问题

I'm having a problem with pop_back() in c++

提问人:rafiafnaanf 提问时间:10/27/2023 最后编辑:Remy Lebeaurafiafnaanf 更新时间:10/28/2023 访问量:93

问:

我正在尝试用 C++ 编写一个程序,该程序可以交换句子的人声(通过反转它)。

#include <iostream>
#include <string>
#include <vector>

int main() {
    // declare the variables
    std::string text;
    char vocals[] = {'a', 'i', 'u', 'e', 'o', 'A', 'I', 'U', 'E', 'O'};

    // get the input
    std::cout << "input the text: ";
    std::getline(std::cin, text);

    // declare the vector to store the vocals
    std::vector<char> v(text.length());

    // identify the vocals
    for (int i = 0; i < text.length(); i++) {
        for (int j = 0; j < 10; j++) {
            if (text[i] == vocals[j]) {
                v.push_back(text[i]);
            }
        }
    }

    // swap the vocals
    for (int i = 0; i < text.length(); i++) {
        for (int j = 0; j < 10; j++) {
            if (text[i] == vocals[j]) {
                text[i] = v.back();
                v.pop_back();
            }
        } 
    }

    // print the result
    std::cout << "the new text is: " << text << std::endl;

    return 0;
}

问题是,当我输入时,它会输出。"vocal switch test run""vucil swatch tst rn"

我通过在最后一个循环中打印来调试代码,所有的人声都存在于向量中。text[i]for

C++ char stdvector 回推

评论

1赞 Sam Varshavchik 10/27/2023
std::vector<char> v(text.length());不做你认为它做的事情。您是否尝试使用调试器一次一个步骤地运行此程序,并监视所有变量和对象的实际值?如果你这样做了,所显示代码的问题将非常明显。您知道如何使用调试器吗?
2赞 273K 10/27/2023
它输出“Vucil Swatch tst rn”而不是 TIA 什么是 TIA,您为什么期望它?
0赞 rafiafnaanf 10/27/2023
TIA 我的意思是提前致谢。我想我应该在那里放一个逗号什么的
0赞 Jarod42 10/27/2023
之后丢失(否则您可能会在同一位置多次替换字母)。break;v.pop_back();

答:

1赞 Chris 10/27/2023 #1

正如评论中所指出的,您在每个循环中都缺少一个。添加这些中断意味着对于字符串中作为元音的每个字符,我们一次只从向量中添加(或在第二个循环中)减去一个字符。break

#include <iostream>
#include <string>
#include <vector>

int main() {
    // declare the variables
    std::string text;
    char vocals[] = {'a', 'i', 'u', 'e', 'o', 'A', 'I', 'U', 'E', 'O'};

    // get the input
    std::cout << "input the text: ";
    std::getline(std::cin, text);

    // declare the vector to store the vocals
    std::vector<char> v(text.length());

    // identify the vocals
    for (int i = 0; i < text.length(); i++) {
        for (int j = 0; j < 10; j++) {
            if (text[i] == vocals[j]) {
                v.push_back(text[i]);
                break;
            }
        }
    }

    // swap the vocals
    for (int i = 0; i < text.length(); i++) {
        for (int j = 0; j < 10; j++) {
            if (text[i] == vocals[j]) {
                text[i] = v.back();
                v.pop_back();
                break;
            }
        }
    }

    // print the result
    std::cout << "the new text is: " << text << std::endl;

    return 0;
}
$ ./a.out
input the text:  vocal switch test run
the new text is:  vucel switch tast ron

为了更好地利用 STL,我可能会使用利用 和 以及基于范围的 for 循环的函数编写以下内容。is_vowelstd::set<char>std::copy_if

#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

bool is_vowel(char ch) {
    static std::set<char> vowels {
        'a', 'e', 'i', 'o', 'u',
        'A', 'E', 'I', 'O', 'U'
    };

    return vowels.find(ch) != vowels.end();
}

int main() {
    std::string text;
    std::vector<char> v;

    std::getline(std::cin, text);
    std::copy_if(
        text.cbegin(), text.cend(),
        std::back_inserter(v),
        is_vowel
    );

    for (auto &ch : text) {
        if (is_vowel(ch)) {
            ch = v.back();
            v.pop_back();
        }
    }

    std::cout << text << std::endl;
}
0赞 zdf 10/27/2023 #2

以下是一些可能对您有所帮助的观察结果。

(1) 您可以使用查找表查找元音。这是一个快速解决方案:

// vowels lookup table - all false except for vowels
bool v[256]{};
v['a'] = v['e'] = v['i'] = v['o'] = v['u'] =
v['A'] = v['E'] = v['I'] = v['O'] = v['U'] = true;

(2)使用两个索引反转字符串:一个从左向右移动,一个从右向左移动。与这些索引关联的字符将被交换。您可以使用相同的原则,但您必须跳过辅音。

// look for the next vowel from left to right
while (i < j && !v[s[i]]) ++i; 

// look for the next vowel from right to left
while (i < j && !v[s[j]]) --j; 

(3)一旦你考虑了左边和右边,你就停下来了。

// if the left side and the right side were already considered, exit the loop
if (i >= j) 
  break;