【问题标题】:find position of a 2D vector which is an element of a class C++查找作为 C++ 类元素的 2D 向量的位置
【发布时间】:2018-11-21 03:37:13
【问题描述】:

我正在研究一个类,在该类的一个元素中查找值的位置时遇到了一些问题。我将我的班级定义如下:

typedef class Chrom                                         
{
 public:
    vector<vector < int>> bit;                  
    vector<vector < bool>> jobisconsidered;

    vector<vector <float>> WaitingTime; 
    void variablesresize()
    {
        int i = 0, j, k;
        float a;

        std::vector<float> datapoints;
        std::ifstream myfile("Input.dat", std::ios_base::in);

        i = 0;                   //making zero counter of characters                        
        myfile.open("Input.dat");//now we reread numerical values                       

        while (!myfile.eof())
        {
            myfile >> a;
            //  cout << "i=" << i << '\n';              
            if (!myfile) // not an int                  
            {
                myfile.clear(); // clear error status               
                myfile.ignore(1); // skip one char at input             
            }
            else
            {
                datapoints.push_back(a);
                ++i;
            }
        }

        myfile.close();

        Jobs = datapoints[0];
        Machines = datapoints[1];

        WaitingTime.resize(Machines);
        bit.resize(Machines);

        for (int i = 0; i < Machines - 1; ++i)  WaitingTime[i].resize(Jobs);

        bit[i].resize(Jobs);
        }
    }
} c;

c popcurrent[50];

在类中,位是二维元素,如果我将其定义为m*n,则行中的所有值都是相同的。但是,当我想在bit 中查找位置时,例如,如果 2 行 3 列的popcurrent[0].bit 为 = { {3,2,1},{3,2,1} },我想找到向量中第一个“3”的位置为 0和popcurrent[0].bit[0][0]=3,我有问题。

具体来说,我使用以下命令尝试了c++ search a vector for element first seen position

auto p = std::lower_bound(popcurrent[0].bit.begin(), popcurrent[0].bit.end(), 1);
int position = p - popcurrent[0].bit.begin();

但我收到以下错误:

 Error  109 error C2893: Failed to specialize function template
'unknown-type std::less<void>::operator ()(_Ty1 &&,_Ty2 &&) const'

我知道一种方法是使用 for 和 if 循环。但我想知道有没有更自动化的方法来做到这一点,比如内置函数。

【问题讨论】:

  • 准备一个 MCVE (stackoverflow.com/help/mcve) 真的很有帮助 - 您的示例无法编译。另外,您使用的是哪个版本的 Visual Studio?

标签: c++ c++11 search multidimensional-array stdvector


【解决方案1】:

我想找到向量中第一个“3”的位置是 0 并且 popcurrent[0].bit[0][0] = 3,我有问题。具体我试过 c ++使用以下内容搜索元素第一次看到位置的向量 命令:

auto p=std::lower_bound(popcurrent[0].bit.begin(), popcurrent[0].bit.end(), 1);
int position = p - popcurrent[0].bit.begin();

主要有两个问题:

问题 - 1: std::lower_bound 接受参数 firstlast,它们是定义部分有序范围的前向迭代器类型。在你的情况下(popcurrent[0].bit.begin()),你传递了一个迭代器,它的指向元素是整数向量(记住std::vector&lt;std::vector&lt;int&gt;&gt;是一个向量数组(vector&lt;int&gt;)不是整数)对于 std::lower_bound,找不到 operator&lt; 的任何定义。这是您的错误的原因,编译器抱怨:

" 嘿,我没有专门针对 operator&lt; 你给定的范围 或向量,以实例化模板 "

问题 - 2: 你不能在这里使用std::lower_bound,因为它需要一个严格排序的数组来对提供的值进行二分搜索。由于您提供了未排序的向量来检查,结果将不正确。请参阅上面的链接以了解更多信息:


解决方案:您可以在firstlast迭代器之间的距离内使用具有时间复杂度线性std::find_if,根据predicate 提供,它将搜索每个元素,直到找到匹配项。如果您不想对类中的每个向量(实际上是向量的 3 维数组)进行排序,这可能是一种替代方法。

以下是示例解决方案:SEE LIVE HERE

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

typedef std::vector<std::vector < int>> Type ;
struct Chrom         // to demonstrate
{
  Type bit;
};

