C++相当于Python的"if x in [string1, string2, …]"

C++ equivalent to Python's "if x in [string1, string2, …]"

本文关键字:string1 string2 Python 相当于 if C++ in      更新时间:2023-10-16

我的小项目是做一个聊天机器人;我没有谷歌过开源,也没有研究过如何构建。我试着这样做,看看我对c++的理解程度:

我试图做一个"盒子"的排序,其中包含所有的"问题",可以给出,并看到"如果","问题"是"在"的"盒子",它将执行所述代码。

在Python中差不多是:

Box = ["Yes", "YES", "yes", "yEs", "YeS", "yES"]
print "Will you be working today?"
response = raw_input("> ")
if response in Box:
    print "Very well, then how can I assist you?"

那么在c++中我该怎么做呢?或者在c++中叫什么?一个数组?一个列表吗?向量?在c++中区分它们有点令人困惑。

对于这种情况,我会考虑将响应转换为所有小写,然后进行直接比较:

#include <string>
#include <cctype>
#include <functional>
#include <algorithm>
// convert string to lowercase
std::string lower_case(std::string s)
{
    std::transform(s.begin(), s.end(), s.begin()
        , std::ptr_fun<int, int>(std::tolower));
    return s;
}
int main()
{
    std::string response;
    // ask question and get response
    // now you don't need to look at every combination
    if(lower_case(response) == "yes")
    {
        // positive response code
    }
    // etc...
}

您可以这样做,需要<string>, <vector><algorithm>:

vector<string> box = { "yes"...};
//get input
if(std::find(box.begin(), box.end(), search_str) != box.end()) {
    //found
}

如果不区分大小写地接受输入,可能会更简单,表达能力更强。

std::string downcased(std::string s) {
  std::locale loc{"en_US.UTF-8"};
  std::transform(begin(s), end(s), begin(s), [&](auto const& c) {
    return std::tolower(c, loc);
  });
  return s;
}

所以你要写

if(downcased(input_string) == "yes") ...

没有"box"要处理

如果你安装了Boost,那么你可以不使用downcased()功能:

if(boost::algorithm::to_lower_copy(input_string) == "yes") ...

也就是说,c++确实有C的基本数组。这些类似于Python使用的列表,但它们是静态的,这意味着它们不会改变它们的大小,也不会将它们的大小作为数据保存在某个地方。c++在标准库中也提供了std::vector<>。这是一个模板类,表示一个动态数组,可以改变它的大小,并且在大多数情况下是自动改变的。用std::find()这样的算法就能做到这一点。例如,

std::vector<std::string> const ys = {"yes", "yEs", };  // &c
if(std::find(begin(ys), end(ys), "yeS") != end(ys))
  ...

将输入更改为小写并只测试"yes"是目前为止最简单的解决方案,但更一般的情况可以使用std::set来完成。

集合是为高速创建的有序结构,"X在这里吗?"查找。它类似于其他人建议的std::vector,但vector需要线性搜索。

#include <iostream>
#include <set>
int main()
{
    std::string input;
    std::cin >> input;
    std::set<std::string> box{"Yes", "YES", "yes", "yEs", "YeS", "yES"};
    if (box.find(input) != box.end())
    {
        std::cout << "Very well, then how can I assist you?" << std::endl;
    }
    return 0;
}

一般来说,您可以预期c++中使用数据结构的经验与Python有很大的不同。Python只有一个list类,它是大多数容器需求的首选,而c++有几个容器数据结构。c风格的数组,std::array, std::liststd::vector都是可能的。std::vector往往是普通列表的首选选项。

也就是说,如果您要做的只是反复测试集合中的成员字符串,那么您应该使用集合数据结构,而不是在列表上进行线性搜索。在c++ 11中,与Python的set类等价的是std::unordered_set(它们都被实现为哈希表)。

#include <iostream>
#include <string>
#include <unordered_set>
int main() {
  std::unordered_set<std::string> box = {"Yes", "YES", "yes"};
  std::string input;
  std::getline(std::cin, input);
  if(box.count(input)) {
    std::cout << "Very well, then how can I assist you?n";
  }
}