简体   繁体   English

在 C++ 中,我如何编写一个 function 在指定的 position 处翻转二维数组?

[英]In C++, how can I write a function that flips a 2d array at a specified position?

For my 2d array in C++, the 2d array needs to be flipped at a certain position.对于我在 C++ 中的二维数组,二维数组需要在某个 position 处翻转。 I have to write a function that flips the array Foe instance, Before:我必须编写一个翻转数组 Foe 实例的 function,之前:

double A[][2] = {{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}}
                                         A     B     C       D

call function invert(or flip): invert(A, 8, 3, 4);调用 function 反转(或翻转): invert(A, 8, 3, 4); after:后:

double A[][2] = { {0, 0}, {1, 1}, {2, 2},{6, 6}, {5, 5}, {4, 4}, {3, 3}, {7, 7}}
                                            D      C        B      A

Here is the attempt I have tried这是我尝试过的尝试

  • @param A is the list of locations (x,y) of the cities in the current tour. @param A 是当前游览中城市的位置 (x,y) 列表。
  • @param n is the number of cities in A. @param n 是 A 中的城市数。
  • @param start is the index of the beginning of the section to be inverted. @param start 是要反转的部分开头的索引。
  • @param len is the length of the segment to invert(or flip). @param len 是要反转(或翻转)的段的长度。
    void invert ( double A[][2], int n, int start, int len ) {
          int(*tmp)[2] = new int[][2];
          for(int i = 0; i >= A.length; i--){
               for(int j = 0; j >= A[i].length; j--){
                    if( i > start)
                        tmp = A[i][j];
                 }
           }
               for(i = start; i < A.length; i++)
                  for(j = start; j < A[i].length; j++){
                     while (i <= end){
                        tmp = A[i][j];
                   }
                }
       }

The errors I have are我的错误是

  • expressions must have class type表达式必须具有 class 类型
  • a value of type double cannot be assigned to an entity of type "double(*)[2] double 类型的值不能分配给“double(*)[2] 类型的实体”
  • cannot determine which instance of overload function "end" is intended无法确定哪个过载实例 function “结束”是意欲的

I am fully aware that most of the errors in my code are evident to find, but I needed to start somewhere.我完全清楚我的代码中的大多数错误都很明显可以找到,但我需要从某个地方开始。

I admit, I don't know how to do it with a 2D C-array.我承认,我不知道如何使用 2D C 阵列来做到这一点。 I can only tell you about the simple way to do it.我只能告诉你简单的方法。

First, a general advice: Name your stuff.首先,一般建议:命名你的东西。 What if I had to read only your code to see that you are dealing with locations of cities, that have x and y coordinates, instead of having to read your text, wouldn't that be great?如果我只需要阅读您的代码就可以看到您正在处理具有 x 和 y 坐标的城市位置,而不必阅读您的文本,那不是很好吗?

Next, for resizable arrays, you can (/should) use std::vector instead of C-arrays.接下来,对于可调整大小的 arrays,您可以(/应该)使用std::vector代替 C 数组。 C-arrays decay to pointers when passed to functions. C 数组在传递给函数时会衰减为指针。 C-arrays have their size as part of their type, but it is inconvenient to access it (and impossible once decayed to a pointer). C 数组的大小是其类型的一部分,但访问它很不方便(一旦衰减为指针就不可能了)。 And manually resizing dynamic C-arrays isn't much fun either.手动调整动态 C 数组的大小也不是很有趣。

Eventually, the "simple way" is to use an existing algorithm.最终,“简单的方法”是使用现有的算法。 To reverse elements in a range it is std::reverse :要反转范围内的元素,它是std::reverse

#include <iostream>  
#include <vector>
#include <algorithm>

struct location {
    int x;
    int y;
};

int main() {

    std::vector<location> cities{{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}};
    for (const auto& loc : cities){
        std::cout << loc.x << " " << loc.y << "\n";
    } 
    std::cout << "\n";
    std::reverse(cities.begin()+ 3,cities.begin() + 7);
    for (const auto& loc : cities){
        std::cout << loc.x << " " << loc.y << "\n";
    } 
    
}

Output: Output:

0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7

0 0
1 1
2 2
6 6
5 5
4 4
3 3
7 7

Actually with a 1-D c-array it is almost the same.实际上,对于一维 c 阵列,它几乎是一样的。 The major difference is that c-arrays do not have begin as member.主要区别在于 c 数组没有begin作为成员。 This produces same output as above:这将产生与上述相同的 output:

location cities2[] = {{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}};
for (const auto& loc : cities2){
    std::cout << loc.x << " " << loc.y << "\n";
} 
std::cout << "\n";
std::reverse(std::begin(cities2)+ 3,std::begin(cities2) + 7);
for (const auto& loc : cities2){
    std::cout << loc.x << " " << loc.y << "\n";
} 

And if you want to wrap it in a function you need to take care of the array decaying to a pointer:如果你想把它包装在 function 中,你需要注意数组衰减到一个指针:

void my_reverse(location* loc, size_t len, size_t first, size_t last){
    std::reverse(loc + first, loc + last + 1);
}

(I choose last to be the last element to be reversed. Note that the algorithm takes an iterator to the element one past the last element to be reversed). (我选择last作为要反转的最后一个元素。请注意,该算法将迭代器带到要反转的最后一个元素之后的元素)。

Complete example with all three variants: https://godbolt.org/z/WMdea7WP3包含所有三个变体的完整示例: https://godbolt.org/z/WMdea7WP3

That's how I'd write the function if I knew it would always be used with 2 column arrays如果我知道 function 将始终与 2 列 arrays 一起使用,我就是这样写的

void invert(double cities[][2], int size, int start, int len) {
    if (size < 0 || len < 0)
        return;

    double tempCoordsX, tempCoordsY;
    int endPos = start + len - 1;

    for (int i = start; i < (start + len/2); i++) {
        int mirroredPos = (endPos - (i - start)) % size;

        tempCoordsX = cities[i][0];
        tempCoordsY = cities[i][1];
        cities[i][0] = cities[mirroredPos][0];
        cities[i][1] = cities[mirroredPos][1];
        cities[mirroredPos][0] = tempCoordsX;
        cities[mirroredPos][1] = tempCoordsY;
    }

}

I repeat: please name your stuff我再说一遍:请给你的东西命名

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM