C 逆时针遍历二维阵列的周长

C 逆时针遍历二维阵列的周长,c,arrays,C,Arrays,这是我关于堆栈溢出的第一个问题,如果我没有正确遵守社区的指导原则和约定,请告诉我 从第0行,第0列(最好不重新访问每个元素)沿逆时针(或顺时针)方向遍历2D数组周长的聪明方法是什么 直观地说,我可以为每个方向依次编写四个for循环(即,为编写一个for循环以遍历左列,然后为编写一个for循环以遍历底行,依此类推)。但这种解决方案感觉是“硬编码的” 是否存在一种“快捷方式”方法可以利用此模式的一些关键洞察?这种快捷方式在程序运行时是否也有效 提前谢谢 编辑特定性: 具体地说,我试图从第0行,第0

这是我关于堆栈溢出的第一个问题,如果我没有正确遵守社区的指导原则和约定,请告诉我

第0行
第0列
(最好不重新访问每个元素)沿逆时针(或顺时针)方向遍历2D数组周长的聪明方法是什么

直观地说,我可以为每个方向依次编写四个
for
循环(即,为
编写一个
for
循环以遍历左列,然后为
编写一个
for
循环以遍历底行,依此类推)。但这种解决方案感觉是“硬编码的”

是否存在一种“快捷方式”方法可以利用此模式的一些关键洞察?这种快捷方式在程序运行时是否也有效

提前谢谢


编辑特定性:

具体地说,我试图从
第0行
第0列
,逆时针遍历这个2D数组,并且只打印每个元素一次

假设数组如下所示:
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20

我的预期产出如下:
1,6,11,16,17,18,19,20,15,10,5,4,3,2

以下是我当前的解决方案(此解决方案有效):

//在左侧循环。
int i;
对于(i=0;i=0;i--)
printf(“%d”,数组[i][columns-1]);
//从上面绕过去。
对于(i=columns-2;i>1;i--)
printf(“%d”,数组[0][i]);
//打印最后一个元素。
printf(“%d.\n”,数组[0][1]);
就我个人而言,我的解决方案似乎简单而重复。我想知道是否有更具创造性的解决方案


如果需要进一步澄清,请告诉我。

就我个人而言,我认为您描述为“硬编码”的四个循环确实是最好和最清晰的解决方案。也就是说,对于数组[N][M],在一个循环中有两个选项:

for(int row = 0, col = 0, i = 0; i < 4;) {
  //process
  switch(i) {
    case 0: 
      if(++row == N)
        ++i;
      break;
    case 1: 
      if(++col == M)
        ++i; 
      break;
    case 2: 
      if(--row == 0)
        ++i;
      break;
    case 3:
      if(--col == 0)
        ++i;
      break;
  }
}
for(int行=0,列=0,i=0;i<4;){
//过程
开关(一){
案例0:
如果(++行==N)
++一,;
打破
案例1:
如果(++col==M)
++一,;
打破
案例2:
如果(--行==0)
++一,;
打破
案例3:
如果(--col==0)
++一,;
打破
}
}

intdirs[][]={{1,0},{0,1},{-1,0},{0,-1};
for(int行=0,列=0,i=0;i<4;){
//过程
if(dirs[i][0]&((row+=dirs[i][0])==0 | | row==N)||
dirs[i][1]&((col+=dirs[i][1])==0 | | col==M))
++一,;
}
注意:所有与0的比较都可以用否定替换<代码>(a==0)=(!a)
适用于所有整数类型

说明: 这两种解决方案都利用了沿某个方向移动直到达到最大/最小值的思想,并增加计数器以跟踪状态。一个使用switch语句来处理状态,另一个使用内存中的数组。对于第二种解决方案,我们只在正在更改的内容(行或列)达到最大值或最小值时才切换状态。我们不关心以0更改的内容是否处于最大值或最小值,这不会更改状态


不过,我要重申,最好的解决方案是使用您提到的四个循环,为了避免重复,请在每个循环中调用一个函数。

我个人认为,您描述为“硬编码”的四个循环确实是最好和最清晰的解决方案。也就是说,对于数组[N][M],在一个循环中有两个选项:

for(int row = 0, col = 0, i = 0; i < 4;) {
  //process
  switch(i) {
    case 0: 
      if(++row == N)
        ++i;
      break;
    case 1: 
      if(++col == M)
        ++i; 
      break;
    case 2: 
      if(--row == 0)
        ++i;
      break;
    case 3:
      if(--col == 0)
        ++i;
      break;
  }
}
for(int行=0,列=0,i=0;i<4;){
//过程
开关(一){
案例0:
如果(++行==N)
++一,;
打破
案例1:
如果(++col==M)
++一,;
打破
案例2:
如果(--行==0)
++一,;
打破
案例3:
如果(--col==0)
++一,;
打破
}
}

intdirs[][]={{1,0},{0,1},{-1,0},{0,-1};
for(int行=0,列=0,i=0;i<4;){
//过程
if(dirs[i][0]&((row+=dirs[i][0])==0 | | row==N)||
dirs[i][1]&((col+=dirs[i][1])==0 | | col==M))
++一,;
}
注意:所有与0的比较都可以用否定替换<代码>(a==0)=(!a)
适用于所有整数类型

说明: 这两种解决方案都利用了沿某个方向移动直到达到最大/最小值的思想,并增加计数器以跟踪状态。一个使用switch语句来处理状态,另一个使用内存中的数组。对于第二种解决方案,我们只在正在更改的内容(行或列)达到最大值或最小值时才切换状态。我们不关心以0更改的内容是否处于最大值或最小值,这不会更改状态


不过我要重申,最好的解决方案是使用您提到的四个循环,为了避免重复,请在每个循环中调用一个函数。

硬编码?二维阵列的其他形状是什么?只有在不使用变量(或者
#define
)控制循环限制的情况下,它才是硬编码的。您没有正确遵循社区指南和约定。咨询handy怎么样,它告诉你可以问什么样的问题,并建议你如何提问?除此之外,您会发现,我们希望您提出关于特定问题的问题(您的问题不是),最好可以用一个示例来演示。概括为“我不知道如何解决这个问题”的广泛问题往往不受欢迎。@WeatherVane嗨,谢谢你的回复!我的意思是代码的结构似乎是重复的。@JohnBollinger我应该包括我的代码吗?我只是在寻找一个独特或聪明的解决方案来解决这个问题。@FridaySky编码可能非常重复。根据您环绕二维数组的原因,您可能只需要两个循环,每对边一个循环。硬编码?还有其他的吗
int dirs[][] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

for(int row = 0, col = 0, i = 0; i < 4;) {
  //process
  if( dirs[i][0] && ((row += dirs[i][0]) == 0 || row == N) ||
      dirs[i][1] && ((col += dirs[i][1]) == 0 || col == M))
    ++i;
}