【问题标题】:Comparing 2 arrays to find out if they have the same elements or not比较 2 个数组以确定它们是否具有相同的元素
【发布时间】:2021-10-22 12:45:40
【问题描述】:

我是一名初级程序员,我需要一些练习方面的帮助!正如您在标题中看到的那样,练习要求编写一个程序来比较 2 个数组的元素,以确定它们是否具有相同的元素。诀窍是第二个数组中的元素可能与第一个数组中的元素顺序不同。 我认为解决此问题的一种方法可能是重新排列 2 个数组以使它们按升序排列,但由于某种原因,它一直说数组具有相同的元素。你能帮帮我吗?

这是代码:

int main()
{
    int v[N];
    int v2[N];
    int i,j;
    int a;
    int b;
    int flag = 0;

    printf("Please enter the values of the 1st array: ");

    for (i = 0; i < N; i++)
    {
        scanf("%d",&v[i]);
    }

    for (i = 0; i < N; i++)
    {
        for(j=i+1; j<N; j++)
        {
            if(v[i]>v[j])
            {
                a = v[i];
                v[i] = v[j];
                v[j] = a;
            }
        }
    }

    printf("\nPlease enter the values of the 2nd array: ");
    
    for (i = 0; i < N; i++)
    {
        scanf("%d", &v2[i]);
    }

    for (i = 0; i < N; i++)
    {
        for (j = i + 1; j < N; j++)
        {
            if (v2[i] > v2[j])
            {
                b = v2[i];
                v2[i] = v2[j];
                v2[j] = b;
            }
        }
    }

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            if (v[i] == v2[j])
            {
                flag=1;
            }
        }
    }

    if (flag == 1)
        printf("\nThe arrays have the same numbers! ");
    else
        printf("\nThe arrays dont have the same numbers!");

    return 0;
}

【问题讨论】:

  • “不工作”从来都不是一个好的问题描述。你得到什么错误或不正确的行为?您是否进行过任何基本调试来回答基本问题,例如输入数组是否正确、排序后的数组是否正确、是否正在比较正确的值等? How to debug small programs.
  • 好的,我更改了文本。问题是它一直说数组具有相同的元素,除非这 3 个元素完全不同。如果其中一个相同,则表示它们具有相同的元素
  • 那么调试呢?你做过基本的调试吗?请注意,仅运行程序不是调试(即测试)。在调试器中单步执行代码和/或添加更多调试打印语句以跟踪程序流程和变量值,以找出首先出错的地方。
  • 如果您要检查第一个数组的每个元素与第二个数组的每个元素,我真的不确定为什么要对这些数组进行排序。这使得排序只是浪费时间
  • 就是这样。我试图找出问题可能出在哪里,根据我的想法,我做对了。我从第一个数组中取出一个元素并将其与第二个数组的所有元素进行比较,如果匹配,我将标志设置为 1 并移动到第二个元素,依此类推。问题主要在于我是如何写比较的,但我不知道如何正确写。

标签: c


【解决方案1】:

排序循环似乎正确,但比较循环不正确:您将第一个数组中的每个项目与第二个数组的每个项目进行比较,因此如果第二个数组中存在任意数量的第一个数组,则结果将为真数组,这是一个弱得多的条件。

您应该使用更简单的比较循环,比较 iv[i]v2[i],从 0N 不包括在内。

这是修改后的版本:

#include <stdio.h>

#define N  100

int main() {
    int v[N];
    int v2[N];
    int i, j;
    int flag;

    printf("Please enter the values of the 1st array: ");

    for (i = 0; i < N; i++) {
        if (scanf("%d", &v[i]) != 1)
            return 1;
    }

    for (i = 0; i < N; i++) {
        for (j = i + 1; j < N; j++) {
            if (v[i] > v[j]) {
                int a = v[i];
                v[i] = v[j];
                v[j] = a;
            }
        }
    }

    printf("\nPlease enter the values of the 2nd array: ");
    
    for (i = 0; i < N; i++) {
        if (scanf("%d", &v2[i]) != 1)
            return 1;
    }

    for (i = 0; i < N; i++) {
        for (j = i + 1; j < N; j++) {
            if (v2[i] > v2[j]) {
                int b = v2[i];
                v2[i] = v2[j];
                v2[j] = b;
            }
        }
    }

    flag = 1;
    for (i = 0; i < N; i++) {
        if (v[i] != v2[i]) {
            flag = 0;
            break;
        }
    }

    if (flag == 1)
        printf("\nThe arrays have the same numbers! ");
    else
        printf("\nThe arrays dont have the same numbers!");

    return 0;
}

这是一个具有相同时间复杂度但不修改数组的替代算法:对于数组v 的每个元素,如果两个数组的副本数相同,则继续,否则数组不同。

#include <stdio.h>

#define N  100

