Я определил эту структуру:
typedef struct Systems {
//stuff...
vector<double> list;
} System;
vector <System> system(100);
В определенный момент я хотел бы выполнить операцию на всех 100 записях system[i].list[0]
или же system[i].list[1]
Как это можно сделать?
на простой вектор STL я бы сделал:
upper_bound(list.begin() list.end(), R)-list.begin();
Но используя структуру, я обнаружил некоторые проблемы: например, я не могу использовать это:
upper_bound(system.begin().list[1], system.end().list[1], R)-system.begin().list[1];
Не могли бы вы помочь мне?
A.
Один из вариантов (который, возможно, не самый лучший) — создать свой собственный итератор:
class system_iterator :
public iterator< random_access_iterator_tag, double >
{
public:
system_iterator() {}
system_iterator(vector<System>::iterator itr, size_t idx)
: m_itr(itr), m_idx(idx) {}
bool operator ==(const system_iterator& rhs) const
{ return m_itr == rhs.m_itr; }
bool operator !=(const system_iterator& rhs) const
{ return m_itr != rhs.m_itr; }
double& operator *() const { return (*m_itr).list[m_idx]; }
system_iterator& operator ++() { ++m_itr; }
// Define other operations needed for random access iterator
private:
vector<System>::iterator m_itr;
size_t m_idx;
};
Теперь вы можете позвонить:
system_iterator begin( system.begin(), 1 ), end( system.end(), 1 );
System& s = system[ std::upper_bound( begin, end, R ) - begin ];
РЕДАКТИРОВАТЬ : Обновление решения после того, как плакат разъяснил, что он / она хотел сделать.
Отказ от ответственности: это не проверено.
Вы должны использовать вторую форму upper_bound
тот, который принимает значение и компаратор.
С лямбдами C ++ 11 это легко:
k = 5;
upper_bound(system.begin(),
system.end(),
R,
[k](double R, System& s) { return R <s.list[k]; });
Если вы не можете использовать C ++ 11, вам нужно написать функцию, которая принимает три аргумента, (int k, double R, System&)
с тем же телом лямбда выше имеет
— использовать std::tr1::bind
связать k
аргумент к этому. Что-то вроде
double func (int k, double R, System& s)
{
return R < s.list[k];
}
upper_bound(system.begin(),
system.end(),
R,
std::tr1::bind (func, k, _1, _2));
Вам наверное нужно using namespace std::tr1::placeholders
,
Конечно, в любом случае вы должны убедиться, что ваш массив отсортирован по list[k]
или хотя бы разделенный на w.r.t
Р.