【问题标题】:Most efficeint way to see if variable is equal to any of these strings查看变量是否等于这些字符串中的任何一个的最有效方法
【发布时间】:2011-11-04 14:23:39
【问题描述】:

我有一个包含五个字符串的列表。我想看看传入的变量是否等于这五个字符串中的任何一个。有没有比 if/else 或 case 语句更好的方法?

【问题讨论】:

  • 五个字符串的列表是什么意思?您实际上有包含这五个字符串的List<string>string[],还是只有五个硬编码字符串等?
  • 您建议case 的事实反过来表明这五个字符串是常量。如果这是真的,请不要费心“优雅”——只需使用case
  • @AakashM:我完全同意。
  • 不是重复的。他正在寻找比较字符串的最快方法,而不是是否使用 if/else 语句来这样做。他举了一个例子,说明他已经知道该怎么做。如果有的话,它是 stackoverflow.com/questions/1051276/… 的副本,但我也不是 100% 确定这一点

标签: c#


【解决方案1】:

假设我明白你的意思,这是一个丑陋但易于理解的方法,我们将字符串放入一个列表中:

var data = new List<string>();
// add some:

data.Add("Stack");
data.Add("Overflow");
data.Add("Is");
data.Add("Awesome");

string test = "Stack";

// does our list contain our test?
bool found = data.Contains(test);

【讨论】:

  • 我相信 HashSet 作为辅助结构更高效,因为 Contains() 方法可以使用恒定时间算法(哈希函数)而不是链表扫描。
【解决方案2】:

我相信使用 HashSet 效率更高!

使用如下所示的测试程序,我得到以下结果:

上架时间:558 哈希时间:150

上架时间:150 哈希时间:7

上架时间:138 哈希时间:7

上架时间:138 哈希时间:7

上架时间:142 哈希时间:3

上架时间:138 哈希时间:3

上架时间:142 哈希时间:3

上架时间:142 哈希时间:3

上架时间:138 哈希时间:7

上架时间:223 哈希时间:7

是的,这可能是列表的最坏情况,因为我的测试正在寻找序列中的最后一个条目,但它说明了这一点。 Contains() 必须线性搜索整个链表(即 List 是什么),即 O(n),其中 HashSet 使用哈希函数来查找键,这是一个常数时间操作O(1)

这是我的测试程序:

static void Main(string[] args)
{
    var list = new List<string>();
    var hash = new HashSet<string>();

    for (int i = 0; i < 1000; i++)
    {
        list.Add(i.ToString());
        hash.Add(i.ToString());
    }

    Stopwatch sw = new Stopwatch();

    for (int j = 0; j < 10; j++)
    {
        sw.Start();
        bool isFound1 = list.Contains("999");
        sw.Stop();
        var time1 = sw.Elapsed;
        sw.Reset();

        sw.Start();
        bool isFound2 = hash.Contains("999");
        sw.Stop();
        var time2 = sw.Elapsed;
        sw.Reset();

        Console.WriteLine("list time: " + time1.Ticks);
        Console.WriteLine("hash time: " + time2.Ticks);
        Console.WriteLine();
    }
}

【讨论】:

    【解决方案3】:

    假设传递的变量也是一个字符串,您可能需要查看this 问题。只需将您的五个字符串放入string[](或List,或任何实现IEnumerable 的东西)并调用IEnumerable&lt;string&gt;.Contains 以查看它是否等于字符串中的任何 . (请注意,这不会告诉您它等于哪个字符串,但因为您实际上并没有要求...)

    【讨论】:

    • Michael,如果没有其他方法,那会比其他方法更有效吗?如果以什么方式有效?比如代码谎言的数量等等。
    • 嗯,它仍然是一个 if 语句,但它在运行时间、内存等方面更短 [ if (arr.Contains("test")) {...} ] - 这是一个框架方法,所以我不知道。 @cschooley 链接了一篇关于性能的文章,在他的回答中包含了这种方法。
    【解决方案4】:
    猜你喜欢
    • 2017-03-23
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2012-09-28
    • 1970-01-01
    • 2013-03-24
    相关资源
    最近更新 更多