【问题标题】:Do we have to create an even and an odd array?我们是否必须创建一个偶数和一个奇数数组?
【发布时间】:2021-01-27 01:19:35
【问题描述】:

我们如何修改以下代码(最初要求用户输入 10 个数字,将其存储在一个数组中,然后打印在屏幕上),以便将偶数打印在第一行,奇数打印在第一行第二个:

#include <stdlib.h>
#include <stdio.h>
int i,j;
int array_1[10];
int main() {
    for(i=0;i<10;i++) {
    printf("Enter a number: ");
        scanf("%d", &array_1[i]);
    }
    printf("The elements of the array are: ");
    for (j=0;j<10;j++) {
        printf("%d ", array_1[j]);
    }
    printf("\n");
    return 0;
}

【问题讨论】:

  • 不,您只需要遍历数组两次。一次打印偶数,一次打印奇数。
  • @RetiredNinja 你介意添加你的代码版本,让我更了解一点吗?
  • 让标签说出语言,而不是标题。
  • 提示:在循环本身中声明您的迭代器变量,例如for (int i = 0; ...),它可以清楚地说明i 是什么以及它的作用域。
  • @tadman “让标签说出语言”是什么意思?

标签: arrays c loops for-loop


【解决方案1】:

O(n) 解:

你必须在数组的后面添加奇数,在数组的前面添加偶数并跟踪索引。


int array_1[10];

int main() {

    int even = 0, odd = 10;

    for (int i = 0; i < 10; i++) {
        printf("Enter a number: ");
        int inp;
        scanf("%d", &inp);
        if (inp % 2 == 0) {
            array_1[even++] = inp;
        } else {
            array_1[--odd] = inp;
        }
    }

    // even numbers
    for (int i = 0; i < even; i++) {
        printf("%i ", array_1[i]);
    }
    printf("\n");

    // odd numbers
    for (int i = 9; i >= odd; i--) {
        printf("%i ", array_1[i]);
    }
    printf("\n");

    return 0;
}

【讨论】:

    【解决方案2】:

    既然你问了,这就是我的做法。我怀疑这可能会给您留下比答案更多的问题。

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    #define NUMBERS_SIZE 10
    
    typedef bool (*number_validator)(int num);
    
    bool isEven(int num)
    {
        return (num & 1) == 0;
    }
    
    bool isOdd(int num)
    {
        return (num & 1) != 0;
    }
    
    void print(const char *title, int *array, int array_size, number_validator isValid)
    {
        printf("%s", title);
        bool first = true;
        for (int i = 0; i < array_size; ++i)
        {
            if (isValid(array[i]))
            {
                if (!first)
                {
                    printf(", ");
                }
                printf("%d", array[i]);
                first = false;
            }
        }
        printf("\n");
    }
    
    int main()
    {
        int numbers[NUMBERS_SIZE] = { 0 };
    
        for (int i = 0; i < NUMBERS_SIZE; i++)
        {
            printf("Enter a number: ");
            scanf("%d", &numbers[i]);
        }
    
        printf("\n");
        print("Even: ", numbers, NUMBERS_SIZE, isEven);
        print(" Odd: ", numbers, NUMBERS_SIZE, isOdd);
    
        return 0;
    }
    

    Demo on ideone

    【讨论】:

    • 这一切,只是为了解决一个最多10行代码就可以完成的问题?!​​
    • 当有人要求只查看 3 或 7 的倍数时,我只需添加另一个验证器即可。当有人要求读取 20 个数字而不是 10 个时,我只需要更改一行。 耸耸肩
    【解决方案3】:

    您可以尝试这种方式。我使用二进制 AND(&) 而不是 MOD(%),因为它更快:

    #include <stdlib.h>
    #include <stdio.h>
    int i,j;
    int array_1[10];
    
    int main()
    {
    for(i=0; i<10; i++)
    {
      printf("Enter a number: ");
      scanf("%d", &array_1[i]);
    }
    
    printf("The Even elements of the array are: ");
    
    for (j=0; j<10; j++)
    {
        if((array_1[j]&1) == 0)
            printf("%d ", array_1[j]);
    }
    
    printf("\nThe Odd elements of the array are: ");
    
    for (j=0; j<10; j++)
    {
        if((array_1[j]&1) != 0)
            printf("%d ", array_1[j]);
    }
    
    printf("\n");
    return 0;
    }
    

    【讨论】:

      【解决方案4】:

      无需创建新数组。您可以先检查偶数,然后再检查奇数。此外,在使用 i 和 j 之前无需声明它们。您可以在 for 循环中声明并初始化它们:

      #include <stdlib.h>
      #include <stdio.h>
      int array_1[10];
      int main() {
          for(int i=0;i<10;i++) {
          printf("Enter a number: ");
              scanf("%d", &array_1[i]);
          }
          printf("The elements of the array are: ");
          
          // Print even numbers
          for (int j=0;j<10;j++) {
              if(array_1[j] % 2 == 0)
                  printf("%d ", array_1[j]);
          }
          printf("\n");
      
          // Print odd numbers
          for (int j=0;j<10;j++) {
              if(array_1[j] % 2 != 0)
                  printf("%d ", array_1[j]);
          }
          printf("\n");
          return 0;
      }
      

      编辑:正如 tadman 在下面的评论中所建议的,有一种更好、更清洁的方法来完成此类任务。正如您在上面的示例中所看到的,我重复了 4 行代码,其中只有一个字符发生了变化。这个任务可以抽象成一个函数来减少代码重复:

      void printIfMod(int* arr, size_t array_size, int mod){
          for (int j=0;j<array_size;j++) {
              if(arr[j] % 2 != mod)
                  continue;
              printf("%d ", arr[j]);
          }
          printf("\n");
      

      如果你把函数放在main之后,记得在main之前添加一个函数原型:

      void printIfMod(int* arr, size_t array_size, int mod);
      int main(){...}
      

      现在,要打印数字,调用模 0 得到偶数和 1 得到奇数的方法:

      // Print even numbers
      void printIfMod(&array_1, 10, 0);
      
      // Print odd numbers
      void printIfMod(&array_1, 10, 1);
      

      最后一点,硬编码array_size 是不明智的,这适用于所有数组。我建议使用sizeof() 来动态计算数组的大小:

      size_t size = sizeof(array_1) / sizeof(int);
      // Print even numbers
      void printIfMod(&array_1, size, 0);
      
      // Print odd numbers
      void printIfMod(&array_1, size, 1);
      

      【讨论】:

      • 这可以通过使用printIfModulo(int* arr, size_t len, int mod) 之类的函数来改进,您可以在其中测试模匹配与输入。减少代码重复并使其更加模块化总是有帮助的。
      • 感谢您的建议,我想过类似的事情,但我不想让答案过于复杂,因为 OP 似乎对这个主题很陌生。我会根据您的建议添加和编辑。再次感谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多