简体   繁体   English

你如何检查二维数组中的所有整数是否都是唯一的?

[英]How would you check if all integers in a 2d array are unique?

I am looking to verify if all of the integers in a 2d array are unique, return true if they are unique otherwise false. 我想验证二维数组中的所有整数是否都是唯一的,如果它们是唯一的则返回true,否则返回false。 The below code is what I have for a simple array. 下面的代码是我对一个简单数组的代码。 But I am not sure how to go about modifying it. 但我不确定如何修改它。

public boolean verifyUniqueIntegers(int array []){
boolean result = true;
   for (int i = 0; i < array.length; i++) {
        if(array[i] <= 0 || array[i] > n*n){
            result = false;
        }
        for (int j = 0; j < i; j++)
            if (array[i] == array[j]) {
                result = false;
            }
    }
    return result;
 }

The best way to approach this problem is to use a mathematical construct called a set. 解决此问题的最佳方法是使用称为集合的数学结构。 The key property of a set for your purposes is that they can not contain duplicates by definition. 为您的目的,集合的关键属性是它们不能按定义包含重复项。 Java provides a data structure allowing us to create sets found in java.util.Set . Java提供了一种数据结构,允许我们创建java.util.Set集合。 This is the generic interface that specifies how sets should behave. 这是通用接口,用于指定集合的​​行为方式。 However, interfaces provide only specification, not implementation, so you'll have to use Set in conjunction with another class java.util.HashSet , which implements Set . 但是,接口只提供规范,而不是实现,因此您必须将Set与另一个实现Setjava.util.HashSet结合使用。 You seem like a novice programmer, so I wrote a test program to show you how this works. 你看起来像一个新手程序员,所以我写了一个测试程序来向你展示它是如何工作的。

import java.util.*;

public class SetTest {
    public static void main(String[] args) {
        int[] set = {1,2,3,4,5,6,7};
        int[] nonSet = {1,2,3,4,5,4};

        System.out.println(verifyUniqueIntegers(set));
        System.out.println(verifyUniqueIntegers(nonSet));
    }

    public static boolean verifyUniqueIntegers(int[] array) {
        Set<Integer> set = new HashSet<Integer>();
        for(int i : array) // This is a construction called a for-each loop
            if(!set.add(i)) // This is an example of what's called autoboxing
                return false;
        return true;
    }
}

Here I've used a static method for convenience, but you can of course change this into an instance method for your purposes once you give it a try. 为了方便起见,我在这里使用了静态方法,但是一旦你试一试,你当然可以将它改成一个实例方法。

First, I create a for-each loop to iterate over all the elements in the array that's passed into verifyUniqueIntegers() . 首先,我创建一个for-each循环来迭代传递给verifyUniqueIntegers()的数组中的所有元素。 For each loops use what are called iterators to create a reference to each element, one at a time, and make it available in the body of the loop. 对于每个循环,使用所谓的迭代器来创建对每个元素的引用,一次一个,并使其在循环体中可用。 When the end of the body is reached, the for-each loop automatically resets i to the next element in the array, as long as there are elements left in the arry. 当到达正文的末尾时,for-each循环会自动将i重置为数组中的下一个元素,只要arry中有剩余元素。 You can ready more about for-each loops in the Oracle Java Tutorials. 您可以在Oracle Java教程中准备更多关于for-each循环的内容。

Then, the method calls set.add(i) . 然后,该方法调用set.add(i) This attempts to add i to the set that we previously defined. 这会尝试将i添加到我们之前定义的集合中。 This is an example of what's called autoboxing. 这是所谓的自动装箱的一个例子。 Since the Set interface is generic, it can contain elements of any object type. 由于Set接口是通用的,因此它可以包含任何对象类型的元素。 Since int is a primitive, we must use the wrapper class Integer to specify the elements in our set. 由于int是基元,我们必须使用包装类Integer来指定集合中的元素。 When we call set.add(i) you don't have to convert the int into an Integer because the java compiler does it for you. 当我们调用set.add(i)您不必将int转换为Integer因为java编译器会为您执行此操作。

This method returns true if i is not a duplicate, then adds it to the Set . 如果i不是重复的,则此方法返回true ,然后将其添加到Set It returns false if i is a duplicate and does nothing. 如果i是重复并且什么都不做,则返回false Thus, we can take advantage of the method check the uniqueness of each element in your array. 因此,我们可以利用该方法检查数组中每个元素的唯一性。 The method returns false as soon as a duplicate is found, and otherwise returns true . 一旦找到副本,该方法就返回false ,否则返回true Hope this helps, good luck! 希望这有帮助,祝你好运!

Your algorithm is slow. 你的算法很慢。 To make it faster, you should use something like HashMap . 为了加快速度,你应该使用像HashMap这样的东西。

  1. Create empty HashMap<Integer> . 创建空HashMap<Integer>
  2. Iterate on all 2d-array elements (for-for loop). 迭代所有2d数组元素(for-for循环)。
  3. For every element check if your HashMap contains it. 对于每个元素,检查您的HashMap包含它。
  4. If yes then return false , it means that not all elements in your array are unique . 如果是,则return false ,这意味着并非数组中的所有元素都是唯一的
  5. If no, add element to HashMap . 如果不是,请将元素添加到HashMap
  6. After for-for loop return true . for-for循环return true

As a beginning programmer, choose basic solutions without the sophistication of more complex parts of the library that do in truth offer more power. 作为一个初学程序员,选择基本的解决方案,而不是图书馆中更复杂的部分的复杂性,实际上提供了更多的权力。 The main thing for you here is to learn how to use 2D arrays. 这里的主要内容是学习如何使用2D数组。

You can do it very simply because of the hidden specification that you did not mention but is in the code. 您可以非常简单地执行此操作,因为您没有提及但在代码中的隐藏规范。 None of the numbers can be greater than N * N. 这些数字都不能大于N * N.

Start with pseudo-code. 从伪代码开始。 The basic algorithm is to have a checking array of length N * N. Put a marker in each element as you find the number in the source array, using the number as the index into the checking array. 基本算法是有一个长度为N * N的检查数组。当你在源数组中找到数字时,在每个元素中放置一个标记,使用数字作为检查数组的索引。 If there is already an element there, then the number is not unique. 如果那里已经存在元素,则该数字不是唯一的。 The code becomes something like this: 代码变成这样:

final int N = 10;  // Your choice of N, or perhaps input it.
int [][] needsChecking = new int [N] [N];  // fill it up.

public boolean arrayIsGood (int [][] src) {
    final int N2 = N * N;
    boolean [] checker = new boolean [N2];
    for (int i = 0; i < N2; i++) {  // Initialize Checker
        checker [i] = false;
    }
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            int value = src [i][j];
            if ((value <= 0) || (value > N2))
                return false;
            if (checker [value - 1])  // already found
                return false;
            checker [value - 1] = true;
        } // for j
    } // for i
    return true;  // if we get here every element has passed.
} // arrayIsGood (int [][])

Some of the other answers are more elegant or more extensible or handle space usage better or may find the result faster, etc. But master the basics first. 其他一些答案更优雅或更具可扩展性或更好地处理空间使用或可能更快地找到结果等。但首先掌握基础知识。

public boolean verifyUniqueIntegers(int array []){
    Set<Integer> set = new HashSet<>(array.length);
    for (int i : array)
    {
        if (set.contains(i))
            return false;
        set.add(i);
    }
    return true;
}

or maybe: 或者可能:

public boolean verifyUniqueIntegers(Integer array []){
    return new HashSet<>(Arrays.asList(array)).size() == array.length;
}

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

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