найти положение двумерного вектора, который является элементом класса C ++ - PullRequest
0 голосов
/ 11 июня 2018

Я работаю над классом, у которого есть некоторые проблемы с поиском позиций значений в одном из элементов класса.Я определил свой класс следующим образом:

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

В классе бит является 2D-элементом, и если я определю его как m*n, все значения в строках будут одинаковыми.Однако, когда я хочу найти позицию в bit, например, если popcurrent[0].bit для 2 строк и 3 столбцов = = 1007 *, и я хочу найти позицию первого «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();

Но я получаю следующую ошибку:

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

Я знаю, один способ - использовать циклы for и if.Но мне интересно, есть ли более автоматизированный способ сделать это, например, встроить функции.

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Я хочу найти позицию первого "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 принимает параметры first, last, которые являются типами прямого итератора, которые определяют частично упорядоченный диапазон.В вашем случае (popcurrent[0].bit.begin()) вы передаете итератор с указанным элементом в виде вектором целых чисел (помните std::vector<std::vector<int>> - это массив векторов (vector<int>), а не целые числа) длякоторый std::lower_bound не смог найти определения для operator<.Это причина вашей ошибки, когда компилятор жаловался, что:

" Эй, у меня нет специализации для operator< вашего заданного диапазона или векторов, чтобы создать экземпляршаблон "

Проблема - 2: Вы не можете использовать std::lower_bound здесь, так как ему нужен строго отсортированный массив для двоичного поиска значения, котороебыл предоставлен.Поскольку вы предоставили несортированные векторы для проверки, результат не будет правильным.См. Ссылку выше, чтобы узнать больше:


Решение: Вы можете использовать std::find_if, который имеет временную сложность, до линейного на расстоянии между first и last итератором, согласно предоставленному predicate, который будет искать каждый элемент, пока не будет найдено совпадение.Это может быть альтернативой, если вы не хотите сортировать каждый вектор в классе, который на самом деле является трехмерным массивом векторов.

Ниже приведен пример решения: СМОТРИТЕ ЗДЕСЬ

#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
0 голосов
/ 11 июня 2018

Сначала я этого не заметил - слишком много неуместного кода - но проблема довольно проста: вы пытаетесь найти первый элемент типа std::vector<int> не меньше, чем значение типа int.

popcurrent[0].bit.begin() указывает на первый элемент std::vector<std::vector<int>>, то есть вектор.Для сравнения вектора целочисленных значений и целых чисел не существует оператора «меньше чем».

...