9

スペースをチェックする「isspace」関数があることは知っていますが、文字列内のすべての文字を反復処理する必要があり、これは頻繁に呼び出されるため、パフォーマンスが低下する可能性があります。std::string にスペースのみが含まれているかどうかを確認する簡単な方法はありますか?

元:

function("       ") // returns true
function("    4  ") // returns false

私が考えた1つの解決策は、正規表現を使用することです。そうすれば、falseの場合に空白のみが含まれることがわかります...しかし、これがisspace関数よりも効率的かどうかはわかりません。

regex: [\w\W] //checks for any word character(a,b,c..) and non-word character([,],..)

前もって感謝します!

4

5 に答える 5

8

通常の文字列を使用すると、できることは次の形式になります。

return string::find_first_not_of("\t\n ") == string::npos;

これは最悪の場合 O(n) になりますが、文字列について他に何も知らなければ、これが最善の方法です。

于 2012-07-11T02:08:56.053 に答える
8

どのメソッドも、必然的に、文字列の各文字を調べる必要があります。各文字を呼び出すループisspace()は非常に効率的です。コンパイラによってインライン化されている場合isspace()、これはほぼ最適です。

もちろん、スペース以外の文字が検出されるとすぐに、ループは中止されます。

于 2012-07-11T02:05:46.943 に答える
2

正規表現が文字列を反復処理しないと仮定しています。正規表現は、FSM を構築し、それに基づいてトラバースする可能性があるため、おそらく線形検索よりもはるかに重いものです。

さらに高速化し、ほぼ一定時間の操作にする唯一の方法は、文字列の更新ごとに繰り返し処理し、スペースのような文字があるかどうかを追跡する bool/bit をキャッシュして、それを返すことで、コストを償却することです。それ以来変更が行われていない場合は値を変更し、その文字列への書き込み操作を行うたびにそのビットを更新します。ただし、これにより、カスタムの速度を上げるために操作を変更する速度が犠牲になります/遅くなりますhas_space()

于 2012-07-11T02:09:31.257 に答える
1

価値のあることとして、ロケールには次のようなことを行う関数 (scan_is) があります。

#include <locale>
#include <iostream>
#include <iomanip>

int main() {

    std::string inputs[] = { 
        "all lower",
        "including a space"
    };

    std::locale loc(std::locale::classic());

    std::ctype_base::mask m = std::ctype_base::space;

    for (int i=0; i<2; i++) {
        char const *pos;
        char const *b = &*inputs[i].begin();
        char const *e = &*inputs[i].end();

        std::cout << "Input: " << std::setw(20) << inputs[i] << ":\t";
        if ((pos=std::use_facet<std::ctype<char> >(loc).scan_is(m, b, e)) == e)
            std::cout << "No space character\n";
        else
            std::cout << "First space character at position " << pos - b << "\n";
    }
    return 0;
}

isspaceこれがループ内での使用 (または の使用) よりも (もしあれば) 本当の利点を与えるかどうかは、おそらく (多くの) 疑問の余地がありますstd::find_if

于 2012-07-11T02:54:54.237 に答える
0

すべての文字が特定のリストにある場合は、find_first_not_of を使用することもできます。その後、ループを回避できます。

ここに例があります

#include <string>
#include <algorithm>
using namespace std;
int main()
{
    string str1="      ";
    string str2="      u    ";
    bool ContainsNotBlank1=(str1.find_first_not_of("\t\n ")==string::npos);
    bool ContainsNotBlank2=(str2.find_first_not_of("\t\n ")==string::npos);
    bool ContainsNotBlank3=(str2.find_first_not_of("\t\n u")==string::npos);
    cout << ContainsNotBlank1 <<endl;
    cout << ContainsNotBlank2 <<endl;
    cout << ContainsNotBlank3 <<endl;
    return 0;
}

出力: 1: 空白とタブのみのため 0: u がリストに含まれていないため "\t\n " 1: str2 には空白、タブ、および u が含まれているため。

ご不明な点がございましたら、お気軽にお問い合わせください。

于 2013-06-19T19:17:19.890 に答える