int count(const int *v, int len, int x) {
    int n = 0;
    for (int i = 0; i < len; i++) {
        n += (v[i] == x);
    }
    return n;
}

int main() {
    int v[N];
    int v2[N];
    int i;
    int flag;

    printf("Please enter the values of the 1st array: ");

    for (i = 0; i < N; i++) {
        if (scanf("%d", &v[i]) != 1)
            return 1;
    }

    printf("\nPlease enter the values of the 2nd array: ");
    
    for (i = 0; i < N; i++) {
        if (scanf("%d", &v2[i]) != 1)
            return 1;
    }

    flag = 1;
    for (i = 0; i < N; i++) {
        if (count(v, N, v[i]) != count(v2, N, v[i])) {
            flag = 0;
            break;
        }
    }

    if (flag == 1)
        printf("\nThe arrays have the same numbers! ");
    else
        printf("\nThe arrays dont have the same numbers!");

    return 0;
}

【讨论】:

    【解决方案2】:

    可能还有其他问题,但我在这里看到的主要问题是:

    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            if(v[i]==v2[j])
            {
                flag=1;
            }
        }
    }
    

    这是说对于第一个数组中的每个元素,检查第二个数组中的每个元素;如果它等于第一个数组中的元素,则设置 flag = 1。本质上,如果两个数组中的任何元素相同,则返回 true。

    【讨论】:

    • 那你建议我怎么做?
    • 当您查看数组元素时,您希望检查两个数组中的相同索引。因此,您应该只使用一个带有一个变量的 for 循环。在那个 for 循环中,您将检查 v[i] 和 v2[i] 是否相同,以及它们是否设置为等于 1 的标志并跳出循环(如果您不知道该怎么做,没关系;程序正常运行不是必需的,只是为了提高效率)。
    【解决方案3】:

    如果您需要确保两个数组的所有元素都相同,但您需要适应它们的不同顺序,您可以对它们进行排序并进行比较,或者您可以随时记录。

    您可以创建一个与您要比较的数组长度相同的整数数组,并将它们用作标志来检查您在检查第一个数组中的元素时是否“使用”了第二个数组中的索引.

    我们将看到所有0,然后当我们扫描第一个数组时,我们将忽略第二个数组中已使用的任何索引。如果找到匹配项,我们将设置一个标志,表明数组 2 中的索引已被使用,并且我们将中断内部循环以节省对第二个数组的任何进一步迭代。

    #include <stdlib.h>
    #include <stdio.h>
    
    int arrays_match(int *arr1, int *arr2, int n) {
        size_t used[n];
    
        /* Initialize the used array to all 0 or false. */
        for (int i = 0; i < n; i++) {
            used[i] = 0;    
        }
    
        for (int i = 0; i < n; i++) {
            int in_both = 0;
    
            for (int j = 0; j < n; j++) {
                if (used[j] == 0 && arr1[i] == arr2[j]) {
                    in_both = 1;
                    used[j] = 1;
                    break;
                }
            }
    
            if (!in_both) return 0;
        }
    
        return 1;
    }
    
    int main() {
        int a[4] = { 1, 2, 3, 4 };
        int b[4] = { 4, 2, 3, 1 };
    
        if (arrays_match(a, b, 4)) {
            printf("Huzzah!\n");
        }
        else {
            printf("Huh?\n");
        }
    }
    

    这最终会打印“Huzzah!”但是如果我们用{ 4, 2, 2, 1 } 初始化a 那么它会打印“嗯?”

    考虑一下当我们运行以下示例时会发生什么。

    a = { 1, 2, 4, 2 }
    b = { 4, 2, 2, 1 }
    used = { 0, 0, 0, 0 }
    

    外层循环首先处理a[0],即1。它遍历内部循环,直到j3,此时它都找到匹配项,而used[3] 仍然是0

    a = { 1, 2, 4, 2 }
    b = { 4, 2, 2, 1 }
    used = { 0, 0, 0, 1 }
    

    现在外部循环正在检查a[1],即2。它检查b,直到到达b[1],并且used[1]0,所以它找到了一个匹配项。

    a = { 1, 2, 4, 2 }
    b = { 4, 2, 2, 1 }
    used = { 0, 1, 0, 1 }
    

    接下来外循环检查a[2],即4。它检查b,直到找到b[0],并且used[0]0,所以它找到了一个匹配项。

    a = { 1, 2, 4, 2 }
    b = { 4, 2, 2, 1 }
    used = { 1, 1, 0, 1 }
    

    最后,外部循环正在检查a[3],它又是2。它检查b,直到到达b[1],这也是2,但used[1]1,所以它在这里找不到匹配项。它继续到b[2] 并找到匹配项,因为used[2] 仍然是0

    a = { 1, 2, 4, 2 }
    b = { 4, 2, 2, 1 }
    used = { 1, 1, 1, 1 }
    

    迭代已结束,未检测到不匹配。该函数返回 1 (true)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多