2012-08-15 33 views
2

首先,这是为了模式匹配而设计的,因此请牢记这一点,因为它可能会有一个完全不同的解决方案,我想知道它。带有通配符的真值表(ish)

我有这一系列的数据(现在叫它mystring)。

string a = get_starting_letters(mystring) 
string b = get_ending_letters(mystring) 
bool c = check_code_appears(mystring) 
. 
. 
. 
and so on 

我想有一个像这样工作的字典/真值表(*表示通配符)。

key (a,b,c...)    value 

"abc", *, True  = "type a string" 
"abc", "xyz", True = "type b string" 
*, "xyz", True  = "type m string" 

这怎么可能在C#中实现?我知道这对F#来说很微不足道,但是这些代码将来可能会被仅知道C#的人更新。

我为什么要这样做?因为当前的代码越来越难以更新(太多嵌套if,else,else if),并且迄今为止只描述了几种“类型”(它将在几个月内加倍)。

其他的解决方案,我一直在思考:一个排序树/结构描述了由条件检查不同的可能变量:

     b = "xyz" 
      a = "abc" < 
mystring <   b = "xxx" 
      a = "cda" < 
         b = * 

然而,它似乎将有一个大的开销,速度对此很重要,另外树不会是二进制的,并且也需要处理通配符。

+0

我没有时间给出完整答案,但我建议用三个键和一个实现IList/IDictionary的值来创建自己的类。你必须重载equals和一些其他的东西,但它会在功能上处理你的情况,并且对于大多数人的需求来说足够快(特别是如果你的集合类型很少的话)。几乎总是如此:先实现,稍后优化 – Bob2Chiv 2012-08-15 22:26:06

+0

如果在F#中微不足道,请与不知道F#并使用F#的人配对。 – 2012-08-15 22:42:16

回答

1

如果你所需要的,如果能够检查给定元组是否给定类型相匹配,那么你可以只使用一个普通的字典,像

Dictionary<string, Tuple<string, string, bool>> lookup = new Dictionary<string, Tuple<string, string, bool>>(); 

//add some values 
lookup["type a string"] = new Tuple<string, string, bool>("abc", null, true); 
lookup["type b string"] = new Tuple<string, string, bool>("abc", "xyz", true); 
lookup["type m string"] = new Tuple<string, string, bool>(null, "xyz", true); 

然后,你只是仰望你的类型'重新检查匹配以查看值是否相等(或者元组中存在空值)。

如果您需要能够确定哪些类型正在与字符串匹配(并且不想迭代已知类型),那么显然这种方法不会工作......但是, d需要建立某种优先规则以及...

更新: 一种方法是使用SQL并添加一些索引(如果您不想编写自己的基于B树的索引)。是的,它是基于磁盘的,但是如果您使用了很多引用,那么表格可能会被缓存,如果您不这样做,那么就没有理由担心性能。

更简单的想法是使用有序集合。内存效率不高,但可能速度很快,取决于您的规则设置方式。您将为包含类型字符串的每个字段的每个可能值构造一个集合。例如,你会有一个集合,其中a =“abc”,它有两个成员,“键入一个字符串”和“类型b字符串”,也是一个a = *的集合,它将有一个成员,“键入m串“。

如果您试图找到与a =“abc”,b =“xxx”和c = true的字符串相匹配的值,您可以将a =“abc”和a = *集合,与b =“xxx”和b = 的联合相交,然后与c = true和c =的联合相交。然后,您将拥有一组与您的密钥相匹配的值。它会在O([a =“abc”] + [a = *] + [b =“xxx”] + [b = *] + [c = true] + [c = *])中运行。 = O(n)的

当然,它为O(n)只是遍历所有的规则来检查比赛,但是在这里我们大大减少了n的大小。