zoukankan      html  css  js  c++  java
  • 从字符串中查找字符出现次数的方法和性能对比

    < DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd>
    今天在一场“特殊的讨论”中引入了一个问题,如何在C#求出字符串中某字符的出现次数,比如求“ADSFGEHERGASDF”中“A”出现的次数。首先想到的方法当然是从头遍历字符串并统计:

    c1 = 0;
    for (int i = 0; i < str.Length; i++)
    {
        if (str[i] == 'A')
         {
             c1++;
         }
    }

    第二种方法也很容易想到,将字符串中所有要查找的字符去除,然后比较去除前后的字符串长度即可。这种方法遭到了某人的鄙视,据说性能很差而且多占空间。

    c2 = str.Length - str.Replace("A", String.Empty).Length;

    接下来某人又提出了第三种方法,是用要查找的字符为分隔符,将原字符串分隔为多个子串,然后求子串的数目即可。在C#中这是一个写起来很短的方法:

    c3 = str.Split(new char[] { 'A' }).Length - 1;

    我们从原理可以推断出三者性能的顺序,但究竟差距是多少呢,还是要动手试验一下。这是非常经典的测试代码:

    string str = "SADTHDGSAFSDGTGHRDGSADFADDRHDFSGASDAA";

    Stopwatch sw = new Stopwatch();

    long t;
    int c = 0;
    GC.Collect();
    Application.DoEvents();

    sw.Start();

    for (int i = 0; i < 100000; i++)
    {
         c = 三种算法
    }

    sw.Stop();

    t = sw.ElapsedMilliseconds;

    首先我们确保正确性,经测试三种方法都能正确处理多种情况,包括首尾、连续出现、不出现或串长度为0等,我所取的字符串是一个很普通的串。编译为Release版,预运行10次后获得以下结果:

    遍历统计:13毫秒
    替换后比较长度:112毫秒
    断开字符串后计数:233毫秒

    这里已经体现出差异,遍历统计比替换后比较要快10倍,断开字符串又要慢一些。接下来我又做了如下两个测试:

    1、不改变字符串的长度,增加或减少要查找字符串的个数。
    2、不改变要查找字符出现的频率,但增长字符串的长度。

    结果发现,三种方法都随字符串长度增加线性变慢,而后两种方法还随要查找的字符增加而变慢。断开字符串的方法还受要查找字符串分布情况的影响。

    研究Replace函数和Split函数的实现可以彻底解决这个问题。不过我没有心情细细研究了,我还是决定选用第二种方法----替换后比较长度。虽然其速度比第一种方法慢,但易于改写为求长度不为1的子串出现次数的方法。第一种方法若改为求长度大于1的字串就要考虑很多因素(尽管不一定真的很麻烦)!

  • 相关阅读:
    Windows Server 2012 R2 里面如何安装Net Framework 3.5
    虚拟机网络驱动(共享文件夹)不见了的解决方案-适用于win7~win10 and Windows Server 2008~Windows Server 2012R2
    在计算机 . 上没有找到服务 WAS
    免费获取WP之类的开发者权限或免费使用Azure 2015-10-19
    颠覆你的认知,带你领略史上最为齐全的微软黑科技之旅
    【技巧】只利用 Visual Stdio 自带的工具这么找父类?
    网站定位之---根据IP获得区域
    06.移动先行之谁主沉浮----我的代码我来写(Xaml的优势)
    05.移动先行之谁主沉浮----小应用的美化
    04.移动先行之谁主沉浮----XAML的探索
  • 原文地址:https://www.cnblogs.com/netcorner/p/2912325.html
Copyright © 2011-2022 走看看