在 C++ 中从字符串中删除标点符号的最有效方法
Most efficient way to remove punctuation marks from string in c++
我正在尝试找到从 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;
}
有easier/more有效的方法吗?
我在考虑使用 str.len,获取字符串的长度,运行 通过 for 循环并检查 ispunct,如果是则删除。
没有字符串副本。没有堆分配。没有堆释放。
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 之间所有字符值的字符串。我将这个字符串追加 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% 的代码。
我正在尝试找到从 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;
}
有easier/more有效的方法吗?
我在考虑使用 str.len,获取字符串的长度,运行 通过 for 循环并检查 ispunct,如果是则删除。
没有字符串副本。没有堆分配。没有堆释放。
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 之间所有字符值的字符串。我将这个字符串追加 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% 的代码。