代码之家  ›  专栏  ›  技术社区  ›  Sijith

在一个线性向量中存储二维数组值的循环逻辑

  •  0
  • Sijith  · 技术社区  · 6 年前

    我只是简单地添加了I+j来查找索引,但它现在在所有情况下都能工作

    我有0>=x<=200和0>=是<=103

    其中x增量x=x+1 y增量y=y+1.5

    有什么通用公式可以用来线性保存所有数据吗

    3 回复  |  直到 6 年前
        1
  •  1
  •   meowgoesthedog    6 年前
    vector_1d_index = vector_2d_row_index * vector_2d_row_length + vector_2d_column_index
    

    ... 假设二维向量是i)行主向量和ii)矩形(等长行)。

    ( vector_1d_size = vector_2d_row_count * vector_2d_row_length ).

        2
  •  0
  •   nakiya    6 年前

    row, col 是二维索引坐标

    <1-d index> = <max number of columns> * row + col
    
        3
  •  0
  •   Gabriel Francischini    6 年前

    如果我理解正确,你希望在C++中存储一个2D浮动索引数组。你需要一些转换,因为C++只支持一维数组(这不是严格的,但是我们会假装它是)。

    首先我们需要知道范围和增量。你提供了它们,对于X,范围是 [0, 200] [0, 103] 以增量 1 1.5 恭敬地。

    ((200-0)/1) = 200 X和X的可能值 ((103-0)/1.5) = 68.666... Y的可能值。我们将得到Y的69个可能值。

    因此,我们可以得到以下数组:

    int my_array_of_ints[69 * 200];
    

    [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] ). 请注意,我们不能有带有[Y=0.5]或[Y=1]的项,因为Y增量固定为1.5(即Y必须是0或1.5或3或4.5或6或……)。

    #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;
        }
    }
    

    哪里:

    • 1
    • 1.5 是y的增量
    • 200 是该范围内x的可能值的个数
    • 69 是该范围内y的可能值的个数。

    get_element(1, 1.5)
    

    它将返回 里面 my_array_of_ints

    #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;
    
    }
    

    输出:

    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 !
    

    希望这能有所帮助。