Как лучше создать subj?
Гуру, посоветуйте!
... << RSDN@Home 1.1.3 beta 1 >>
Здравствуйте, ss_greh, Вы писали:
_>Как лучше создать subj?
Сначала определится с удобным тебе порядком обхода, а потом просто создать и все
... << RSDN@Home 1.1.0 stable >>
Здравствуйте, v_su, Вы писали:
_>>Как лучше создать subj?
_>Сначала определится с удобным тебе порядком обхода, а потом просто создать и все
С порядком я давно определился
Вопрос в другом: должен ли это быть один итератор, или два — в двух измерениях.
Один — неудобно пользоваться. Как прикажите получить значение из точки 18x34?
Т.е. как получить понятно — но неудобно.
Два — ? Непонятно какой из них разыменовывать и как их получать. Один через другой?
Да и как быть в этом случае с концепцией итераторов как абстракцией указателей?
Или тогда внешний итератор будет итератором итераторов? Короче одни вопросы.
Здравствуйте, ss_greh, Вы писали:
_>>>Как лучше создать subj?
_>>Сначала определится с удобным тебе порядком обхода, а потом просто создать и все
_>С порядком я давно определился
_>Вопрос в другом: должен ли это быть один итератор, или два — в двух измерениях.
_>Один — неудобно пользоваться. Как прикажите получить значение из точки 18x34?
_>Т.е. как получить понятно — но неудобно.
Итератор это последовательный перебор через ++, а уж эту последовательность можешь задать в его реализации. Если твой итератор перебирает все элементы построчно по возрастанию индекса столбца, то
iter = arr.my_begin();
cout << *(iter + 18 * arr.colsize() + 34);
... << RSDN@Home 1.1.0 stable >>
Здравствуйте, ss_greh, Вы писали:
_>Вопрос в другом: должен ли это быть один итератор, или два — в двух измерениях.
_>Один — неудобно пользоваться. Как прикажите получить значение из точки 18x34?
_>Т.е. как получить понятно — но неудобно.
_>Два — ? Непонятно какой из них разыменовывать и как их получать. Один через другой?
_>Да и как быть в этом случае с концепцией итераторов как абстракцией указателей?
_>Или тогда внешний итератор будет итератором итераторов? Короче одни вопросы.
N-мерный массив (гиперкуб) можно рассматривать как 1-мерный массив N-1-мерных срезов, зафиксировав любой индекс.
Срез k-го порядка (k-мерный гиперкуб) определяется N-k фиксированными индексами и k свободными.
Срез 0-го порядка — это отдельный элемент.
Адрес k-го порядка — указывает на соответствующий срез.
Соответственно, итератор k-го порядка — это адрес k-го порядка, в котором определено, какой из фиксированных индексов варьируется.
Домен итераторов k-го порядка — это N-k-1 фиксированных индексов и номер 1 скользящего.
У среза k-го порядка можно взять N-k разных доменов k-1 порядка. Из них "естественным" будет тот, у кого номер свободного индекса наименьший.
Адрес k-го порядка может быть значением N-k разных итераторов.
Эскиз
template<int N, class E>
class hypercube
{
public:
typedef int dimension; // 0..N
typedef int range; // -1, 0..+oo
const range FREEINDEX = -1;
struct indexvector { range i[N]; }; // -1 значит свободный индекс
const indexvector& sizes() const;
E& at(const indexvector& ii) // пофиг константность
{
assert(find(ii.i, ii.i+N, FREEINDEX)==ii.i+N); // все индексы связаны
// выдать элемент
}
slice all() { indexvector ii; fill(ii.i, ii.i+N, FREEINDEX); return slice(this, ii); }
struct slice
{
hypercube* hc;
indexvector ii; // k порядка (т.е. k значений свободны)
slice(hypercube*, indexvector);
domain subrange(dimension d) const
{
assert(ii[d] == FREEINDEX);
return domain(*this, d);
}
domain superrange(dimension d) const
{
assert(ii[d] != FREEINDEX);
indexvector jj = ii; jj[d] = FREEINDEX;
return domain(slice(hc, jj), d);
}
E& at() const { return hc->at(ii); } // можно только для 0 порядка
};
struct domain
{
slice sl; // k+1 порядка
dimension d; // номер скользящего индекса
domain(slice, dimension);
iterator begin() const { return iterator it(*this, 0); }
iterator end() const { return iterator it(*this, sl.hc->sizes()[d]); }
};
struct iterator
{
slice sl; // k порядка - это уже текущее значение
dimension d; // номер скользящего индекса
domain mydomain() const { return sl.superrange(d); }
iterator& operator++() { ++sl.ii[d]; return *this; }
iteratot& operator--() { --sl.ii[d]; return *this; }
slice operator*() const { return sl; }
slice* operator->() const { return &sl; }
};
};