在 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+=3size-=3 交换,直到size&lt;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(例如&amp;array[i])而不是值(array[i])。做swap 的唯一其他方法是将整个数组加上2 个索引值传递给交换(例如swap (int *a, int i, int j) 交换元素ij),但你很少看到它这样做。跨度> 【参考方案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 中反转数组的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 在数组中计算反转

在C中打印反转的字符串/数组

如何反转字符串数组并使用指针反转每个字符串?

C语言九十五之实现经典的反转数组(通过指针或数组下标操作)

如何使用 XOR 赋值运算符 ^= 来反转 c 中的数组

javascript反转数组