C++ 如何在1000个潜在关键字中确定一个给定的关键字?
所以我不是一个专业的开发人员,但我会定期进行编程。我想写一段代码,并寻找一些关于管理解析器的建议,解析器正在读取文本文件,将每一行视为字符串,并尝试确定该行上的输入。任何给定的行都可能是1000多个不同关键字中的一个,这是最困难的部分。一旦我有了这个关键字,我觉得必须有一种更有效的方法来确定它是什么,而不是实现1000条if-else语句或1000条case-break语句。一旦匹配了给定的关键字,我计划跳转到一个通用例程,该例程实例化该关键字类型的对象。我不想在找到目标之前进行999次测试,我觉得这只是一种浪费。我试着按字母顺序将它分解,这大大减少了它,但仍然有大量难以管理的if-else语句 我已经发现我不能嵌套超过128条if-else语句,所以我当前的替代方案是1000条只包含“if”语句而不匹配“else”语句,我知道这是一种不好的做法。下面是我当前代码的概括:C++ 如何在1000个潜在关键字中确定一个给定的关键字?,c++,performance,parsing,C++,Performance,Parsing,所以我不是一个专业的开发人员,但我会定期进行编程。我想写一段代码,并寻找一些关于管理解析器的建议,解析器正在读取文本文件,将每一行视为字符串,并尝试确定该行上的输入。任何给定的行都可能是1000多个不同关键字中的一个,这是最困难的部分。一旦我有了这个关键字,我觉得必须有一种更有效的方法来确定它是什么,而不是实现1000条if-else语句或1000条case-break语句。一旦匹配了给定的关键字,我计划跳转到一个通用例程,该例程实例化该关键字类型的对象。我不想在找到目标之前进行999次测试,我
if (keyword_str.compare(keyword1)) {
Parse(keyword1); // A general routine to parse all these similarly formatted keywords
}
if (keyword_str.compare(keyword2)) {
Parse(keyword2);
}
if (keyword_str.compare(keyword3)) {
Parse(keyword3);
}
//
//
//
if (keyword_str.compare(keyword999)) {
Parse(keyword999);
}
if (keyword_str.compare(keyword1000)) {
Parse(keyword1000);
}
任何帮助都将不胜感激!谢谢
好的,这就是我要说的重点,但仍然有点迷失在如何使用映射来确定对象类型,然后实例化该对象上。以下是一些代码片段:
class baseClass
{
public:
baseClass();
~baseClass();
};
//
// keyword1 class declaration
class keyword1 : public baseClass
{
public:
// Constructors
keyword1 () { cout << "keyword1 constructor..." << endl;}
~keyword1 () { cout << "keyword1 destructor..." << endl;}
protected:
};
//
// keyword2 class declaration
class keyword2 : public baseClass
{
public:
// Constructors
keyword2 () { cout << "keyword2 constructor..." << endl;}
~keyword2 () { cout << "keyword2 destructor..." << endl;}
protected:
};
//
// keyword3 class declaration
class keyword3 : public baseClass
{
public:
// Constructors
keyword3 () { cout << "keyword3 constructor..." << endl;}
~keyword3 () { cout << "keyword3 destructor..." << endl;}
protected:
};
//
//*******************
map <string, baseClass> keyword_map;
keyword_map.insert (make_pair ("keyword1", keyword1 )); // ########## This is where I'm lost
keyword_map.insert (make_pair ("keyword2", keyword2 )); // ########## This is where I'm lost
keyword_map.insert (make_pair ("keyword3", keyword3 )); // ########## This is where I'm lost
// Search for keyword
string searching_for = "keyword3";
map <string, baseClass> ::const_iterator it = keyword_map.find(searching_for);
if (it == keyword_map.end()) {
cout << "No keyword found." << endl;
}
else
{
cout << "Found the keyword!" << endl;
it->second; // ########## This is where I'm lost
}
类基类
{
公众:
基类();
~baseClass();
};
//
//关键字1类声明
类关键字1:公共基类
{
公众:
//建设者
关键字1(){cout
一旦匹配了给定的关键字,我计划跳转到一个通用例程,该例程实例化该关键字类型的对象
你的直觉是你不想有1000个不同的IF语句是正确的
抽象地说,我建议考虑一下旧的学校卡片目录是如何工作的(假设你见过,年轻人还知道这些是什么吗?)
卡片目录很有用,因为你不是从第一个抽屉开始,按顺序检查所有项目,然后转到下一个抽屉。相反,你可以使用一个快速测试来确定要查看哪个抽屉。这个快速测试涉及指纹或候选人的身份。旧的图书卡目录通常使用非常简单的“散列函数”(前一个或两个字母;“此抽屉包含标题以“S-Ti”开头的书籍的所有卡片)。您可以根据该测试缩小需要进行的比较的数量,以便只查看一个抽屉
如果想找到一种对字符串进行指纹识别的方法,并像这样将它们归档到桶中,听起来需要做很多工作,那么你就很幸运了。这是在标准库的保护下已经为你完成的所有工作。除非你的需求非常特殊(或者你的关键字中有奇怪的模式,它们都有相同的“指纹”)…这应该是可行的
选择一个代表关键字的std::string
键。“值”将是某种工厂……一种从关键字后面的内容创建对象的方法。这可能是“更好的方法”的基础
…但是
在初始化一个std::无序_map
进行竞价时,如果您的“值”在地图中,每一个都是为了构建不同的类,1000是大量的类。在键入class ObjectOne
并将其编号为class ObjectOne和
之前,您可能希望列出更多的细节,这听起来就像执行1000条IF语句进行比较一样有问题
因此,在继续这个想法之前,也许你应该在聊天或其他论坛上寻求更多的评论
更新以响应编辑
您的代码在关键字类是什么方面存在问题。它们是用来表示关键字类的吗(如……它们的实例化数量与关键字的实例化数量一样多?)对于只有一个实例并代表一类事物的类,应该持怀疑态度;这就是类本身的用途。如果这有意义的话:-/
因此,您希望在地图中放置的不是关键字的实例。更重要的是,您在概念上希望放置一个稍后调用的关键字类。在精神上,这类似于:
#include <typeinfo>
map <string, type_info &> keyword_map;
keyword_map.insert (make_pair ("keyword1", typeid(keyword1) ));
keyword_map.insert (make_pair ("keyword2", typeid(keyword2) ));
keyword_map.insert (make_pair ("keyword3", typeid(keyword3) ));
因为它是一个静态成员,所以它就像一个普通函数一样。你可以获取它的地址,存储指针,然后在没有任何类实例调用它的情况下调用它。它返回一个指向基类的共享指针,尽管最后只会得到指向基类的指针……它在任何virtu上都会以多态方式运行在基类的接口中定义的所有函数,根据关键字的类型而定
(请注意,在这种情况下您需要这样做!最好在默认情况下这样做,只有在您有很好的理由时才不这样做。)
map>keyword\u-map;
关键字_map.insert(生成_对(“关键字1”,“关键字1::工厂”);
关键字_map.insert(生成_对(“关键字2”,“关键字2::工厂”);
关键字_map.insert(生成_对(“关键字3”,“关键字3::工厂”);
现在,当您找到一个关键字时,调用从find
返回的函数来获取相应关键字类的实例,然后对对象实例执行您计划执行的任何操作
但是我想你会发现在这样的设计中很难在基类上定义一个让你满意的接口。这也是为什么我说1000个类表明你可能没有你想用的方法解决的问题。我还想你会有很多其他问题,但请把它们作为我的新问题帖子r-own.:-一个无序的\u映射
在这里工作得非常快。它是一个
class keyword1 : public baseClass {
// ...
static shared_ptr<baseClass> factory() {
return make_shared<keyword3>();
}
// ...
};
map <string, shared_ptr<baseClass>(*)()>> keyword_map;
keyword_map.insert (make_pair ("keyword1", &keyword1::factory ));
keyword_map.insert (make_pair ("keyword2", &keyword2::factory ));
keyword_map.insert (make_pair ("keyword3", &keyword3::factory ));
#include <iostream>
#include <unordered_map>
#include <functional>
using namespace std;
typedef unordered_map<string, function<void ()>> ufmap;
ufmap M;
int main() {
// Create Keys and functions
string s_a = "A";
function<void ()> f_a = [](){
cout << "Construct type A here" << endl;
};
string s_b = "B";
function<void ()> f_b = [](){
cout << "Construct type B here" << endl;
};
// Add Keys and functions to the map
M.insert(pair<string, function<void ()>>(s_a, f_a));
M.insert(pair<string, function<void ()>>(s_b, f_b));
// Finding a string and using its function
string searching_for = "A";
ufmap::const_iterator it = M.find(searching_for);
if (it == M.end()) {
// String key wasn't found
}
else {
it->second();
}
}