代码之家  ›  专栏  ›  技术社区  ›  Yanshof

如何根据某个字段在数组中查找元素(不使用for循环扫描整个数组)

  •  0
  • Yanshof  · 技术社区  · 6 年前

    我有4个字段的结构 我将这个结构的100个实例保存在某个数组(而不是映射)中,我想找到 数组中根据特定字段的某些元素

    我可以扫描所有,但我可以使用也许 std::find 或者其他方法(我知道find扫描所有数组,但我认为使用find很简单。)

    代码:

    struct MyElement 
    {
        std::string val1;
        std::string val2;
        std::string val3;
    }
    
    std::array<MyElement, 100> _myArray;
    
    
    // need to find the first element that the val2 is 'Go' 
    bool found = false; 
    for(int i = 0; i < 100 ; i++)
    {
        if(_myArray[i].val2 == 'Go')
        {
            found = true;
            break;
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   lubgr    6 年前

    如果 MyElement 实例未排序,无法避免对特定对象进行线性扫描。 std::find_if 你的朋友在这里,你可以用它来避免手写的循环,它会在第一场比赛时停止。例子:

    #include <algorithm>
    #include <cassert>
    
    std::array<MyElement, 100> _myArray;
    
    _myArray[50] = { "...", "Go", "..." };
    
    const auto lookup = std::find_if(_myArray.cbegin(), _myArray.cend(),
        [](const MyElement& e){ return e.val2 == "Go"; });
    
    assert(lookup == _myArray.cbegin() + 50);
    

    如果需要重复查找元素,那么首先对序列进行排序,然后使用二进制搜索可能比较有利:

    const auto binaryPred =  [](const MyElement& e1, const MyElement& e2){
         return e1.val2 < e2.val2;  };
    
    std::sort(_myArray.begin(), _myArray.end(), binaryPred);
    
    const auto fasterLookup = std::lower_bound(_myArray.cbegin(), _myArray.cend(), "Go",
            [](const MyElement& e, const auto& value){ return e.val2 == value; });
    

    但是,如果不知道确切的情况,这是否会有回报是无法预测的。如果不确定,测量两种方法。