【问题标题】:How can I parse a vector to a bool in C++?如何在 C++ 中将向量解析为布尔值?
【发布时间】:2019-10-06 06:10:57
【问题描述】:

我正在尝试编写一个程序,它首先检查名称是否在向量中,如果没有,则将其添加到向量中。我的代码似乎难以解析,至少这是我从中得到的。我尝试将字符串更改为 char,但对我没有多大帮助。

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

bool isinVector(std::string uElement, std::vector<std::string> uArray)
{
    for (unsigned int i = 0; i <= sizeof(uArray); i++) {
        if (uArray[i] == uElement) {
            return true;
        }
        else {
            return false;
        }
    }
}

int main()
{
    bool trigger = false;
    while (!trigger) {
        std::vector<std::string> names;
        names.push_back("Bart");
        std::string newName;
        getline(std::cin, newName);
        if (isinVector(newName, names))
        {
            std::cout << "true" << std::endl;
            trigger = true;
        }
        else
        {
            std::cout << "false" << std::endl;
            names.push_back(newName);
            for (int i = 0; i <= sizeof(names); i++) {
                std::cout << names[i] << std::endl;
            }
        }
    }
}

【问题讨论】:

  • 请明确您需要帮助的具体内容。这现在很模糊。
  • 请使标题与您遇到的问题相关,而不仅仅是“请帮助我”。你的代码的哪一部分出错了?请缩小范围。
  • sizeof(uArray) 没有给你uArray 的大小。请改用uArray.size()
  • sizeof 并不代表您认为的意思,您也没有看到它在任何示例中与向量一起使用。

标签: c++ string vector boolean


【解决方案1】:

我对您的代码进行了一些调整,删除了您的 isinVector 函数并在 main 函数中使用了 lambda。以后请提供一个简明的问题和例子。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::find_if;

int main(){
    bool trigger = false;
    while (!trigger) {

        vector<string> names;

        names.push_back("Bart");

        string newName;

        getline(cin, newName);

        if(find_if(names.begin(), names.end(), [newName] (const string& name){

            return !name.compare(newName);

        }) != names.end()){

            cout << "true" << endl;
            trigger = true;

        }

        else{

            cout << "false" << endl;
            names.push_back(newName);

            for (size_t i = 0; i < names.size(); i++) {

                cout << names.at(i) << endl;

            }
        }
    }

    return 0;
}

代码使用 std::find_if 检查元素是否存在于向量中。如果std::find_f 没有将迭代器返回到uArray.end() 则元素存在。此外,您的 for 循环使用了不正确的 sizeof,请使用 vector.size 方法。而且您一直循环到 &lt;= ,它应该是 &lt; uArray.size() 并且通过 .at 方法而不是索引 [] 访问向量中的元素更安全,因为 .at 会抛出 out_of_range 异常。

【讨论】:

  • 谢谢,下次我会更小心地放下我的示例代码!
  • 如果您决定将语法更改为 +11,我会在主函数中添加 lambda 表达式并编写 auto 而不是迭代器类型。 OP 可能不熟悉 +03/+11 语法,解释您的更改会对他有所帮助
  • 好的,我来调整一下。
  • “通过 .at 方法而不是索引 [] 访问向量中的元素更安全” - 当然,但是当您知道索引在范围内时, .at() 只是增加了编译器无法为您消除的不必要开销。
  • 是的@JesperJuhl,这是真的。理想情况下,如果开发人员不知道向量的边界,则不应调用 indexing 或 .at。他们应该永远知道。我可以看到一些情况,在多线程应用程序中,向量正在被更改,而开发人员在特定时间可能不知道大小。但在这种情况下,可以使用线程锁定。在单线程应用程序中,我不相信我遇到过不知道自己的向量边界的情况。
【解决方案2】:

更新帖子中的一些错误。

  1. sizeof 使用不当
  2. 重新发明标准算法
  3. 缺乏错误检查

考虑您要完成的任务。你想:

  1. 初始化包含名称 Bart 的起始向量
  2. 不断读取新名称。对于每个新名称读取:

    一个。检查它是否已经在向量中。

    • 如果存在则终止读取循环
    • 否则将其添加到向量中,并打印整个向量

这一系列操作可以通过逐步细化来完成。


第 1 步。读取名称

首先,您需要能够连续读取名称:

#include <iostream>
#include <string>

int main()
{
    std::string name;
    while (std::getline(std::cin, name))
        std::cout << name << '\n';
}

足够简单。运行此命令将回显您键入的任何字符串,一次一个,以换行符分隔。

第 2 步。在向量中累积名称

接下来,我们需要添加一个向量来保存我们正在读取的字符串,初始填充名称为“Bart”。在这个过程中,我们只是将我们读到的每个字符串放入向量中

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

int main()
{
    std::vector<std::string> names = { "Bart" };

    std::string name;
    while (std::getline(std::cin, name))
    {
        names.emplace_back(name);
        for (auto const& s : names)
            std::cout << s << ' ';
        std::cout.put('\n');
    }
}

除了之前所做的之外,我们现在还在向量中累积字符串,包括重复项,并在读取每个名称后报告向量内容。这使我们更接近我们的既定目标。

第 3 步:基于重复检测的条件循环退出

现在我们需要检查重复项,一旦发生就终止循环。我们可以使用std::find 来做到这一点。最终代码如下:

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

int main()
{
    std::vector<std::string> names = { "Bart" };

    std::string name;
    while (std::getline(std::cin, name))
    {
        if (std::find(names.begin(), names.end(), name) != names.end())
            break;

        names.emplace_back(name);
        for (auto const& s : names)
            std::cout << s << ' ';
        std::cout.put('\n');
    }
}

就是这样。这是一个简单的任务,但它非常适合作为一个示例,说明如何将多部分任务分解为可管理的目标,然后将其分块构建。

希望你觉得它有用。

【讨论】:

    【解决方案3】:

    现在我的代码如下所示:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    
    
    
    bool isinVector (std::string uElement, std::vector<std::string> uArray) {
        bool invector = false;
        std::vector<std::string>::iterator it = std::find(uArray.begin(), 
        uArray.end(),uElement);
        if(it != uArray.end()){
            invector = true;
        }
        return invector;
    }
    
    
    int main(){
        bool trigger = false;
        std::string name;
        std::vector<std::string> names = { "Bart" };
        while (std::getline(std::cin, name)){
            if (isinVector(name, names)) {
                std::cout << "true" << std::endl;
                break;
            }
            else
            {
                std::cout << "false" << std::endl;
                names.emplace_back(name);
            }
        }
        return 0;
    }
    

    它成功了,非常感谢大家!

    【讨论】:

    • 如果你想看的话,我确实对我最初发布的代码做了进一步的调整。另请查看@WhozCraig 帖子,那里也有有用的信息。
    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多