2012-07-11 88 views
4

我知道有一個檢查空格的「isspace」函數,但是這需要我遍歷字符串中的每個字符,這可能會導致性能不佳,因爲這會被稱爲很多。有沒有一種快速的方法來檢查一個std :: string是否只包含空格?如何檢查一個字符串是否包含空格/製表符/新行(任何空白)?

例如:

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

一個解決方案,我想的是使用正則表達式,然後我就知道,它僅包含空格,如果它是假的......但我不知道這是否會比isspace功能更有效率。

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

在此先感謝!

+7

_「這將需要我通過串中的每個字符,可以是性能不好迭代」 _你怎麼能指望測試是否所有字符匹配你的條件_without_迭代字符串中的所有字符? – 2012-07-11 02:04:36

+2

在您的解決方案處於正常工作狀態之前,不要擔心微型優化。 – 2012-07-11 02:05:53

+1

據我所知,如果一個字符串中包含空格而不檢查每個字符是否爲空格,實際上是不可能的,除非您發現非空格時返回false,而不是檢查字符串的其餘部分。 – RoneRackal 2012-07-11 02:07:02

回答

6

任何方法必要時都需要查看字符串的每個字符。在每個字符上調用isspace()的循環非常高效。如果編譯器內聯isspace(),那麼這將會接近最優。

當看到非空格字符時,該循環當然應該中止。

+0

我現在明白了,會在10分鐘內接受:) – 2012-07-11 02:07:44

7

一個普通字符串,你能做的最好的將是以下形式:

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

這將是爲O(n)在最壞的情況下,但不知道其他關於字符串,這將是你能做的最好。

+0

這不一定是你能做的最好的。看到我的評論。 – 2012-07-11 02:13:48

+1

'if(b)return true;返回false;'應該寫成'return b;'。 – GManNickG 2012-07-11 02:23:12

+1

@PreetKukreti使用常規的std :: string。如果你想實現你的想法,你需要將std :: string包裝在另一個類中,比如cached_string或類似的東西。如果這是一個選項,那麼通過一切手段你的想法更快。 – Yuushi 2012-07-11 02:25:15

2

您正在假設正則表達式不會迭代字符串。正則表達式可能比線性搜索要重得多,因爲它可能會建立一個FSM並以此爲基礎進行遍歷。

您可以進一步加速並使其接近恆定時間操作的唯一方法是通過迭代字符串的每次更新來緩解成本,並緩存跟蹤是否存在類似空間的布爾/位字符,如果沒有更改,則返回該值,並且每當您對該字符串執行寫操作時更新該位。但是,這會犧牲/減慢修改操作的速度,以提高自定義has_space()的速度。

+0

Nit:'isspace'具有恆定的時間複雜度,因爲它只測試一個字符。用'isspace'測試每個字符的循環會具有線性複雜性。 – 2012-07-11 02:15:10

+0

@JamesMcNellis啊。我認爲這是一個字符串操作。將更新。謝謝。 – 2012-07-11 02:16:11

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)。

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是不進列表 「\噸\ n」 個 1:因爲STR2包含空格,標籤和你。

希望它可以幫助 告訴我,如果您有任何疑問

相關問題