2012-11-04 42 views
0

如何在算术分析器从中缀转换为后缀表示法中改进存储函数的数据结构?在一个结构中存储函数和运算符的C++

在这一刻我使用的字符数组的数组:

char *funct[] = { "sin", "cos", "tan"... } 
char text[] = "tan"; 

这impementation是有点混乱,导致了以下comparisions,如果我们测试的字符是一个函数

if (strcmp (funct[0], text) == 0) || (strcmp (funct[1], "text) == 0) || (strcmp (func[2], text) == 0)) 
{ 
    ... do something 
} 

(或for循环版本)。

如果有很多功能(和大量的比较),索引引用导致错误,并且不清楚。当我们删除/添加一个新功能时,还有必要更改索引...

如何改进这样的结构以便易于阅读,易于维护和易于扩展?

我在想枚举

​​

其结果

if (strcmp (funct[Fsin], text) == 0) || (strcmp (funct[Fcos], "text) == 0) || (strcmp (func[Ftan], text) == 0)) 
{ 
... 

,但有可能是一个更好的解决办法...

+0

你写C或C++代码?您已将问题标记为C++,但您发布的代码是C,而不是C++。这也不是很清楚你想通过比较来达到什么目的。 –

+0

你可以使用'std :: string'的'std :: array'或'std :: vector'并使用'std :: find'。 – chris

+0

第二个例子是否正确?如果你使用一个枚举,你可以使用一个直接的'switch'来完成特定于操作符的处理。 – Lindydancer

回答

1

您可以使用std ::地图。

enum functions 
{ 
    sin, 
    cos, 
    tan 
}; 

std::map<std::string, unsigned char> func_map; 
func_map["sin"] = sin; 
func_map["cos"] = cos; 
func_map["tan"] = tan; 

// then: 
std::string text = "cos"; 

std::map<char*, unsigned char>::iterator it; 
it = func_map.find(text); 

if(it != func_map.end()) 
{ 
    // ELEMENT FOUND 
    unsigned char func_id = it->second; 
} 
else 
{ 
    // NOT FOUND 
} 
+1

将原始char *(或任何类型的指针)存储到std :: map或任何其他std容器中并不是一个好主意(把它放在适当的位置)。已经有很好的文件证明,它们不能很好地与原始指针一起玩,也不打算。在上面的例子中,find()函数将比较指向字符串的指针而不是指向的字符串值,这不会给你期望的结果。我会用std :: string来替换这个键,这将解决这个问题。 –

+0

@TimoGeusch你是对的。 – micnyk

0

为了达到最快的代码,你可能有一些样图如下:

typedef std::map<std::string, func_t> func_map; 
func_map fm; 
fm["sin"] = sin_func(); // get value of this entry from somewhere 
fm["cos"] = cos_func(); // for example sin_func or cos_func 

auto i = fm.find("sin"); 
if(i != fm.end()) { 
    func_t f = i->second; // value found, we may use it. 
} 

另外,如果真的是有很多的项目,你可以使用std::unordered_map代替std::map

相关问题