在 C 范围内反转数组

问题描述 投票:0回答:6

我必须用C语言来解决它。我有 n 个整数的数组。 L 和 U 是下限和上限。我必须反转 [L,U] 数组中的数字。我尝试过这种方式,但在某些情况下答案是错误的。代码中需要更改哪些内容?或者还有其他逻辑来完成任务吗?

#include <stdio.h>
int main() {
  int x, arr[100], n, l, u, a, temp, temp1;
  scanf("%d%d%d", &n, &l, &u);
  for (int i = 0; i < n; i++) {
    scanf("%d", &x); // read elements of an array
    arr[i] = x;
  }
  a = n / 2;
  for (int i = 0; i < a; i++) {
    for (int j = a; j < n; j++) {
      if (arr[i] >= l && arr[i] <= u) {
        if (arr[j] >=l && arr[j] < u) {
          temp = arr[j];
          temp1 = arr[i];
          arr[i] = temp;
          arr[j] = temp1;
        }
      }
    }
  }

  for (int i = 0; i < n; i++) {
    printf("%d ", arr[i]);
  }
}

输入示例: 10(整数个数) -7(下限) 5(上限) -10 -9 5 -2 -3 7 10 6 -8 -5

输出示例: -10 -9 -5 -3 -2 7 10 6 -8 5

我的输出: -10 -9 -5 -2 -3 7 10 6 -8 5

arrays c for-loop if-statement reverse
6个回答
1
投票

有一个

O(N)
解决方案,不需要嵌套循环。

首先,使用现有的代码,声明一个附加数组和一些其他辅助变量,用于跟踪需要交换的索引。

  int left, right;
  int swaplist[100] = {0};
  int swapcount = 0;

您可以完全保持初始摄入循环,但如果该值位于下限和上限之间,则进行修改以将新扫描值的 index 附加到

swaplist
数组。

  for (int i = 0; i < n; i++) {
    scanf("%d", &x); // read elements of an array
    arr[i] = x;

    if ((x >= l) && (x <= u)) {
        swaplist[swapcount++] = i;
    }
  }

然后用一个循环迭代“swaplist”并对原始数组进行交换。

  left = 0;
  right = swapcount-1;
  while (left < right) {
      int leftindex = table[left];
      int rightindex = table[right];

      int tmp = arr[leftindex];
      arr[leftindex] = arr[rightindex];
      arr[rightindex] = tmp;
      left++; right--;
  }

0
投票

你做出了勇敢的尝试。您的嵌套

for()
循环适用于某些排序算法,但不适用于此任务的目的。

根据样本输入和所需的输出,您确实希望在数组的两端建立一个“括号”,然后将两者向中心移动,交换值恰好满足

low <= n <= high
值的元素。 (在这种情况下,-7 <= n <= 5).

解决方案如下:

#include <stdio.h>

int swap( int arr[], size_t l, size_t r ) { // conventional swap algorithm
    int t = arr[l];
    arr[l] = arr[r];
    arr[r] = t;
    return 1;
}

int main() {
    int arr[] = { -10, -9, 5, -2, -3, 7, 10, 6, -8, -5, }; // your data
    size_t i, sz = sizeof arr/sizeof arr[0];

    for( i = 0; i < sz; i++ ) // showing original version 
        printf( "%d ", arr[i] );
    putchar( '\n' );

#define inRange( x ) ( -7 <= arr[x] && arr[x] <= 5 ) // a good time for a macro

    size_t L = 0, R = sz - 1; // 'L'eft and 'R'ight "brackets"
    do {
        while( L < R && !inRange( L ) ) L++; // scan from left to find a target
        while( L < R && !inRange( R ) ) R--; // scan from right to find a target
    } while( L < R && swap( arr, L, R ) && (L+=1) > 0 && (R-=1) > 0 );

    for( i = 0; i < sz; i++ ) // showing results
        printf( "%d ", arr[i] );
    putchar( '\n' );

    return 0;
}
-10 -9 5 -2 -3 7 10 6 -8 -5
-10 -9 -5 -3 -2 7 10 6 -8 5

0
投票

