Если что-то решается во время выполнения, вам может понадобиться std::arrays
в качестве пары ключ-значение .
Есть много способов индексировать многомерные массивы с помощью одного for-l oop. Перейти от многомерного массива к одномерному массиву просто. Если i
, j
, k
- ваши индексы, тогда вы сохраните их в позиции index=k*N*N+j*N+i;
в многомерном массиве (где в вашем случае N=2*SIZE
. Если вы хотели ввести for (int i =-SIZE; i<=SIZE; i++)
, тогда у вас будет N=2*SIZE+1
). Итак, если у вас есть n-мерный массив, а index [k] - это массив индексов, вы можете упаковать его в одномерный индекс с помощью следующего алгоритма:
//dynamically allocated array of size depth
std::vector<int> index(depth,0);
// ... populate some interesting index here, where 0<=index[i]<N
//for depth=3, this would calculate 0*N*N*N+index[2]*N*N+index[1]*N+index[0].
int one_dimensional_index=0;
for(int i=depth-1; i>=0; i--) {
one_dimensional_index*=N;
one_dimensional_index+=index[i];
}
std::cout<<"Multidimensional index is stored at one-dimensional index: "<<one_dimensional_index<<std::endl;
Но если я правильно понимаю, вы хотите решить обратную задачу. Это можно сделать с помощью целочисленного деления и модульной арифметики c. (index[2]*N*N+index[1]*N+index[0])%N
- это просто index[0]
, а (index[2]*N*N+index[1]*N+index[0])/N
- это просто index[2]*N+index[1]
, поэтому, выполняя операции деления и по модулю, вы можете вернуть индексы. В конце концов, у вас будет реализация, которая выглядит примерно так:
std::vector<int> indexFromMulti(int one_dimensional_index,int nn, int depth){
std::vector<int> index(depth,0);
for(int i=0; i<depth; i++) {
index[i]=(one_dimensional_index%N);
one_dimensional_index/=N;
}
return index;
}
Вот полная реализация, которая выводит следующее для size = 1, depth = 4 и width = 4.
user@desktop:~$ g++ test.cpp
user@desktop:~$ ./a.out
qtable populated with:
qtable[{-1, -1, -1, -1}]=[4, 2, 3, 1];
qtable[{-1, -1, -1, 0}]=[3, 4, 5, 3];
qtable[{-1, -1, 0, -1}]=[1, 2, 3, 2];
(...)
qtable[{0, 0, -1, 0}]=[5, 3, 4, 5];
qtable[{0, 0, 0, -1}]=[3, 1, 5, 3];
qtable[{0, 0, 0, 0}]=[1, 1, 5, 3];
Исходный код:
#include <iostream>
#include <vector>
#include <map>
std::vector<int> indexFromMulti(int one_dimensional_index,int nn, int depth){
std::vector<int> index(depth,0);
for(int i=0; i<depth; i++) {
index[i]=(one_dimensional_index%nn);
one_dimensional_index/=nn;
}
return index;
}
//integer power from https://stackoverflow.com/a/1505791/13783653
int int_pow(int x, int p)
{
if (p == 0) return 1;
if (p == 1) return x;
int tmp = int_pow(x, p/2);
if (p%2 == 0) return tmp * tmp;
else return x * tmp * tmp;
}
//Function to print with pretty formatting
void print_qtable(std::map<std::vector<int>, std::vector<int>> qtable){
std::cout<<"qtable populated with: "<<std::endl;
for(auto iter = qtable.begin(); iter != qtable.end(); ++iter) {
std::cout<<"qtable[{";
for(size_t i=0;i<iter->first.size();i++){
std::cout<<iter->first[i];
if(i!=iter->first.size()-1)
std::cout<<", ";
}
std::cout<<"}]=[";
for(size_t i=0;i<iter->second.size();i++){
std::cout<<iter->second[i];
if(i!=iter->second.size()-1)
std::cout<<", ";
}
std::cout<<"];"<<std::endl;
}
}
std::map<std::vector<int>, std::vector<int>> qtable(int size, int depth, int breadth){
int nn=2*size;
int max_index=int_pow(nn,depth);
std::map<std::vector<int>, std::vector<int>> q_table;
for (int i=0;i<max_index;i++){
std::vector<int> key=indexFromMulti(i,nn,depth);
//change the interval [0,nn) to the interval [-size,size).
for(int j=0;j<depth;j++)
key[j]-=size;
//Fill in the value
std::vector<int> value(breadth,0);
for(int j=0;j<breadth;j++)
value[j] = (rand() % 5)+1;
q_table[key]=value;
}
return q_table;
}
int main() {
print_qtable(qtable(1,4,4));
return 0;
}