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