ユーザーの入力中に QTextEdit の単語数をカウントする Qt C++ のメソッドを実装する必要があります。また、ユーザーが複数のスペースを入力した場合、それらは単語として扱われるべきではありません。既に入力されたテキストでこれを行う方法は知っていますが、単語の総数を常に更新する必要があります。これを手伝ってくれませんか。
5 に答える
ほとんどの場合、自分で解析する必要があります。単一のスプリッターで文字列を分割することは、本番環境では適切な解決策ではありません。これは、私が以前に書いた、まさにこれを行う単純なパーサーです。
void processChar(const QChar &ch)
{
// if char is not separator
if (!sp[ch.unicode()]){
if (!isWord){ // set where word begins
wordBegin = counter;
isWord = 1;
}
++textChar;
}
// if char is separator
else{
// if there is a current word
if (isWord){
QString tempWord(text.mid(wordBegin, counter - wordBegin));
tempWord = tempWord.toLower();
// if word does not exist add with value one
if (!words.contains(tempWord)){
words.insert(tempWord, 1);
++uniqueWords;
}
// if word exists find its value and increment by one
else {
words.insert(tempWord, words.value(tempWord) + 1);
}
++totalWords;
isWord = 0;
}
// else skip
++sepChar;
}
}
processChar()
テキストの各文字を呼び出します。
これは非常に高速で、sp
すべての文字を含むルックアップ テーブル (char 配列) を使用し、区切り文字をマークします。すべてのセパレーターの QString からテーブルを作成する方法は次のとおりです。
void indexChars()
{
// zero everything
for (unsigned i = 0; i < 65536; ++i) sp[i] = 0;
// set every separator index to 1
for (int i = 0; i < separators.length(); ++i) {
sp[separators.at(i).unicode()] = 1;
}
}
16 ビット文字も処理できるようにしたかったので、テーブルはかなり大きいです。
どれだけ速いか - 余分な作業を行っているにもかかわらず、MS Word の単語数よりも約 20 倍高速であり、さらに、テキスト内のすべての一意の単語と出現回数のリストを実際に作成し、 QMap に保存しますwords
。textChar
テキスト文字、区切り文字sepChar
、合計および一意の単語を追跡します。
機能は少しやり過ぎかもしれませんが、余分なものがすべて必要ない場合は、それを取り除くことができます. 不要なものを削除すると、さらに速くなります。
これらのスニペットを使用できます。また、最後のカウント以降にテキストが変更された場合は、タイマーを使用して定期的に単語をカウントすることができます。これは、テキスト フィールドに入力されたすべての文字をカウントするという代替手段よりも優れたソリューションです。
ドキュメントに最初から含まれる単語数を計算したい場合、最良の解決策は次のとおりです。
void MainWindow::docChanged()
{
QTextDocument *doc = qobject_cast<QTextDocument *>(sender());
QRegExp re("\\b\\w+\\b");
int wordCount = 0;
QTextCursor c = doc->find(re);
while (!c.isNull()) {
wordCount++;
c = doc->find(re, c);
}
ui->labelWordCount->setText(QString::number(wordCount));
}