[英]Loop logic to store 2D array values in one liner vector
I have one requirement where I need to store 2 axis values into liner vector, some values like[x =0][y=1] and [y=0][x=1] i dint know how to save 我有一个要求,我需要将2个轴值存储到线性向量中,一些值[x = 0] [y = 1]和[y = 0] [x = 1]我确实知道如何保存
I simply added i+j to find index but it now working in all case 我只是添加了i + j来查找索引,但是现在在所有情况下都可以使用
I have 0>=x<=200 and 0>=y<=103 我有0> = x <= 200和0> = y <= 103
where x increment x= x+1 y increment y = y+1.5 其中x增量x = x + 1 y增量y = y + 1.5
is there any generic formula i can derive to save all data linearly 我可以导出任何通用公式来线性保存所有数据吗?
vector_1d_index = vector_2d_row_index * vector_2d_row_length + vector_2d_column_index
... assuming your 2D vector is i) row-major and ii) rectangular (uniform length rows). ...假设您的2D向量是i)行大和ii)矩形(等长行)。
( vector_1d_size = vector_2d_row_count * vector_2d_row_length
). (
vector_1d_size = vector_2d_row_count * vector_2d_row_length
)。
Your description is vague. 您的描述含糊不清。 But what I can gather is that you are looking to store values from 2-d indices in a 1-d array.
但是我可以收集的是,您正在寻求将二维索引中的值存储在一维数组中。 The general technique is to use something like follows:
通用技术是使用如下所示的内容:
Assume row, col
are 2-d index coordinates 假设
row, col
为row, col
索引坐标
<1-d index> = <max number of columns> * row + col
If I have understood right, you want a way to store a 2D float-indexed array in C++. 如果我没看错,您想要一种在C ++中存储2D浮点索引数组的方法。 You will need some conversion, because C++ "only support 1D arrays" (that isn't strictly true, but we will pretend that it is).
您将需要进行一些转换,因为C ++“仅支持1D数组”(严格来说并非如此,但我们会假装确实如此)。
First we need to know the ranges and the increments. 首先,我们需要知道范围和增量。 You provided them, and for X the range is
[0, 200]
and for Y [0, 103]
with increments 1
and 1.5
respectvely. 您提供了它们,对于X,范围是
[0, 200]
,对于Y [0, 103]
0,103 [0, 103]
,分别增加1
和1.5
。
That means we have ((200-0)/1) = 200
possible values for X and ((103-0)/1.5) = 68.666...
possible values for Y. We'll go with 69 possible values for Y. 这意味着我们有
((200-0)/1) = 200
可能的值, ((103-0)/1.5) = 68.666...
Y的可能值。我们将为Y选择69个可能的值。
So, we could have the following array: 因此,我们可以具有以下数组:
int my_array_of_ints[69 * 200];
For example, the item [X=0][Y=0]
will be our [0 * 69 + 0]
index (item my_array_of_ints[0]
), while our [X=1][Y=1.5]
will be our [1 * 69 + 1]
index (item my_array_of_ints[70]
). 例如,项目
[X=0][Y=0]
将是我们的[0 * 69 + 0]
索引(项目my_array_of_ints[0]
),而我们的[X=1][Y=1.5]
将是我们的[1 * 69 + 1]
索引(项目my_array_of_ints[70]
)。 Note that we can't have items with [Y=0.5] or [Y=1] because Y increment is fixed to 1.5 (ie Y must be 0 or 1.5 or 3 or 4.5 or 6 or ...). 请注意,因为Y的增量固定为1.5(即Y必须为0或1.5或3或4.5或6或...),所以我们不能使用[Y = 0.5]或[Y = 1]的项。
This function for converting the 2D index into a 1D linear index would be: 用于将2D索引转换为1D线性索引的函数为:
#include <cmath>
int get_element(float x, float y){
int index_x = std::round(x / 1);
int index_y = std::round(y / 1.5);
if ((0 <= index_x) && (index_x < 200) &&
(0 <= index_y) && (index_y < 69)){
return my_array_of_ints[index_y * 200 + index_x];
} else {
// You should decide what to do if x or y is out-of-range
return 0;
}
}
Where: 哪里:
1
is the increment of x 1
是x的增量 1.5
is the increment of y 1.5
是y的增量 200
is the number of possibles values of x in that range with this increment 200
是该范围内x的可能值的数量,此增量 69
is the number of possibles values of y in that range with this increment. 69
是此范围内y的可能值的数量。 So then we could do something like this: 所以我们可以做这样的事情:
get_element(1, 1.5)
And it would return the value of [X=1][Y=1.5]
inside my_array_of_ints
. 并且它将在
my_array_of_ints
内部返回[X=1][Y=1.5]
。
Wrapping this code around a class, templatizing the type of the array, generalizing the ranges and increments and providing a dummy main: 将此代码包装在一个类周围,对数组的类型进行模板化,概括范围和增量,并提供一个虚拟main:
#include <cmath>
#include <iostream>
template <typename Datatype> class Vector2D {
float x_increment;
float x_minimum;
float x_maximum;
float y_increment;
float y_minimum;
float y_maximum;
// For example, Y range [0, 103] with increment 1.5
// results in 69 possibles values for Y, and we need to
// remember to "linearize" the indexes
int x_possibles;
int y_possibles;
Datatype *array;
public:
Vector2D(float x_increment, float y_increment,
float x_maximum, float y_maximum,
float x_minimum=0, float y_minimum=0)
: x_increment(x_increment), x_minimum(x_minimum),
x_maximum(x_maximum), y_increment(y_increment),
y_minimum(y_minimum), y_maximum(y_maximum),
// These two may seem arcane, but they are the
// generalization of how we found the values initially
x_possibles(std::ceil((x_maximum-x_minimum)/x_increment)),
y_possibles(std::ceil((y_maximum-y_minimum)/y_increment)),
array(new Datatype[y_possibles * x_possibles]) {
// This may help to understand this 2D Vector
std::cout << "Creating 2D vector X in range ["
<< x_minimum << ", " << x_maximum
<< "] with increment of " << x_increment
<< " (totalizing " << x_possibles
<< " possible values for x) "
<< " and Y in range [" << y_minimum
<< ", " << y_maximum << "] with increment of "
<< y_increment << " (totalizing " << y_possibles
<< " values for y)."
<< std::endl;
}
// Frees up the raw array
~Vector2D(){
delete this->array;
}
Datatype& get_element(float x, float y){
int index_x = std::round((x-x_minimum)/this->x_increment);
int index_y = std::round((y-y_minimum)/this->y_increment);
// This debug message may help understand this function
// It is, in some sense, the answer of this question
std::cout << "The 2D point [X=" << x << ", Y=" << y
<< "] is mapped into the vector index ["
<< index_y << " * " << x_possibles
<< " + " << index_x << "]" << std::endl;
if ((0 <= index_x) && (index_x < x_possibles) &&
(0 <= index_y) && (index_y < y_possibles)){
return this->array[index_y * x_possibles + index_x];
} else {
// You should decide what to do if x or y is out-of-range
return this->array[0];
}
}
};
int main(){
// And you could use that class like this:
// A 2D-like vector with X [0, 200] inc. 1
// and Y [0, 103] inc. 1.5 of floats
Vector2D<float> my_data(1, 1.5, 200, 103, 0, 0);
// Sets [X=1][Y=1] to 0.61345
my_data.get_element(1, 1) = 0.61345;
auto elem1 = my_data.get_element(1, 1);
// Prints the [X=1][Y=1] to screen
std::cout << "[X=1][Y=1] is "
<< elem1
<< std::endl;
// Gets a few more interesting points
my_data.get_element(0, 0);
my_data.get_element(1, 1.5);
my_data.get_element(10, 15);
my_data.get_element(200, 103);
// A separator
std::cout << "---" << std::endl;
// Another example, this time using chars
// X is [-10, 1] inc. 0.1 and Y is [-5, 3] inc. 0.05
Vector2D<char> my_chars(0.1, 0.05, 1, 3, -10, -5);
// Sets [X=-4.3][Y=2.25] to '!'
my_chars.get_element(-4.3, 2.25) = '!';
auto elem2 = my_chars.get_element(-4.3, 2.25);
std::cout << "[X=-4.3][Y=2.25] is "
<< elem2
<< std::endl;
}
Outputs: 输出:
Creating 2D vector X in range [0, 200] with increment of 1 (totalizing 200 possible values for x) and Y in range [0, 103] with increment of 1.5 (totalizing 69 values for y).
The 2D point [X=1, Y=1] is mapped into the vector index [1 * 200 + 1]
The 2D point [X=1, Y=1] is mapped into the vector index [1 * 200 + 1]
[X=1][Y=1] is 0.61345
The 2D point [X=0, Y=0] is mapped into the vector index [0 * 200 + 0]
The 2D point [X=1, Y=1.5] is mapped into the vector index [1 * 200 + 1]
The 2D point [X=10, Y=15] is mapped into the vector index [10 * 200 + 10]
The 2D point [X=200, Y=103] is mapped into the vector index [69 * 200 + 200]
---
Creating 2D vector X in range [-10, 1] with increment of 0.1 (totalizing 110 possible values for x) and Y in range [-5, 3] with increment of 0.05 (totalizing 160 values for y).
The 2D point [X=-4.3, Y=2.25] is mapped into the vector index [145 * 110 + 57]
The 2D point [X=-4.3, Y=2.25] is mapped into the vector index [145 * 110 + 57]
[X=-4.3][Y=2.25] is !
Hope that may help. 希望对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.