如果我正确理解了赋值,那么您需要反转满足某些条件的数组元素。

如果是这样,那么这些嵌套的 for 循环

  for (int i = 0; i < a; i++) {
    for (int j = a; j < n; j++) {
      if (arr[i] >= l && arr[i] <= u) {
        if (arr[j] >=l && arr[j] < u) {
          temp = arr[j];
          temp1 = arr[i];
          arr[i] = temp;
          arr[j] = temp1;
        }
      }
    }
  }

没有道理。

只需使用一个for循环就足够了,如下面的演示程序所示。

#include <stdio.h>

int main( void )
{
    int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
    const size_t N = sizeof( a ) / sizeof( *a );

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

    int l = 10, u = 50;

    for (size_t i = 0, j = N; i < j; i++ )
    {
        while (i < j && !( l <= a[i] && a[i] <= u )) ++i;

        if (i < j)
        {
            while (i < --j && !( l <= a[j] && a[j] <= u ));

            if (i < j)
            {
                int tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }

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

程序输出为

1 10 2 3 20 4 30 5 40 6 7 50 9
1 50 2 3 40 4 30 5 20 6 7 10 9

您可以编写一个单独的函数,例如

#include <stdio.h>

void reverse_in_range( int a[], size_t n, int low, int upper )
{
    for (size_t i = 0, j = n; i < j; )
    {
        while (i < j && !( low <= a[i] && a[i] <= upper )) ++i;

        if (i < j)
        {
            while (i < --j && !( low <= a[j] && a[j] <= upper ));

            if (i < j)
            {
                int tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;

                ++i;
            }
        }
    }
}

int main( void )
{
    int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
    const size_t N = sizeof( a ) / sizeof( *a );

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

    reverse_in_range( a, N, 10,50 );

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

0
投票

感谢大家的帮助。我读了所有这些,但我找到了另一种方法来解决这个问题。我会写它以防万一。 (一些变量名称是随机的,因此如有疑问,请评论)。

#include <stdio.h>
int main() {
  int x, main[100], n, l, u, a = 0, arr[100], temp, m = 0,f=0,c,d;
  scanf("%d%d%d", &n, &l, &u);
  for (int i = 0; i < n; i++) {
    scanf("%d", &x); // read elements of an array
    main[i] = x;
    if (x >= l && x <= u) {
      a++; //check if element is in range [l,u] and increasing a. later "a" will be used a length of the array "arr". this array cootains elements, which in in [u,l].
    }
  }


  //add [u,l] elements in new array "arr"
  for (int i = 0; i < n; i++) {
    if (main[i] >= l && main[i] <= u) {
      arr[m] = main[i];
      m++; //index counter of "arr", 
    }
  }
  d=0;
  for(int i=0;i<n;i++){
    if(main[i]==arr[d]){
      c=arr[a-d-1];
      main[i]=c;
      d++;
    }
  }
  for(int i=0;i<n;i++){
    printf("%d ",main[i]);
  }
}

0
投票

这个功能应该可以用

    /**
     * reverse_array - reverses an array
     * @a: pointer to array
     * @n: variable for array size
     */

     void reverse_array(int *a, int n)
     {
            int length = 0, length1, length2, actlength = n - 1;
            int arr[100];

            for (length1 = 0, length2 = 0; length1 < n; length1++, length2++)
                    arr[length1] = a[length2];

            if (n > 0)
            {
                    while (length < n)
                    {
                            a[length] = arr[actlength];
                            actlength--;
                            length++;
                    }
            }
     }

-1
投票

我最好的猜测是 scanf 非常烦人,最重要的是,你的格式不明确。

%d%d%d 将如何读取 1234?它会给你 12 3 和 4 吗? 1 23 和 4? ...

尝试去做

scanf("%d %d %d" ...); // or
scanf("%d, %d, %d" ...); 

类似的事情。请注意,不建议使用 scanf,getc 是一个巧妙的替代方案,尽管当您想要读取多于一位数字的数字时也很烦人,但您可以创建一个函数 read_number,该函数基于 getc,将读取数字为一个字符串并用 stoi 返回 int 值。

© www.soinside.com 2019 - 2024. All rights reserved.