std::tuple<int, int, int> findPosition(const std::vector<Chrom>& vec3D, const int& val)
{
   int First = 0, Second = 0, Third = -1;   // initilize the positions
   for(const Chrom& each_chrom: vec3D)
   {
      for(const std::vector<int>& innerVec: each_chrom.bit)
      {
         std::vector <int>::const_iterator get_pos;
         get_pos = std::find(innerVec.cbegin(), innerVec.cend(), val);
         Third = (*get_pos == val) ? get_pos - innerVec.cbegin(): -1;   // check val found otherwise -1
         if(Third != -1) return std::make_tuple(First, Second, Third);  // if found return them
         ++Second;
      }
      Second = 0;
      Third = -1;
      ++First;
   }
   return std::make_tuple(First, Second, Third);
}

int main()
{
   // this is a 3 dimensional vector
   std::vector<Chrom> popcurrent(2);          //  position inside the popcurrent
   popcurrent[0].bit =  {  {3,2,1},           // (0,0,0) (0,0,1) (0,0,2)
                           {3,10,1}  };       // (0,1,0) (0,1,1) (0,1,2)
   popcurrent[1].bit =  {  {5,8,11},          // (1,0,0) (1,0,1) (1,0,2)
                           {4,7,1}  };        // (1,1,0) (1,1,1) (1,1,2)

   int pos_popcurrent, pos_bit, pos_inner_vec;
   for(int val = 1; val <= 12; ++val)
   {
      std::cout << "\nCurrently looking for: " << val ;
      std::tie(pos_popcurrent, pos_bit, pos_inner_vec) = findPosition(popcurrent, val);
      (pos_inner_vec != -1) ?
         std::cout << "  found @ popcurrent[ " << pos_popcurrent << " ].bit[ " << pos_bit << " ][ " << pos_inner_vec <<" ]":
         std::cout << "  Not found";
   }
   return 0;
}

输出:

Currently looking for: 1  found @ popcurrent[ 0 ].bit[ 0 ][ 2 ]
Currently looking for: 2  found @ popcurrent[ 0 ].bit[ 0 ][ 1 ]
Currently looking for: 3  found @ popcurrent[ 0 ].bit[ 0 ][ 0 ]
Currently looking for: 4  found @ popcurrent[ 1 ].bit[ 1 ][ 0 ]
Currently looking for: 5  found @ popcurrent[ 1 ].bit[ 0 ][ 0 ]
Currently looking for: 6  Not found
Currently looking for: 7  found @ popcurrent[ 1 ].bit[ 1 ][ 1 ]
Currently looking for: 8  found @ popcurrent[ 1 ].bit[ 0 ][ 1 ]
Currently looking for: 9  Not found
Currently looking for: 10  found @ popcurrent[ 0 ].bit[ 1 ][ 1 ]
Currently looking for: 11  found @ popcurrent[ 1 ].bit[ 0 ][ 2 ]
Currently looking for: 12  Not found

【讨论】:

  • 感谢@JeJo 的彻底回复,只是我在尝试运行代码时遇到了 2 个错误。对于“auto findPosition(const std::vector& vec3D, const int& val)”行中的 auto,我看到 Error 无法重载由 return 区分的函数,对于 auto,我看到 auto 函数需要尾随返回类型错误。有什么解决方法吗?
  • @questionaskerprogrammer 为了编译它,你需要一个编译器 gcc 4.8.1 或更高版本。这里auto findPosition(const std::vector&lt;Chrom&gt;&amp; vec3D, const int&amp; val) 代替auto 你也可以将实际返回类型写为std::tuple&lt;int, int, int&gt;。在答案中查看我更新的代码;我只是用实际类型替换了所有汽车。
  • 它没有完全工作,但经过一些调整我可以使用它。
【解决方案2】:

一开始我没有注意到 - 有太多不相关的代码 - 但问题很简单:你试图找到std::vector&lt;int&gt;类型的第一个元素不小于int类型的值。

popcurrent[0].bit.begin() 指向std::vector&lt;std::vector&lt;int&gt;&gt; 的第一个元素,即一个向量。没有用于比较整数向量和整数的“小于”运算符。

【讨论】:

    猜你喜欢
    • 2018-11-26
    • 2020-12-29
    • 1970-01-01
    • 2015-04-15
    • 2022-01-08
    • 2010-11-13
    • 2019-09-25
    • 1970-01-01
    相关资源
    最近更新 更多