C++相当于Python的"if x in [string1, string2, …]"
C++ equivalent to Python's "if x in [string1, string2, …]"
我的小项目是做一个聊天机器人;我没有谷歌过开源,也没有研究过如何构建。我试着这样做,看看我对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::list
和std::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";
}
}