繁体   English   中英

检查两个int数组是否相等-无论顺序如何

[英]Checking two int arrays for equality - Regardless of order

免责声明:这是一项家庭作业,所以请不要只给我代码,我想对如何使用尽可能少的实际代码来做到这一点做出一种解释。

因此,我有两个未排序且长度相等的整数数组,可以包含重复值。 由于这是家庭作业,因此存在一个奇怪的条件,即不允许我使用java.utils中的任何内容或对数组进行排序。

我应该检查两个数组是否包含相同的元素,而不管顺序如何。 因此,比较数组[5、6、7、5、6、3]和[6、6、7、5、5、3]将返回true,而比较[7,7 8]和[7、8、8 ] 不会。

我不知道如何执行此操作,已经搜索了问题,但是它们似乎都使用了java.utils中的某些内容,或者数组不包含重复项。 我尝试遍历第一个数组中的每个值,并遍历第二个数组中的每个值,以检查该值是否存在,但重复时会跳闸。

对于能提供正确指导的任何帮助,建议或技巧,我将不胜感激。 谢谢!

如何依次从第一个int数组中获取每个元素,并检查是否在第二个int数组中找到它。 为了使这个想法可行,您需要创建一个布尔值数组,这些值都被初始化为false ,以指示是否使用了第二个int数组中的值。 然后,当您从第一个数组中找到每个值时,请将布尔数组中的相应元素设置为true

一种方法是遍历第一个数组并删除与在第二个数组中找到的元素相等的元素。

当您无法从第二个数组中的第一个数组中找到元素时,则数组不相等。 当找到第二个数组中第一个数组中的最后一个元素时,这些数组相等。

如果不修改数组,则必须克隆首先更改的数组。

这是一个解决方案,在较长的阵列上可能会变慢,因为它是O(n²)

// return how often n appears in an array
public static int count(int n, int[] array) { ... }

public static boolean equalarrays(int[] arr1, int[] arr2) {
   for (int i: arr1) {
       if (count(i, arr1) != count(i, arr2)) return false;
   }
   return arr1.length == arr2.length;
}
1   public static boolean compare(int[] a, int[] b)
2   {
3       if(a.length != b.length) return false;
4
5       aloop:for(int i = 0; i < a.length; ++i)
6       {
7           bloop:for(int j = 0; j < b.length; ++j)
8           {
9               if(a[i] == b[j])
10              {
11                  for(int k = j; k < i; ++k)
12                  {
13                      if(a[k] == b[j])    continue bloop;
14                  }
15
16                  continue aloop;
17              }
18          }
19
20          return false;
21      }
22
23      return true;
24  }

这基本上是说:取两个大小相同的数组(3) ab ,迭代槽a (5) ,迭代槽b (7) ,将a元素与b (9)的每个元素进行比较,如果b任何元素等于元素a

  • 如果为true:检查a该元素是否已在a循环的索引上迭代(11)并与已处理的元素(13)进行比较。
    • 如果为true:获取b下一个元素并重复。 (13)
    • 如果设置为false:获得下一个元素a和重复。 (17)
  • 如果假:嗯,当时没有元素b等于元素a (18)将返回false

如果我们到了线(23)的所有元素b是元素a 返回true。

编辑:另外,您可以反转aloop和bloop以获得一些额外的性能。 (我没有将其放入主代码块中,因为它容易使人感到困惑。)

bloop:for(int j = 0; j < b.length; ++j)
// could be written as
bloop:for(int j = b.length; (--j) >= 0; )
// which is faster as the comparison and incrementation step are merged into one

这是我自己做的一项有趣的活动。 我建议做两个包含两个数组表的所有值的ArrayList。 我这样做是因为您可以使用remove()方法。 遍历给定的第一个数组的所有元素。 那将是您的参考数组。 在参考数组的第一次迭代中获取对象。 然后检查您的其他阵列是否包含它。 如果false正确,则检查失败,并且您可以当场返回false ,如果正确:将其删除然后获取参考数组的下一个迭代。

即使您不想要该代码,也可以将其放在pastebin中: http : //www.pastebin.com/3BEV2CqH,它接受Object[] ... tables参数,并使用equals方法进行比较。 我敢肯定,如果您能像我一样把它拉下来,您的老师将会感到惊讶。

一个简单的解决方案是复制两个数组,然后对副本进行排序和比较。 如果使用良好的排序算法,则为O(NlogN) 如果使用正确的库方法,则可以用大约3行代码编写它。

@ Andy256和@Stochastically的解决方案都应该起作用,但是它们都是O(N^2)

一种通用的通用方法是对两个数组进行排序,然后进行比较。 对于任何两个阵列,此方法将始终在可预测的时间内成功。 我认为没有任何一种算法的最坏情况时间会比对数组排序所需的时间好得多。

但是,在许多情况下,使用一种“通常”比排序数组更快的方法可能会很有用。 举一个简单的例子,假设对每个整数X计算(X *(X + 123456)),然后将这些值的总和(以long )相加。如果两个列表以相同的顺序包含相同的值,则它们的总和应为等于。 列表可能包含不同的值,但仍会产生相同的总和,但是在大多数情况下,列表包含不同的值时,它们的总和可以被识别为不同,而不必麻烦对列表进行排序。

您可能还想考虑“哈希基数排序”。 基数排序的工作原理是让每个遍将事物分成多个存储桶,然后输出第一个存储桶的内容,然后输出第二,第三,第四,第五个存储桶的内容。 过去,打孔卡以这种方式进行分类,方法是使用一台机器检查每张卡上的一列,然后根据打孔的内容将每张卡放入十三个存储桶中的一个。 一个人可以使用2 ^ 32个存储桶进行一次遍历,使用65,536个存储桶进行两次遍历,使用256个存储桶进行4次遍历,等等,对任意数量的32位整数进行排序。各种铲斗通常会明显歪斜。 如果定义了一种将输入值映射到例如从0到255的数字的函数,以便将输入的1/256分配给每个值,则可以在线性时间内将“排序”列表的任务减少为排序256的任务列表,每个列表的大小为1/256。 请注意,按常规意义不会对结果序列进行“排序”,但是包含相同项目的两个列表将以相同的方式进行“排序”。

这是一个解决方案。 该帖子还是旧的

public static boolean equality(int[] list,int[] list2)
  {
    boolean result = false;
    int correct = 0;
    if(list.length == list2.length)
    {
      for(int i = 0; i< list.length; i++)
      {
        for(int j = 0; j < list2.length; j++)
        {
          if(list[i] == list2[j])
          {
            correct++;
            if(correct == list.length && correct == list2.length)
            {
              result = true;
            }
          }
        }
      }
    }
    return result;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM