Как реализовать замкнутый массив на C++?

352
19 декабря 2016, 19:45

Необходимо сделать массив на C++, например размера 4 (с индексами 0 1 2 3), чтобы в дальнейшем при оброщении к несуществующему элементу 4 программа выдавала значение с индексом 0, как это реализовать с условием ясно нужно вырозить доступ к элементам с помощью формулы. Возможно некоректно поставлен вопрос, но в итоги это заготовка программы которая должна создать двумерный массив замкнутый по всем концам как это происходит в фигуре Тор, для того чтобы в дальнейшем реализовать определение покрыий для карты Карно.

Answer 1

Для неотрицательных значений:

const int SIZE = 4;
int a[SIZE];
for(int i=0;i<15;i++) cout << a[i%SIZE] << " ";

% - остаток от деления, значения 0,1,2,3,0,1,2,3,0,...

Для отрицательных значений:

ряд чисел которые мы должны преобразовать:

-5,-4,-3,-2,-1,0,1,2,3,4,5...

Что мы должны получить (для SIZE=4):

3,0,1,2,3,0,1,2,3,0,1...

Вышеуказанный способ нам выдаст следующие значения:

-1,0,-3,-2,-1,0,1,2,3,0,1...

Мы можем ко всем этим значениям прибавить SIZE и тогда у нас все значения будут положительными, и вторично берем по модулю:

for(int i=-5;i<=5;i++)
{
    j=( (i%SIZE) + SIZE )%SIZE;
    cout << a[j] << " ";
}

Для упрощения понимания кода: Что бы в коде часто не встречались непонятные формулы используйте функцию или макрос, которая будет преобразовывать индексы.

например макрос:

#define GetIndex(_index,_size) ( ( (_index%_size) + _size )%_size )

Для двухмерного случая:

const int X_SIZE = 4;
const int Y_SIZE = 10;
int a[X_SIZE][Y_SIZE];
cin >> x >> y;
cout << a[GetIndex(x,X_SIZE)][GetIndex(y,Y_SIZE)];
Answer 2

Согласен, наследование от std::vector не самая лучшая идея и CyclicArray нужно использовать с осторожностью.

#include <vector>
#include <type_traits>
#include <iostream>
template <typename T>
class CyclicArray : public std::vector<T> {
 public:
  typedef typename std::vector<T>::size_type UnsignedIndex;
  typedef typename std::make_signed<UnsignedIndex>::type SignedIndex;
  using std::vector<T>::vector;
  T& operator[](SignedIndex index) {
    return GetElement(index);
  }
  const T& operator[](SignedIndex index) const {
    return GetElement(index);
  }
private:
  T& GetElement(SignedIndex index) {
    return std::vector<T>::operator[](NormalizeIndex(index));
  }
  const T& GetElement(SignedIndex index) const {
    return std::vector<T>::operator[](NormalizeIndex(index));
  }
  UnsignedIndex NormalizeIndex(SignedIndex index) {
    auto size = std::vector<T>::size();
    SignedIndex res = (index % size);
    if (res < 0) {
      res += size;
    }
    return static_cast<UnsignedIndex>(res);
  }
};
int main() {
  CyclicArray<int> a{1, 2, 3, 4};
  for (int i = -8; i < 9; ++i) {
    std::cout << i << ": " << a[i] << std::endl;
  }
  // 2-Dimensional
  CyclicArray<CyclicArray<int>> b{{1, 2, 3, 4},
                                  {5, 6, 7, 8},
                                  {9, 10, 11, 12},
                                  {13, 14, 15, 16}};
  for (int i = -4; i < 4; ++i) {
    for (int j = -4; j < 4; ++j) {
      std::cout << i << ", " << j << ": " << b[i][j] << std::endl;
    }
  }
}
READ ALSO
Генератор случайных чисел

Генератор случайных чисел

Не могу понять как заставить генератор случайных чисел давать дробные значенияПробовал сделать так

204
Стоит ли использовать Qt C++?

Стоит ли использовать Qt C++?

Всем привет, около месяца пишу на C++ и вот появилась мысль попробовать Qt, тем более он кроссплатформенный

244