2009-11-04 74 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 2009-11-05 01:50:55

+0

是的,我知道,哎呀。我會解決這個問題,實際上也許可以同時簡化一些事情。 – ephemient 2009-11-05 03:12:07

+3

'boost :: lambda'比'boost :: bind'更有用,例如:'std :: erase_if(nums.begin(),nums.end(),_1 < 5 || _1 > 45);'錯誤但是,如果你發現錯誤信息是可怕的東西,但! – bdonlan 2009-11-05 03:36:47

0

你的想法是不太可能的的std ::排序只能影響你的矢量的順序,並不能修改該值自理。

我能想到的最接近的東西就是讓所有有效值(> = 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

有很多方法可以做到這一點。最簡單的是首先刪除所有不必要的元素,然後排序:

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()); 

注意,使用的刺激時,綁定你需要包括佔位符(_1),告訴它這說法是在其上迭代的一個。

如果你喜歡它一步到位,你可以有條件地所有的整數複製到多集,其中排序的項目爲您提供:

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

嘿,你犯了同樣的錯誤我開始:'remove_if'實際上並沒有刪除任何東西:) – ephemient 2009-11-04 23:39:16

+0

是...查找刪除刪除成語(http://en.wikibooks.org/wiki/More_C %2B%2B_Idioms/Erase-Remove) – 2009-11-05 01:11:20

+0

糟糕,忘記了這一點。相應地更新了示例。謝謝! – zdan 2009-11-05 01:46:15