C++:访问向量列表中的特定元素

3

我有一个向量列表:

list< vector<int> > myList;

这个列表的结构如下:
({1,2,3}, {4,5,6}, ...)

我希望通过位置获取特定元素。例如,getFromList(myList, 0, 2) 将返回 3。我尝试了以下代码,但它并不起作用:

int getFromList(list< vector<int> > myList, int i, int j) 
{
    int ki = 0, kj = 0, num;
    for (list<vector<int>>::iterator it1 = myList.begin(); it1 != myList.end(); ++it1) {
        vector<int>::iterator it2;
        ki++;
        for (it2 = (*it1).begin(); it2 != (*it1).end(); ++it2) {
            kj++;
            if (ki == i && kj == j) {
                num = (*it2);
            }
        }
    }

    return num;
}

如果我使用你的命令,会出现很多错误,Cássio Renan。第一个错误:错误 28 错误 C2227:“->at”的左侧必须指向类/结构/联合/通用类型 - Gooman
@CássioRenan begin() 返回的 list 迭代器是双向迭代器,不允许使用 operator+ - Jérôme
3个回答

3

Cássio在评论中提供的解决方案行不通,因为您无法随机访问list的元素。

相反,您可以使用头文件<iterator>中定义的std::next来完成此操作:

return std::next(myList.begin(), i)->at(j);

请注意,该方法不会对传入的列表大小进行任何边界检查。在返回结果前,请确保i是一个有效的索引。

2
这里有一个演示程序。
#include <iostream>
#include <list>
#include <vector>
#include <iterator>
#include <stdexcept>


int getFromList( const std::list<std::vector<int>> &myList, size_t i, size_t j )
{
    if ( !( i < myList.size() ) ) throw std::out_of_range( "The frst index is out of the range" );

    auto it = std::next( myList.begin(), i );

    if ( !( j < it->size() ) ) throw std::out_of_range( "The second index is out of the range" );

    return it->operator []( j );
}    

int main()
{
    std::list<std::vector<int>> myList = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11, 12 } };

    std::cout << "myList[" << 2 << "][" << 3 << "] = " << getFromList( myList, 2, 3 ) << std::endl;

    return 0;
}

它的输出结果为

myList[2][3] = 11

请注意函数的第一个参数是常量引用。

至于您的函数,当其中一个索引超出有效范围时,它具有未定义的行为,因为该函数返回变量 num 的未初始化值。


你为什么在这里对第二个索引进行检查时抛出自己的异常,而不是依赖于vector::at执行的边界检查呢? - Simon Gibbons
1
@SimonGibbons 当两个抛出异常不一致时,这是一个不好的想法。一个发出用户定义的清晰信息,另一个发出系统信息。 - Vlad from Moscow

0

我自己找到了一些解决方案:

int getFromList(list< vector<int> > myList, int i, int j) 
{
    list<vector<int>>::iterator iter = myList.begin();
    advance(iter, i);
    vector<int> x = (*iter);

    return x[j];
}

这不是一个好的决定,因为你1)通过值传递列表;2)你没有检查有效范围;3)你在函数内部创建了一个向量。 - Vlad from Moscow
好的,弗拉德。在这种情况下,最好使用你或西蒙提供的决策。 - Gooman
他的解决方案具有未定义的行为。 - Vlad from Moscow
是的,我理解你的意思并编辑了我的评论。来自俄罗斯的问候和感谢。 - Gooman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接