检查字符串是否在静态编译时集中的最快方法是什么?

时间:2018-11-10 00:56:55

标签: string algorithm language-agnostic

我知道哈希码通常是检查动态集的最快方法,但是我想知道什么是检查动态字符串是否在编译时已知的只读字符串集中的最快方法。 (我的意思主要是{length: usize; chars: &[u8]}字符串,而不是绳索或约束字符串。)

当前,我通常在做这样的事情,但看起来好像不是很理想:

// What I mean
let keywords = Set::new(["do", "if", "in", "for", "new", "try"]);
fun is_keyword(s: &str) { keywords.contains(s) }

// What I write
function is_keyword(s: &str) {
    match s.length() {
        2 -> s == "do" || s == "if" || s == "in",
        3 -> s == "for" || s == "new" || s == "try",
        // etc.
        _ -> false
    }
}

对于C样式字符串集,有没有比第二种变体更快的东西了?还是它会尽我所能尽快达到?

这与语言无关-我不在乎答案使用什么语言。由于熟悉,我只是使用Rust。

2 个答案:

答案 0 :(得分:2)

对于静态集,可以使用完美的哈希。这本质上是一个哈希表,但是哈希函数保证集合中的每个字符串都哈希到该表中的唯一索引。

要测试动态字符串,只需使用完美的哈希函数将其哈希到索引,然后查看该索引处的唯一字符串是否与测试字符串匹配。

通过Google搜索,您会发现许多不同的方法来进行完美的哈希处理。这里描述了我的最爱之一:http://cmph.sourceforge.net/papers/chm92.pdf

它通常用于编译器中的关键字匹配,或在支持该功能的语言中对字符串执行switch / case。

答案 1 :(得分:0)

就像您说的那样,最快的方法似乎是对字符串进行哈希处理。您当前的方式将花费O(N)时间来搜索集合中最大的字符串,或者根本不寻找集合中的字符串。