2017-03-01 100 views
2

我試圖找到std::vector<double>中最後一個非零元素的索引。如果向量中的最後一個元素不是零,那麼它應該返回最後一個元素的索引。查找std :: vector中的最後一個非零元素

我相信我可以用std::find_if_not反向迭代器和std::distance,在此基礎上:

std::find_if_not(amounts.rbegin(), amounts.rend(), 0.0)

其中amountsstd::vector<double>,但我有這個與std::distance和組合的難度前向迭代器amounts.begin()

另外,有沒有一種方法可以引入謂詞進行比較,比如說1e-8的容差?

我正在使用C++ 11。

+0

如果您使用簡單的for循環,開發時間可能會更快。 –

+0

我想我會被解僱,如果我這樣做:我需要這樣做很多次。 –

+2

['std :: find_if_not'](http://en.cppreference.com/w/cpp/algorithm/find)的最後一個參數應該是一個一元謂詞 - 您可以使用lambda。 –

回答

7

實施例:

std::vector<double> v{1.32, 1.423, 2.543, 3.534, 4.2, 0}; 

auto result1 = std::find_if(std::rbegin(v), std::rend(v), [](auto& v) { return std::fabs(v - 0) > std::numeric_limits<double>::epsilon(); }); 
if (result1 != std::rend(v)) { 
    std::cout << *result1 << "\n"; 
    std::cout << std::distance(std::begin(v), (result1 + 1).base()); 
} 

輸出:

4.2 
4 

[編輯]上

更多的解釋:在OP問題

std::fabs(v - 0) > std::numeric_limits<double>::epsilon(); } 

有:

此外,有沒有辦法,我可以介紹一個謂詞來比較,說一個寬容1e-8?

所以這是這樣的容差檢查,你可以用epsilon代替epsilon用一些其他的值。

+1

對代碼的一些解釋是有用的,這就是爲什麼我低估了。 – zett42

+1

對我來說它是有用的,因爲它是。謝謝。 (我唯一不喜歡的是與std :: numeric_limits :: epsilon())的比較。 –

+0

你真的明白他爲什麼使用'return std :: fabs(v - 0)> std :: numeric_limits :: epsilon()'而不是'return v!= 0'嗎?你可能,但其他人在看代碼可能不會... – zett42

0

簡單for環也可以達到目的,請參閱活樣品:http://ideone.com/dVNOKk

#include <iostream> 
#include <vector> 

int main() { 
    std::vector<int> v{1, 2, 3, 4, 1, 2, 3, 0, 4, 1, 2, 3, 4, 0, 0, 0}; 

    for (int i = static_cast<int>(v.size()) - 1; i >= 0; --i) { 
     if (v.at(i) != 0) { 
      std::cout << "Last non-zero at: " << i << '\n'; 
      break; 
     } 
    } 
    return 0; 
} 

輸出:Last non-zero at: 12

+1

'v.size() - 1'以無符號算術評估。如果矢量爲空,則效果不佳。 –

+0

@XavierImbs我不認爲它確實(http://ideone.com/uuw5PC),但添加演員來澄清。 –

+0

現在將矢量的支持大小限制爲一半。 'v.at(i)!= 0'也不適合雙打。 – luk32

0

但我有在這與標準::距離和前向迭代amounts.begin()合併困難

反向迭代器具有成員函數base返回一個非反向迭代與關係&*(rit.base() - 1) == &*rit。所以,你可以使用以下命令:

std::distance(amounts.begin(), found.base()) - 1; 

另一種選擇:

amounts.size() - std::distance(amounts.rbegin(), found) - 1 

此外,有沒有辦法,我可以介紹一個謂詞來比較,說的1E-8的公差?

是的。事實上,你必須使用一個謂詞,即使是精確的比較,因爲這是std::find_if_not期望的第三個參數(而不是元素的值)。

相關問題