2012-04-18 3 views
2

문자열을 다음과 같이 비교해야합니다. 누구나 내게 통찰력이나 알고리즘을 C++로 제공 할 수 있습니까? 예를 들어 :두 개의 영숫자 문자열을 비교하십시오.

"a5" < "a11"  - because 5 is less than 11 
"6xxx < 007asdf" - because 6 < 7 
"00042Q < 42s"  - because Q < s alphabetically 
"6 8" < "006 9" - because 8 < 9 

답변

1

나는이 순서대로 비교를 수행한다고 가정하고있다 : 1-9 범위의 숫자 존재; 자릿수; 자릿수; 자리수 후의 캐릭터 라인의 값

C로되어 있지만 C++ std :: string 클래스를 사용하여 쉽게 변환 할 수 있습니다.

int isdigit(int c) 
{ 
    return c >= '1' && c <= '9'; 
} 

int ndigits(const char *s) 
{ 
    int i, nd = 0; 
    int n = strlen(s); 

    for (i = 0; i < n; i++) { 
     if (isdigit(s[i])) 
      nd++; 
    } 
    return nd; 
} 

int compare(const char *s, const char *t) 
{ 
    int sd, td; 
    int i, j; 

    sd = ndigits(s); 
    td = ndigits(t); 

    /* presence of digits */ 
    if (!sd && !td) 
     return strcasecmp(s, t); 
    else if (!sd) 
     return 1; 
    else if (!td) 
     return -1; 

    /* value of digits */ 
    for (i = 0, j = 0; i < sd && j < td; i++, j++) { 
     while (! isdigit(*s)) 
      s++; 
     while (! isdigit(*t)) 
      t++; 

     if (*s != *t) 
      return *s - *t; 
     s++; 
     t++; 
    } 

    /* number of digits */ 
    if (i < sd) 
     return 1; 
    else if (j < td) 
     return -1; 

    /* value of string after last digit */ 
    return strcasecmp(s, t); 
} 
+0

"5 a"< "5 b" –

+0

@ user765443처럼 시도한 공간은 어떨까요 : "("5 a ","5 b ")에 숫자가 있음, val 마지막 자리수'return strcmp (s, t);가 평가됩니다. strcmp는 ASCII 테이블에 따라 문자열의 나머지를 비교합니다. 이는 (0x20 0x61)에서 (0x20 0x62)를 비교한다는 의미입니다. 첫 번째 문자열은 더 작습니다. –

+0

"a5" "a11"사례를 올바르게 처리하지 * 않습니다 * 내가 그것을 썼을 때 조금 성급했습니다. '/ * value of digits * /'부분에 내부 루프를 추가해야합니다. –

-3

이 시도하고 약 std::string.compare 읽어

#include <iostream> 
using namespace std; 


int main(){ 
    std::string fred = "a5"; 
    std::string joe = "a11"; 

    char x; 

    if (fred.compare(joe)) 
    { 
     std::cout << "fred is less than joe" << std::endl; 
    } 
    else 
    { 
      std::cout << "joe is less than fred" << std::endl; 
    } 


    cin >> x; 
} 
+1

올바르게) (비교의 반환 값을 처리하지 않을 : 0 수단을 일치 한, 그렇지 않으면 부호가 큰 http://www.cplusplus.com/reference/string/string/compare/ –

+1

입니다 나타냅니다 당신은 대답 OP 질문을하지 않았고 나쁜 예제를 제공했습니다 – Ulterior

2

귀하의 예제 만 표시 숫자, 문자 및 공백을. 그래서 잠시 나는 당신이 다른 모든 기호를 무시한다고 가정 할 것입니다. 또한 대문자와 소문자를 동등한 것으로 취급하려고합니다.

숫자의 실행을 "용어"로 해석하고 글자를 "용어"로 해석하며 글자와 숫자 사이의 전환은 공백과 동일합니다. 단일 공간은 임의의 수의 공간과 동등한 것으로 간주됩니다.

(참고 :

"5a" vs "a11" 
"a5" vs "11a" 

그래서 당신이 문자열을 숫자 용어의 비교에 직면 할 때 무엇을 해결해야한다 : 당신은 눈에 띄게 같은 경우에 무엇을해야하는지의 예를 누락 또한 "5 a"== "5a"와 같은 본질적인 동등성에 대해서는 언급하지 않았습니다. "012"를 사용하기 때문에 명확한 방법이 될 수 있습니다. 문자열을 "terms"의 std::vector으로 바꾼 다음 문자열을 비교하려고 시도하지 말고 이들 벡터를 비교합니다 직접). 이 용어는 숫자 또는 문자열입니다.

how to split a string value that contains characters and numbers

까다 방법 빠른 일회성 비교 될 것이다 중개를하지 않고 문자열에 자신을 일이, 당신이 시작하는 특히 STL의 대답을 도움이 될 수 있습니다. 그러나 그들은 이해하기 어렵고 수정하기가 더 어려울 것이며 동일한 구조를 반복적으로 비교하려고한다면 더 느릴 것입니다.

구조로 구문 분석하는 좋은 점은 프로세스에서 데이터의 본질적인 "정리"를 얻는 것입니다. 정보를 canonical form으로 가져 오는 것은 이러한 다양한 입력을 허용하는 프로그램에서 종종 목표가됩니다.

3

알고리즘 strverscmp을 사용하는 것이 좋습니다. 실제로이 기능이 작업을 수행 할 수 있습니다.

이 기능의 역할은 다음과 같습니다. 두 문자열이 같으면 은 0을 반환하고 그렇지 않으면 바로 뒤에 차이가 있다는 두 문자열이 같음 앞에있는 속성을 사용하여 두 바이트 사이의 위치를 ​​찾습니다. 이 위치를 포함한 (또는 시작 위치 또는 끝 위치) 가장 큰 연속 숫자 문자열 을 찾습니다. 하나 또는 이 비어 있으면 (3)에 (바이트 값의 숫자 순서 지정)이 반환 될 내용을 반환하십시오. 그렇지 않은 경우 숫자 문자열을 숫자로 비교하십시오. 하나 이상의 앞에 오는 0이 포함 된 숫자 문자열은 앞쪽에 소수점이있는 것처럼 해석됩니다 (따라서 앞에 오는 0이있는 특정 숫자 문자열은 더 적은 숫자의 숫자 문자열보다 앞에 오는 숫자가 이됩니다) 0). 따라서 순서는 000, 00, 01, 010, 09, 0, 1, 9, 10입니다.

관련 문제