在c ++中从字符串中删除标点符号的最有效方法

时间:2016-08-01 23:12:00

标签: c++ string visual-studio strlen

我正在尝试找到从c ++中删除字符串中标点符号的最有效方法,这就是我目前所拥有的。

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <algorithm>

using namespace std;

void PARSE(string a);

int main()
{
    string f;
    PARSE(f);
    cout << f;
}

void PARSE(string a)
{
    a = "aBc!d:f'a";

    a.erase(remove_if(a.begin(), a.end(), ispunct), a.end());

    cout << a << endl;
}

有更简单/更有效的方法吗?

我在考虑使用str.len,获取字符串的长度,通过for循环运行它并检查ispunct然后删除它。

1 个答案:

答案 0 :(得分:1)

没有字符串副本。没有堆分配。没有堆释放。

void strip_punct(string& inp)
{
    auto to = begin(inp);   
    for (auto from : inp)
        if (!ispunct(from)) 
            *to++ = from;
    inp.resize(distance(begin(inp), to));
}

比较:

void strip_punct_re(string& inp)
{
    inp.erase(remove_if(begin(inp), end(inp), ispunct), end(inp));
}

我创建了各种工作负载。作为基线输入,我创建了一个包含32到127之间所有char值的字符串。我附加了这个字符串num - 次来创建我的测试字符串。我用strip_punctstrip_punct_re调用了测试字符串iters的副本 - 次。我在每次测试时执行了10次这些工作负载。在降低最低和最高结果后,我平均了时间。我在Microsoft Surface Book 4(Skylake)上使用Windows 10上VS2015的发布版本(优化)进行了测试。我SetPriorityClass()进程HIGH_PRIORITY_CLASS,并使用QueryPerformanceFrequency/QueryPerformanceCounter计算结果。所有时序都是在没有连接调试器的情况下执行的。

 num        iters      seconds      seconds (re)    improvement
10000        1000        2.812        2.947             4.78%  
 1000       10000        2.786        2.977             6.85%
  100      100000        2.809        2.952             5.09%

通过改变num和iters,同时保持处理的字节数相同,我能够看到成本主要受处理的字节数而不是每次调用开销的影响。阅读反汇编证实了这一点。

所以这个版本的速度提高了约5%,并产生了30%的代码。

相关问题