简体   繁体   English

查找作为C ++类元素的2D向量的位置

[英]find position of a 2D vector which is an element of a class C++

I am working on a class that I have some problems in finding positions of values in one of elements of the class. 我在一个班上工作,在班上一个要素中寻找价值位置时遇到一些问题。 I have defined my class as follows: 我的班级定义如下:

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];

In the class, bit is a 2D element and if I define it as m*n , all values in the rows are the same. 在该类中,bit是2D元素,如果我将其定义为m*n ,则行中的所有值都相同。 However, when I want to find position in bit , for example if popcurrent[0].bit for 2 rows and 3 columns is = { {3,2,1},{3,2,1} } , and I want to find position of the first " 3 " in the vector is 0 and popcurrent[0].bit[0][0]=3 , I have problems. 但是,当我想在bit查找位置时,例如,如果2行3列的popcurrent[0].bit是= { {3,2,1},{3,2,1} } ,我想在向量中找到第一个“ 3 ”的位置是0并且popcurrent[0].bit[0][0]=3 ,我遇到了问题。

Specificaly I tried c++ search a vector for element first seen position with the following commands: 具体来说,我尝试使用以下命令通过c ++在向量中搜索元素首次看到的位置

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

But I get following error: 但是我得到以下错误:

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

I know one way is to use for and if loops. 我知道一种方法是使用for和if循环。 But I wonder is there any more automated way to do this such as build in functions. 但是我想知道还有没有更多的自动化方法可以做到这一点,例如内置函数。

I didn't notice it at first - there's too much irrelevant code - but the problem is quite simple: you're trying to find the first element of type std::vector<int> not less than value of type int . 起初我没有注意到它-太多无关的代码-但问题很简单:您试图找到std::vector<int>类型的第一个元素不少于int类型的值。

popcurrent[0].bit.begin() points to the first element of std::vector<std::vector<int>> , that is a vector. popcurrent[0].bit.begin()指向std::vector<std::vector<int>>的第一个元素,即向量。 There's no "less than" operator for comparing a vector of ints and an int. 没有用于比较整数向量和整数的“小于”运算符。

I want to find position of the first " 3 " in the vector is 0 and popcurrent[0].bit[0][0] = 3 , I have problems. 我想找到向量中第一个“ 3 ”的位置是0,而popcurrent[0].bit[0][0] = 3 ,我遇到了问题。 Specificaly I tried c++ search a vector for element first seen position with the following commands: 具体来说,我尝试使用以下命令通过c ++在向量中搜索元素首次看到的位置:

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

There are mainly two problems: 主要有两个问题:

Problem - 1: std::lower_bound takes parameters first , last , which are forward-iterator types which defining the partially-ordered range. 问题-1: std::lower_bound接受参数firstlast ,它们是正向迭代器类型,用于定义部分排序的范围。 In your case( popcurrent[0].bit.begin( )), you are passing a iterator which has the pointed element as a vector of integers (remember std::vector<std::vector<int>> is an array of vectors( vector<int> ) not integers) for which std::lower_bound , could not find any definition for operator< . 在您的情况下( popcurrent[0].bit.begin( )),您正在传递一个迭代器,该迭代器的尖元素为整数向量 (请记住std::vector<std::vector<int>>是一个数组为std::lower_bound找不到operator<任何定义的vectors( vector<int>vector<int> )不是整数)。 This is the reason of your error, where compiler complaining that: 这是您出错的原因,其中编译器抱怨:

" Hey, I don't have a specialisation for operator< your given range or vectors, to instantiate the template " 嘿,我没有专门的operator<您给定的范围或向量,以实例化模板

Problem - 2: You can not use std::lower_bound here, as it needs a strictly sorted array to binary search the value which has been provided. 问题-2:您不能在此处使用std::lower_bound ,因为它需要严格排序的数组才能对提供的值进行二进制搜索。 As you provided an unsorted vectors to check, the result won't be correct. 由于您提供了未排序的向量进行检查,因此结果将不正确。 See above link to read more: 请参阅上面的链接以了解更多信息:


Solution: You can use std::find_if which has a time complexity, up to linear in the distance between first and last iterator, according to the predicate provided, which will search for each element until a match is found. 解决方案:您可以使用std::find_if ,它具有时间复杂度,根据提供的predicate ,它在firstlast迭代器之间的距离最大为线性 ,它将搜索每个元素,直到找到匹配项。 This could be an alternative if you do not want to sort each vector in the class, which is actually a 3-dimensional array of vectors. 如果您不想对类中的每个向量进行排序,这实际上是3维向量数组,则可以选择这种方法。

Following is a sample solution: 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;
}

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM