如何计算 QString 开头的重复字符? [英] How to count recurring characters at the beginning of a QString?

查看:48
本文介绍了如何计算 QString 开头的重复字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个行列表,我需要计算开头出现的哈希值.

Im dealing with a list of lines, and I need to count the hashes that occur at the beginning.

#  item 1
## item 1, 1
## item 1, 2
#  item 2

等等.

如果每一行都是一个 QString,我怎样才能返回出现在字符串开头的哈希数?

If each line is a QString, how can I return the number of hashes occurring at the beginning of the string?

QString s("### foo # bar ");
int numberOfHashes = s.count("#"); // Answer should be 3, not 4

推荐答案

琐碎:

int number_of_hashes(const QString &s) {
    int i, l = s.size();
    for(i = 0; i < l && s[i] == '#'; ++i);
    return i;
}

在其他语言(主要是解释型语言)中,您必须担心字符迭代,因为它很慢,并将所有内容委托给库函数(通常用 C 编写).在 C++ 中,迭代在性能方面非常好,所以一个脚踏实地的 for 循环就可以了.

In other languages (mostly interpreted ones) you have to fear iteration over characters as it's slow, and delegate everything to library functions (generally written in C). In C++ iteration is perfectly fine performance-wise, so a down-to-earth for loop will do.

只是为了好玩,我做了一个小基准,将这个简单的方法与 进行比较QRegularExpression 来自 OP 的一个,可能缓存了 RE 对象.

Just for fun, I made a small benchmark comparing this trivial method with the QRegularExpression one from OP, possibly with the RE object cached.

#include <QCoreApplication>
#include <QString>
#include <vector>
#include <QElapsedTimer>
#include <stdlib.h>
#include <iostream>
#include <QRegularExpression>

int number_of_hashes(const QString &s) {
    int i, l = s.size();
    for(i = 0; i < l && s[i] == '#'; ++i);
    return i;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    const int count = 100000;
    std::vector<QString> ss;
    for(int i = 0; i < 100; ++i) ss.push_back(QString(rand() % 10, '#') + " foo ## bar ###");
    QElapsedTimer t;
    t.start();
    unsigned tot = 0;
    for(int i = 0; i < count; ++i) {
        for(const QString &s: ss) tot += number_of_hashes(s);
    }
    std::cerr<<"plain loop: "<<t.elapsed()*1000./count<<" ns\n";
    t.restart();
    for(int i = 0; i < count; ++i) {
        for(const QString &s: ss) tot += QRegularExpression("^[#]*").match(s).capturedLength();
    }
    std::cerr<<"QRegularExpression, rebuilt every time: "<<t.elapsed()*1000./count<<" ns\n";

    QRegularExpression re("^[#]*");
    t.restart();
    for(int i = 0; i < count; ++i) {
        for(const QString &s: ss) tot += re.match(s).capturedLength();
    }
    std::cerr<<"QRegularExpression, cached: "<<t.elapsed()*1000./count<<" ns\n";
    return tot;    
}

正如预期的那样,基于 QRegularExpression慢了两个数量级:

As expected, the QRegularExpression-based one is two orders of magnitude slower:

plain loop: 0.7 ns
QRegularExpression, rebuilt every time: 75.66 ns
QRegularExpression, cached: 24.5 ns

这篇关于如何计算 QString 开头的重复字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