2012-07-11 3 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

_ 문자열에있는 모든 문자를 반복하지 않고 조건을 일치합니까? –

+2

솔루션이 정상적으로 작동 할 때까지 미세 최적화에 대해 걱정할 필요가 없습니다. –

+1

내 지식으로는 모든 문자가 공백인지 검사하지 않고 문자열에 공백이 있는지 실제로 볼 수는 없습니다. 공백이 아닌 공백을 발견했을 때를 제외하고는 그보다 더 빨리 할 수 ​​없습니다. 나머지 문자열. – RoneRackal

답변

6

메서드는 필요에 따라 문자열의 각 문자를 살펴볼 필요가 있습니다. 각 문자에 isspace()을 호출하는 루프는 매우 효율적입니다. isspace()이 컴파일러에 의해 인라인된다면, 이것은 거의 최적 상태에 가까울 것입니다.

루프는 물론 공백이 아닌 문자가 표시되면 즉시 중단해야합니다. 일반 문자열로

+0

지금 이해하고 10 분 안에 받아 들일 것입니다 : –

7

, 당신이 할 수있는 최선의 형식이 될 것입니다 :

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

이것은 최악의 경우 O (n)이 될 것입니다,하지만, 문자열에 대해 더 알고없이이 될 것 네가 할 수있는 최선.

+0

이것이 반드시 당신이 할 수있는 최선은 아닙니다. 내 의견보기. –

+1

'if (b) true를 반환; return false;'그냥 return b;라고 써야합니다. – GManNickG

+1

@PreetKukreti 정규 std :: string을 사용합니다. 아이디어를 구현하려면 cached_string 또는 이와 유사한 다른 클래스에 std :: string을 래핑해야합니다. 이것이 옵션이라면, 당신의 아이디어는 더 빠릅니다. – Yuushi

2

정규 표현식을 문자열에 대해 반복하지 않습니다. Regex는 선형 검색보다 훨씬 무거웠습니다. FSM을 만들고이를 기반으로 트래버스 할 수 있기 때문입니다.

더 빠르게 속도를 높이고 거의 일정한 시간 작업을 할 수있는 유일한 방법은 문자열을 업데이트 할 때마다 반복하여 비용을 상환하고 공간이 유사한 지 추적하는 bool/bit를 캐싱하는 것입니다 문자가 변경되지 않은 경우 해당 값을 반환하고 해당 문자열에 대한 쓰기 작업을 수행 할 때마다 해당 비트를 업데이트합니다. 그러나 이것은 사용자 지정 속도를 높이기 위해 작업을 수정하는 속도를 희생 시키거나 느리게합니다. has_space().

그것은 가치가 무엇인지에 대한
+0

Nit :'isspace'는 단일 문자 만 테스트하기 때문에 일정한 시간 복잡성을 가지고 있습니다. 'isspace'로 각 문자를 테스트하는 루프는 선형 복잡성을 갖습니다. –

+0

@JamesMcNellis 아. 나는 그것이 문자열 연산이라고 생각했다. 업데이트됩니다. 감사. –

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; 
} 

그것은이 훨씬 제공 여부 아마 (있는 경우) 실제 활용 (A의 많은) 질문에 열려 루프 내에서 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 목록에 있지 않기 때문에 "\ t \ n" 1 STR2 공백이 때문에 탭 및 u.

은 당신이 어떤 질문이 있으면 말해 도움이되기를 바랍니다 모든 문자 여부를 테스트 할 것으로 예상합니까 _ "성능에 나쁜 될 수있는 문자열의 모든 문자를 통해 반복하는 나를 필요"

관련 문제