在 C 中反转数组
Posted
技术标签:
【中文标题】在 C 中反转数组【英文标题】:Reversing arrays in C 【发布时间】:2016-04-23 04:11:16 【问题描述】:我正在尝试制作一个程序,该程序接受一个数组并将其向后还原,但是该程序必须以三个一组的方式对数组执行此操作。因此,如果用户在数组中输入数字 1、2、3、4、5、6,程序将输出:3、2、1、6、5、4。
当我运行当前程序时,我得到:3 2 1 4 5 6。如果有人能帮我弄清楚为什么这会很好,因为我有点困惑。
这是我的代码:
int * numbersProcessFour(int *x, int size)
int i = 0, three = 3, six = 6, nine = 9;
if (size < 4)
for (i; i < three; i++)
reverse_array(x, three);
printf("%d ", x[i]);
else if (size > 3 && size < 7)
for (i; i < three; i++)
reverse_array(x, three);
printf("%d ", x[i]);
for (i; i < 6; i++)
reverse_array(x, three);
printf("%d ", x[i]);
else if (size > 6 && size < 10)
for (i; i < three; i++)
reverse_array(x, three);
printf("%d ", x[i]);
for (i; i < 6; i++)
reverse_array(x, three);
printf("%d ", x[i]);
for (i; i < 9; i++)
reverse_array(x, three);
printf("%d ", x[i]);
void reverse_array(int *x, int length)
int i, temp;
for (i = 0; i<length / 2; i++)
temp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = temp;
【问题讨论】:
有多种方法。您能否尝试先创建一个二维数组arr[SIZE][3]
,然后仅反转第一个维度。
你想太多了。只需将x[0]
与x[2]
、x+=3
和size-=3
交换,直到size<3
。如果是size==2
,则将x[0]
替换为x[1]
。
创建两个指针并交换第一个和第二个数组元素。
@user3386109 你对我想太多了。这让我很生气...我根据请求更改了我的 reverse_array 函数,但这并不能解决我将打印输出作为最终结果的问题。仍然得到 3 2 1 4 5 6
【参考方案1】:
继续从您的评论到颤振的回答,您可能会想得有点过头了。为了交换数组的每个 3 元素分区中的第 1 个和第 3 个元素,您只需一次遍历数组 3 个元素。您需要决定如何处理任何最终的部分分区,但由于您的目标是交换第一个和第三个,因此在小于完整分区的任何地方都没有第三个,因此逻辑选择是忽略任何最终的部分分区。
您和 fluter 所做的合并 swap
的变体是:
/* reverse 1st and 3rd element in each group of 3 */
void rev3 (int *a, size_t sz)
if (sz < 3) return;
size_t i;
for (i = 0; i < sz; i += 3)
if (sz - i < 3) break;
swap (&a[i], &a[i+2]);
你可以把它和:
#include <stdio.h>
void rev3 (int *a, size_t sz);
void swap (int *a, int *b);
int main (void)
int a[] = 1,2,3,4,5,6,7,8,9;
size_t i;
rev3 (a, sizeof a/sizeof *a);
for (i = 0; i < sizeof a/sizeof *a; i++) printf (" %2d", a[i]);
putchar ('\n');
return 0;
void swap (int *a, int *b)
int t = *a;
*a = *b;
*b = t;
使用示例
编译并运行后,它将为您提供问题中指定的整个数组中第一个和第三个元素的交换(反转)。
$ ./bin/revarr3
3 2 1 6 5 4 9 8 7
无论您使用单独的swap
还是将该操作包含在您的反转函数中,都没有区别。当过程方法有效时,也不需要额外听到调用递归函数的情况。查看所有答案并比较/对比实现目标的不同方法。
【讨论】:
感谢您的详细解释。虽然我对交换功能有疑问。我只有一个数组(指针)进入该函数。它仍然如何工作?另外,如果我想删除任何多余的数字,我会怎么做? 嗯,你必须交换指针,而不是值,因为当你将值作为参数传递给任何函数(包括swap
)时,函数会收到一个 copy值(存储在不同的地址),因此如果您尝试交换副本 - 调用函数中没有任何变化。因此,您将 pointer-to-the-value 传递给swap
(例如&array[i]
)而不是值(array[i]
)。做swap
的唯一其他方法是将整个数组加上2 个索引值传递给交换(例如swap (int *a, int i, int j)
交换元素i
和j
),但你很少看到它这样做。跨度>
【参考方案2】:
每个 3 的倍数都有分支,这是低效的。解决它的一种方法是您可以将数组拆分为 3 个较小的数组,然后对其进行反转。此外,反转 3 个元素的数组与交换第一个和第三个元素相同。
int i;
int temp;
for (i = 0; i < count; i += 3)
if (i+2 >= count)
break;
temp = arr[i];
arr[i] = arr[i+2];
arr[i+2] = temp;
【讨论】:
这是对我的 reverse_array 函数的调整。我最挣扎的部分是将数组分配给三个较小的数组。我觉得我真的想多了。 你不需要创建和分配更小的数组,你可以就地完成【参考方案3】:numberProcessFour
的通用版本可能如下所示。
int reverse_array_mod(int *input, size_t size, int mod)
int i, smod;
/* Error: return modulus if size cannot be divided by mod */
if(size%mod)
return size%mod;
smod = size/mod;
for(i=0; i<smod; i++)
reverse_array(input+i*mod, mod);
/* return 0 on success */
return 0;
测试
int main(int argc, char **argv)
int a[] = 0, 1, 2, 3, 4, 5;
int i, err, mod;
for(mod=1; mod<5; mod++)
err = reverse_array_mod(a, 6, mod);
if(err)
fprintf(stderr, "Error %d, modulus %d invalid\n", err, mod);
return err;
for(i=0; i<6; i++)
printf("%d\n", a[i]);
printf("\n");
return 0;
结果:
0
1
2
3
4
5
1
0
3
2
5
4
3
0
1
4
5
2
Error 2, modulus 4 invalid
【讨论】:
【参考方案4】:试试这个
int *numbersProcessFour(int *x, int size)
int i;
for(i = 0; i + 3 < size; i += 3)
reverse_array(x + i, 3);
if(size - i > 1)
reverse_array(x + i, size - i);
return x;
【讨论】:
以上是关于在 C 中反转数组的主要内容,如果未能解决你的问题,请参考以下文章