我正在尝试找到从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然后删除它。
答案 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_punct
和strip_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%的代码。