2011-04-26 8 views
7

현재 문자열 인해 설계 제약 조건에 문자 또는 숫자를 (포함 할 수 있습니다오버로딩을 비교 한 연산자 "잘못된 연산자는 <"

++ C에서, 문자열을 포함하는 각 객체와 객체의 벡터를 정렬 시도 이것은 비교기가 변경 될 수 있기 때문에 필요합니다).

현재 개체의 클래스가 오버로드되어 두 개체가 비교 될 때 포함 된 문자열이 비교됩니다. 이 점은 한 가지로 작용합니다. 그러나 STL 정렬과 같은 정렬 연산을 사용하여 객체를 순서대로 정렬하면 "1", "4", "12"와 같은 세 개의 문자열을 순서대로 정렬합니다 "1", "12", "4". 4는 12보다 크지 만 가장 왼쪽 숫자와 비교하기 시작하기 때문에이 '잘못된'정렬이 발생합니다.

내 초기 응답은 비교 작업을 오버로드하는 방법을 변경하는 것이 었습니다. 먼저 비교할 문자열의 길이를 확인합니다. 문자열의 내용이 크거나 작 으면 표시가됩니다. A의

// overloaded comparision operators 
friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){ 
    // we need to deal with strings of different lengths... 
    if(record1.comparator.length() < record2.comparator.length()) 
     return true; 
    else 
     return (record1.comparator < record2.comparator); 
} 

이 작업의 결과 "표현 : 잘못된 연산자 <"런타임 동안 메시지.

내가 실수하고있는 부분에 대한 아이디어가 있습니까? 정렬 작업을 원하는 방식으로 작업을 정확하게 지시 할 수 있어야합니다. 현재 개체를 포함하는 벡터를 사용하고 있기 때문에 유효하지 않은 경우에도 정렬 작업을 수행해야합니다. nodeRecord 객체의 초기화 중

비교기 :

단일 비교기를 사용하고 그 기능을 좀 더 똑똑하지 않는 이유는
nodeRecord(int fromNode, int toNode, int connectionCost, bool compareByCost = false){ 
    // take the provided stock information and insert it into the object 
    stringstream fromNodeSS; 
    fromNodeSS << fromNode; 
    this->fromNode = fromNodeSS.str(); 
    stringstream toNodeSS; 
    toNodeSS << toNode; 
    this->toNode = toNodeSS.str(); 
    this->connectionCost = connectionCost; 

    // set the comparator to our chosen comparision term 
    if (!compareByCost){ 
     this->comparator = this->fromNode; // we use from node in this case, since we build the tree outwards 
    } 
    else{ 
     stringstream ss; 
     ss << this->connectionCost; 
     this->comparator = ss.str(); // we use the connection cost in this case, to allow us to sort new connections 
    } 

    // set this as a non-null (active) record 
    this->nullRecord = false; 
} 
+0

비교기는 무엇인가? 그 코드를 게시하십시오. –

+0

비교기의 정의를 보여 주실 수 있습니까? –

+0

@Mike 및 @Mario - 비교기는 nodeRecord 객체를 초기화하는 동안 초기화됩니다. 위의 내용을 볼 수 있습니다. – BSchlinker

답변

10

운영자는 사실상 유효하지 않습니다.

연산자 <에는 정렬에 사용할 수 있기를 원하면 숫자 속성이 있어야합니다. x < y => !(y < x)

이의이 x = "b"y = "aa"을 정의 할 수 있습니다 : 하나는 반대 칭 속성입니다.

  • x < y"b"의 길이 "aa"
  • y < x 때문에 "aa"의 길이보다 열등하므로

    "b"

흠 열등?

또한 접두어가 0 인 경우 사용자의 정의가 이상합니다.

아, 문자열을 비교하는 것은 숫자를 비교하는 것보다 속도가 느립니다.

걸릴까요? 비교 정보로 노드를 변경하지 마십시오. 실제 비교 모드는 노드 자체 내에서 아무런 관련이 없습니다.

그러면 두 가지 비교 방법을 쓰게 될 것입니다. 하나는 비용으로, 다른 하나는 원점별로 비교하는 것입니다.


그리고 다시 원래의 문제에 와서 어떻게 분류 ["a", "b", "aa"]을 고려 비교기를 작성하는?

거의 다 왔지만 길이 비교는 불완전합니다. 길이가 다른 경우에만 실제 어휘 비교로 되돌아 가야하므로, 오른 쪽 인수의 길이가 왼손 인수의 길이보다 떨어진 경우를 잊어 버린 것입니다.

따라서 정확한 형태는 두 개의 스트링을 가정하면,이다

bool compare(std::string const& lhs, std::string const& rhs) { 
    if (lhs.length() < rhs.length()) { return true; } 
    if (rhs.length() < lhs.length()) { return false; } // don't forget this 
    return lhs < rhs; 
} 
+0

감사합니다. 귀하의 솔루션은 문제가 무엇인지 파악하고 이해하는 데 정말로 도움이되었습니다. 그리고 내가 잊어 버린 다른 경우에 대해 생각 나게했다. – BSchlinker

0

? 처음에 숫자가 있는지 확인한 다음 strtol() 또는 atoi() 쌍을 만들어 결과를 비교하십시오.

그렇지 않은 경우 숫자가 아닌 요구 사항에 따라 문자열과 문자의 길이를 비교하십시오.

+0

문자열을 정렬하는 방법과 비슷하게 문자열을 정렬 할 수 있기를 원합니다. 예를 들어, "a", "aa"및 "b"는 "a", "b", "aa"순으로 정렬해야합니다. 내가 게시 한 방법은 제가 이것을 성취 할 수있는 유일한 방법입니다. – BSchlinker

+0

@ BSchlinker : 내 대답을 업데이트했습니다. – wallyk

+0

불행히도, 내 문제가 해결되지 않습니다. 같은 오류가 발생할 것입니다 = ( – BSchlinker

1

오류를 던지고있는 다음 코드 세그먼트를 찾았는데 내 오버로드 된 작업이 어떻게 작동하는지 생각했습니다.

template<class _Ty1, class _Ty2> inline 
    bool _Debug_lt(_Ty1& _Left, _Ty2& _Right, 
     _Dbfile_t _File, _Dbline_t _Line) 
    { // test if _Left < _Right and operator< is strict weak ordering 
    if (!(_Left < _Right)) 
     return (false); 
    else if (_Right < _Left) 
     _DEBUG_ERROR2("invalid operator<", _File, _Line); 
    return (true); 
    } 

전문 솔루션이 도움이 모든 사람에게

// overloaded comparision operators 
friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){ 
    // we need to deal with strings of different lengths... 
    if(record1.comparator.length() > record2.comparator.length() 
     && (record1.comparator.length() !=0 && record2.comparator.length() != 0)) 
     return false; 
    else if(record1.comparator.length() < record2.comparator.length() 
     && (record1.comparator.length() !=0 && record2.comparator.length() != 0)) 
     return true; 
    else 
     return (record1.comparator < record2.comparator); 
} 

감사 (감사 마티유 M. 왼쪽 의견을 다시 수정)입니다!

관련 문제