【问题标题】:How do I reverse runs of nonnegative integers in an array in C?如何在 C 中的数组中反转非负整数的运行?
【发布时间】:2021-07-13 00:16:05
【问题描述】:

我需要在 C 中创建一个随机数组,在其中找到非负值,当连续至少有 2 个时,将它们反转。例如,如果我有随机数组5 6 -7 -8 9 -4 7 8 2 -2,我需要得到6 5 -7 -8 9 -4 2 8 7 -2。这是我迄今为止尝试过的:

    #include <stdio.h>
#include <stdlib.h>
 int ARRAY[100];
int main(void) {
 int i;
 int nn; 
 int temp = ARRAY[i];
 rand();
 
 for (i=0; i<100; ARRAY[i++]=rand()%100-50 );

 printf("FIRST ARRAY:\n");
 for (i=0; i<100; i++)
    printf("%3d ",ARRAY[i]);
 putchar('\n');
 putchar('\n');



for(i=0; i<100; i++){
    if (ARRAY[i]<0) {
        if(!nn) {
            nn = 1;

        }
    }

        else {
            temp=ARRAY[i];
            ARRAY[i] = ARRAY[nn - 1];
            ARRAY[nn - 1] = temp;


            }
    }







 printf("Result:\n");

 putchar('\n');
 for (i=0; i<100; printf("%3d ",ARRAY[i++]));
 putchar('\n');
 return 0;
}

但运气不好。

【问题讨论】:

  • 通过编写空体for 循环来停止如此“聪明”。它们很少合适,而且在您使用它们的任何地方都不合适。
  • 在分配局部变量之前停止读取它们。

标签: arrays c reverse function-definition sub-array


【解决方案1】:

对于初学者来说,不需要全局声明数组

int ARRAY[100];

也永远不要使用像100 这样的幻数。使用命名常量。

除了常量以外的所有变量都用大写字母命名是一种不好的编程风格。

您可以编写一个单独的函数,如下面的演示程序所示。

#include <stdio.h>

void reverse_non_negative( int a[], size_t n )
{
    for (size_t i = 0; i < n; )
    {
        while (i < n && a[i] < 0) i++;

        size_t j = i;

        while (i < n && !( a[i] < 0 )) i++;

        for (size_t k = 0; k < ( i - j ) / 2; k++)
        {
            int tmp = a[j + k];
            a[j + k] = a[i - k - 1];
            a[i - k - 1] = tmp;
        }
    }
}

int main()
{
    int a[] = { 5, 6, -7, -8, 9, -4, 7, 8, 2, -2 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for (size_t i = 0; i < N; i++)
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    reverse_non_negative( a, N );

    for (size_t i = 0; i < N; i++)
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

程序输出是

5 6 -7 -8 9 -4 7 8 2 -2
6 5 -7 -8 9 -4 2 8 7 -2

更通用的方法可以如下所示

#include <stdio.h>

void reverse_sub_ranges( int a[], size_t n, int predicate( int ) )
{
    for (size_t i = 0; i < n; )
    {
        while (i < n && !predicate( a[i] )) i++;

        size_t j = i;

        while (i < n && predicate( a[i] )) i++;

        for (size_t k = 0; k < ( i - j ) / 2; k++)
        {
            int tmp = a[j + k];
            a[j + k] = a[i - k - 1];
            a[i - k - 1] = tmp;
        }
    }
}

int non_negative( int value )
{
    return !( value < 0 );
}

int main()
{
    int a[] = { 5, 6, -7, -8, 9, -4, 7, 8, 2, -2 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for (size_t i = 0; i < N; i++)
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    reverse_sub_ranges( a, N, non_negative );

    for (size_t i = 0; i < N; i++)
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

程序输出和上图一样就是

5 6 -7 -8 9 -4 7 8 2 -2
6 5 -7 -8 9 -4 2 8 7 -2

【讨论】:

  • 谢谢你,但我认为这对于我需要做的事情来说有点太复杂了。我需要让它尽可能简单,即使你可能认为这很简单。还是谢谢。
  • @RexepoLT 你是对的。我认为没有什么复杂的。:) 我只是在函数中移动了适当的代码。
  • 是的,我明白这一点,但我需要让这个任务没有函数,只是一个简单的“for”循环。但这可能会有所帮助,谢谢。
  • @RexepoLT 没问题。仅将代码从 main 中的函数移动,而不是使用变量 n 使用变量 n。在任何情况下,您都不能仅使用一个 for 循环来完成任务,因为您需要使用另一个循环来反转子范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 2018-10-15
  • 1970-01-01
  • 2022-11-23
  • 2021-11-17
  • 1970-01-01
  • 2019-01-17
相关资源
最近更新 更多