2009-11-04 2 views
1
bool pred(int k, int l, int num1, int num2) 
{ 
return (num1 < num2); 
} 

int main() 
{ 
    vector <int> nums; 
    for (int i=50; i > 0; --i) 
    { 
     nums.push_back(i); 
    } 
    std::sort (nums.begin(), nums.end(), boost::bind(&pred, 5, 45)); 
} 

나는 부스트 초보자입니다. boost :: bind를 사용하는 법을 배우고 있었고 정수 벡터를 정렬하고 벡터에서 45보다 크고 5보다 작은 모든 요소를 ​​없애고 싶었습니다. 힘든 시간을 보냈습니다. 아무도 내가 그것을 도울 수 있다면 좋을까?boost :: bind를 사용하여 정렬

내가 문제를 직면하는 이유는 벡터 요소를 벡터를 통해 반복하면서 벡터 요소를 제거하려고 시도하기 때문입니다. 내가 먼저 정렬 한 다음 요소를 제거하면 훨씬 더 쉬울 것입니다. 그러나 나는 이런 식으로하고 싶다. 어떤 도움을 주셔서 감사합니다.

답변

4

sort에서이를 수행 할 수 없습니다.

sort 전후의 요소를 제거하십시오.

bool outOfRange(int low, int high, int num) { 
    return low > num || num > high; 
} 

... 

    nums.erase(
      std::remove_if(nums.begin(), nums.end(), 
        boost::bind(&outOfRange, 5, 45, _1)), 
      nums.end() 
     ); 

실제로는 boost::bind이 전혀 필요하지 않지만. 지옥, 우리는 그것도 조금 더 일반적인 만들 수 있습니다

template<typename T, class cmp = std::less<T> > 
struct outOfRange : std::unary_function<T, bool> { 
    outOfRange(const T &low, const T &high) : low(low), high(high) {} 
    bool operator()(const T &val) { return cmp()(val, low) || cmp()(high, val); } 
    const T &low, &high; 
} 

... 

    nums.erase(
      std::erase_if(nums.begin(), nums.end(), outOfRange<int>(5, 45)), 
      nums.end() 
     ); 
+0

나는 당신이 향상에 자리 표시자를 포함 할 필요가 있다고 생각합니다 : : 바인드 표현식 : boost :: bind (& outOfRange, 5, 45, _1) – zdan

+0

그래, 알 겠어. 나는 그것을 고치고 실제로 동시에 사물을 단순화 할 것이다. – ephemient

+3

'boost :: lambda'는'boost :: bind'보다 훨씬 유용합니다 :'std :: erase_if (nums.begin(), nums.end(), _1 < 5 || _1 > 45);'오류 메시지가 잘못 나온다면 무서운 것들입니다! – bdonlan

0

아이디어가 표준으로 아주 불가능합니다 :: 종류는 당신의 벡터의 순서에 영향을 미칠 수 있고, 값을 스스로가 수정할 수 없습니다.

내가 생각할 수있는 벽장은 모든 유효한 값 (> = 5 및 < = 45)이 유효하지 않은 값 앞에 오지만 올바른 값과 잘못된 값이 모두 정렬 된 것입니다.

bool pred(int min, int max, int num1, int num2) 
{ 
    bool num1_valid = (num1 >= min) && (num1 <= max); 
    bool num2_valid = (num2 >= min) && (num2 <= max); 

    if (num1_valid == num2_valid) 
    { 
     return num1 < num2; 
    } 
    else 
    { 
     return num1_valid; 
    } 
} 
2

많은 방법이 있습니다. 당신이 자리 (_1)를 포함 할 필요가 결박 부스트를 사용하는 경우, 이상 반복되는 하나 인 인수를 알 수 있다는

bool outsideRange(int num, int min, int max) 
{ 
    return (num < min) || (num > max); 
} 

nums.erase(std::remove_if(nums.begin(),nums.end(),boost::bind(&outsideRange,_1,5,45))); // See comments about remove-erase idiom. 
std::sort(nums.begin(),nums.end()); 

참고 : 가장 쉬운 방법은 먼저 종류의 모든 불필요한 요소를 제거하는 것입니다. 당신이 한 번에 그것으로 선호하는 경우

, 당신은 조건부로 당신을 위해 MULTISET, 정렬 항목 모두의 int를 복사 할 수 있습니다 :

bool outideRange(int num, int min, int max) 
{ 
    return (num < min) || (num > max); 
} 

std::multiset numsInSet; 
std::remove_copy_if(
    nums.begin(), 
    nums.end(), 
    std::inserter(numsInSet,numsInSet.begin()), 
    boost::bind(&outideRange,_1,5,45)); 
+0

Heh, 내가 처음에했던 것과 같은 실수를 저 지르 셨습니다 : remove_if는 실제로 아무 것도 제거하지 않습니다 :) – ephemient

+0

... 지우기 - 제거 관용구를 찾으십시오. (http://en.wikibooks.org/wiki/More_C % 2B % 2B_Idioms/Erase-Remove) –

+0

죄송합니다. 그에 따라 예제를 업데이트했습니다. 감사! – zdan