【问题标题】:How can I find the index of the highest value in a vector, defaulting to the greater index if there are two "greatest" indices?如何找到向量中最大值的索引,如果有两个“最大”索引,则默认为更大的索引?
【发布时间】:2016-06-11 10:03:25
【问题描述】:

我一直在使用std::max_element(vec),但据我所知,如果两个“最大”索引相等,它会返回最小索引。

例子:

vector<int> v = {1, 2, 3, 4, 5, 3, 3, 2, 5};

std::max_element(v) 将引用 v[4],但出于我项目的目的,我需要它引用 v[8]。最好的方法是什么?

【问题讨论】:

  • max_elementreverse_iterators? (您是在编写伪代码,还是已经在使用 Eric Niebler 的范围库?目前没有标准的 std::max_element 仅采用 std::vector。)
  • 你可以从你得到的第一个结果开始搜索。
  • @BoBTFish 谢谢!我会调查一下。

标签: c++ algorithm vector


【解决方案1】:

制作自己的函数很容易:

/* Finds the greatest element in the range [first, last). Uses `<=` for comparison.
*
* Returns iterator to the greatest element in the range [first, last).
* If several elements in the range are equivalent to the greatest element,
* returns the iterator to the last such element. Returns last if the range is empty.
*/

template <class It>
auto max_last(It first, It last) -> It
{
    auto max = first;
    for(; first != last; ++first) {
        if (*max <= *first) {
            max = first;
        }
    }
    return max;
}

【讨论】:

  • 您可以通过采用遵循严格弱排序的Comparator,然后使用if(!cmp(*first, *max)) { max = first; },使其遵循标准算法的风格。虽然标准算法通常有一个不带比较器的版本,并且默认为 &lt;(这与默认为 std::less&lt;T&gt; 不太一样,可能是专门的)。
  • 一个类型更可能支持&lt;而不是&lt;=。而&lt;=可以用&lt;来实现:a &lt;= b等于(a &lt; b) || (!(a &lt; b) &amp;&amp; !(b &lt; a))。所以你不一定需要&lt;=
【解决方案2】:

你可以用这个

max_element(v.rbegin(), v.rend());

指最大值的最大索引。

例如,

#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;

int main()
{
    vector<int> v = {1, 2, 3, 4, 5, 3, 3, 2, 5};
    *max_element(v.rbegin(), v.rend())=-1;
    for (auto i: v) cout << i << ' ';
}

产生输出

1 2 3 4 5 3 3 2 -1 

上面提到的方法返回一个反向迭代器,正如@BoBTFish 指出的那样。要获得前向迭代器,您可以这样做:

#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;

int main()
{
    vector <int> v = {1, 2, 3, 4, 5, 3, 3, 2, 5};
    reverse_iterator < vector <int> :: iterator > x (max_element(v.rbegin(), v.rend()));
    vector <int> :: iterator it=--x.base(); // x.base() points to the element next to that pointed by x. 
    *it=-1; 
    *--it=0; // marked to verify 
    for (auto i: v) cout << i << ' ';
}

产生输出

1 2 3 4 5 3 3 0 -1 
              ^

可以看出迭代器it是一个前向迭代器。

【讨论】:

  • 请记住,这会为您提供一个reverse_iterator 到元素,您可能希望将其转换回“正确的”迭代器类型(std::vector::iterator)。我认为如果你展示如何做到这一点,它会改善你的答案。
猜你喜欢
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 2018-04-25
  • 2016-08-21
  • 2014-05-19
相关资源
最近更新 更多