【问题标题】:How to get max_element from vector<std::string>如何从向量中获取 max_element<std::string>
【发布时间】:2014-11-26 02:09:52
【问题描述】:

使用来自cplusplus.com 的代码,我试图在vector&lt;std::string&gt; 中找到最大int 值。 向量是 std::string 格式,这里没有选择。

bool myfn(int i, int j)
{
    return i < j;
}

vector<std::string> dat;
dat.push_back(2.1);
dat.push_back(5.3);

for (int l = 0; l < dat.size(); ++l)
{
    std::cout << *std::max_element(dat.begin(), dat.end(), myfn) << '\n';
}

预期输出:

3

错误:

.cpp:76:93: error: no matching function for call to 'max_element(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >::size_type, bool (&)(int, int))'

如何找到vector&lt;std::string&gt; 中的最大值?

【问题讨论】:

  • myfn 完全没有必要。默认是做不到。
  • 你的循环没用。 max_element 将覆盖整个范围。

标签: c++ c++11 vector max


【解决方案1】:

您使用错误的参数调用max_element。它需要两个迭代器和一个函数:

template <class ForwardIterator, class Compare>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last,
                           Compare comp);

你用一个向量和一个大小来调用它。混淆可能源于您链接的参考中的示例:

std::min_element(myints,  myints +7,  myfn)
//               ^^^^^^   ^^^^^^^^^
//                int*       int*

在这种情况下,myintsmyints + 7 都是int* 类型,原始指针是一个迭代器。但是,在您的情况下,您传递了两种 不同 类型(vector&lt;string&gt;size_t),其中 既不是 也是迭代器。所以你需要这样做:

*std::max_element(dat.begin(), dat.end(), myfn)

或者,为了说明与参考中的示例等效的内容(尽管肯定更喜欢上面的):

std::string* first = &dat[0];
*std::max_element(first, first + dat.size(), myfn)

这很有效,因为在这种情况下,我传递了两个 string*,它们是迭代器。

(同样根据您的使用情况,dat 应该是 vector&lt;int&gt; 而不是 vector&lt;string&gt;。)

【讨论】:

  • 添加模板并更改 .begin 和 .end,现在会抛出此错误 bpaste.net/show/f869abf55eea
  • @nerd007 当你的向量元素是std::string 类型时,你的myfn 函数仍然接受两个整数作为参数。如果您将参数类型更改为std::string,您的错误将消失,但max_element 使用的默认比较是&lt;,因此甚至不需要myfn
  • 问题是 std::string max_element 因为向量是 std::string (这里没有选择),当我尝试将其转换为 std::double 时,我丢了一个数字,所以我的数学会错的。您的代码不起作用,因为它适用于 int,而不是 std::string 向量。 :(
  • @nerd007 你必须选择一种类型。您声明了vector&lt;string&gt; dat,但随后dat.push_back(1)...1 不是string。您的比较器函数myfn 需要两个ints,而不是两个strings。一切都必须是同一类型。
  • 数据来自 www 作为字符串。这些字符串填充一个 std::string 向量。一旦他们在那里,我需要最大值(首选)。是的,这里需要转换。 www 不会向我扔双打。在数据类型上别无选择,我必须使用我得到的东西。
【解决方案2】:

您有一个充满字符串vector&lt;std::string&gt; dat; 的向量,但您的比较函数需要 2 个整数。您可能想要更改存储在向量中的类型或更改您使用的比较函数。如果您使用整数,那么默认的比较运算符将执行您想要的操作,而无需编写自定义函数。

另外,std::max_element 期望得到一个迭代器,一个用于开始,一个用于结束,因此您需要将调用更改为类似于std::max_element(dat.begin(), dat.end(), myfn)。您可能会注意到实际上不需要您拥有的循环,因为您已经通过调用 std::max_element 超出了该范围,所有此循环所做的只是多次计算完全相同的值,您只需要计算一次。

【讨论】:

  • 如何将字符串格式的长小数(双精度)插入双精度向量?
  • @nerd007 你会想使用类似 std::stod cplusplus.com/reference/string/stod
  • @nerd007,这也开始感觉它可能是一个 XY 问题,您将使用什么示例输入?请提供一个逐字逐句的例子,这会有所帮助。
  • 我有一个用字符串填充的向量(别无选择)而不是双倍。我需要知道最大元素的双精度值。这里需要进行转换。
【解决方案3】:

您的 std::vector dat 声明是错误的,因为您想要 push_back int。 std::max_element 和 std::min_element 返回迭代器而不是值。你可以看看下面的例子

#include <vector>
#include <algorithm>
#include <iostream>

int main()
{
    std::vector<int> v {1,2,3,4,6};
    auto biggest = std::max_element(std::begin(v), std::end(v));
    std::cout << "Max element is " << *biggest
       << " at position " << std::distance(std::begin(v), biggest) << std::endl;

    auto smallest = std::min_element(std::begin(v), std::end(v));
    std::cout << "min element is " << *smallest
        << " at position " << std::distance(std::begin(v), smallest) << std::endl;

    return 0;
}

【讨论】:

  • 我得到一个异常,可能是因为你的向量是int,我的是字符串。是否有一个简单的函数可以即时转换为双精度(这些是长小数)?
  • 如果你想使用双精度,你需要将数据类型更改为双精度。这很简单 std::vector v {1.0,2.0,3.0,4.0,6.0};
  • 数据以字符串形式出现(别无选择)。我需要返回一个双精度值。
  • 你如何对向量进行处理?我有无穷无尽的数据。
【解决方案4】:

指针可以是迭代器。这就是允许您在标准库函数中使用数组作为范围的原因。 myints 是引用数组第一个元素的表达式,myints + 7 引用数组末尾之后的元素。等效地,您可以执行std::begin(myints)std::end(myints)。标准容器以这些成员函数myvector.begin()myvector.end() 的形式公开迭代器。您将这些迭代器(而不是容器和大小)传递给 std::max_element

默认情况下,std::max_element 使用operator&lt; 来比较元素。在这种情况下,您不需要比较器函子。

您的std::vectorvalue_typestd::string,但您试图传递int。要么将value_type改为int,要么使用字符串转换函数,即C++11的std::to_string

最后,你的循环是完全没有必要的。 std::max_element 范围内的运算符。

std::vector<int> dat; 
dat.push_back(1); 
dat.push_back(3);

std::cout << *std::max_element(dat.begin(), dat.end()) << '\n';

【讨论】:

  • 数据为 std::string 格式。不是int。最后,它需要采用双重格式。但我得到了 std::string。
  • 数据为 std::string 格式。 not int 那么你不应该提供一个比较函数来接受 int 吗?您需要一个接受字符串的比较函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 2015-09-24
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
相关资源
最近更新 更多