如何检查两个序列是否按某种顺序具有相同的值,(忽略重复)java

时间:2018-06-06 12:15:54

标签: java arrays

这是一个2部分问题第1个问题要求创建一个方法来检查两个序列是否具有相同顺序的相同值。

其次我坚持这个问题要求创建一个方法来检查两个序列是否按某种顺序具有相同的值,忽略重复,即 序列1(1,4,9,16,9,7,4,9,11) 序列2(11,11,7,9,16,4,1) 因此序列1仍然与序列2相同,因为11,4和9是重复元素

所以我添加了一个方法public boolean equals(Sequence other),它检查两个序列在​​同一个顺序部分1中是否具有相同的值,但我现在需要做的是第2部分检查两个序列是否具有相同的值按某种顺序,忽略重复。

import java.util.Arrays;
public class Sequence {
    private int[] values;
    public Sequence(int size)
    {
        values = new int[size];
    }
    public void set(int i, int n)
    { 
        values[i] = n; 
    }
    public boolean equals(Sequence obj) 
    {
        if (this == obj)
        {
            return true;
        }
        if (obj == null)
        {
            return false;
        }
        if (getClass() != obj.getClass())
        {
            return false;
        }
        Sequence other = (Sequence) obj;
        if (!Arrays.equals(values, other.values))
        {
            return false;
        }
        return true;
    }
    public static void main(String args[]){
        Sequence s = new Sequence(5);
        Sequence s2 = new Sequence(5);// new Sequence(4)
        s.set(0, 1);
        s2.set(0, 1);
        System.out.println(s.equals(s2));//will print true      
    }
}

我有点困惑我知道这是你检查重复的方法,但这就是我所知道的我真的不知道在这种情况下如何使用它或如何忽略重复

for (int i = 0; i < values.length; i++) 
{ 
    for (int j = i + 1; j < other.length; j++) 
    { 
        if (values[i].equals(other[j]) ) {}
    }
}

5 个答案:

答案 0 :(得分:1)

缓慢的方法是:遍历较小的数组,并为每个值检查它是否包含在较大的数组中。然后反过来......所以,没有任何进一步的“聪明”,你需要进行n * m比较。时代2。

更复杂的解决方案:对两个阵列进行排序。然后开始轮流遍历两个数组(当两个数组都被排序时,您不需要重复迭代第二个数组以确定它是否包含来自另一个数组的值)。然后你只需要遍历两个数组(但是如上所述:以某种交替的方式)。

答案 1 :(得分:1)

我认为最简单的方法如下:

  • 对两个阵列进行排序
  • 获取数组的不同值。
  • 比较已排序的唯一数组

更新,感谢@DodgyCodeException,结果表明在流中对数组进行排序更有效。

    int[] val1 = {1,1,4,9,16,9,7,4,9,11};
    int[] val2 = {11, 7, 9, 16, 7, 4, 1};

    //Compare should  be false
    System.out.println(Arrays.equals(val1, val2)); //false

    //Sort Array and get distinct Values
    //Assign to new int[] if you do not want to change the original arrays
    val1 = Arrays.stream(val1).sorted().distinct().toArray();
    val2 = Arrays.stream(val2).sorted().distinct().toArray();

    //Compare should be true
    System.out.println(Arrays.equals(val1, val2)); //true

答案 2 :(得分:1)

这对于Java的Set机制来说是微不足道的。只要equalshashCode针对T类型正确实施,以下代码段就会有效:

private boolean equalWithDuplicates(T[] a, T[] b) {
    return new HashSet<>(Arrays.asList(a)).equals(new HashSet<>(Arrays.asList(b)));
}

然而,正如评论者所指出的那样,this SO post似乎表明基元的数组需要加框,以使解决方案有效:

private boolean equalWithDuplicates(int[] a, int[] b) {
    Set<Integer> boxedA = Arrays.stream(a).boxed().collect(Collectors.toSet());
    Set<Integer> boxedB = Arrays.stream(b).boxed().collect(Collectors.toSet());
    return boxedA.equals(boxedB);
}

答案 3 :(得分:0)

不确定您的意思,但如果您想删除重复项,最简单的方法是使用java.util.HashSet之类的java.util.Set。 此外,写一个equals(Sequence obj)方法可能被认为是不好的做法,因为它会重载equals(Object obj)。你可能想要覆盖那个方法,rahter然后重载它。

答案 4 :(得分:0)

我认为你的Sequence课程看起来像这样。 EQUALS_IGNORE_ORDER_AND_DUPLICATES的主要想法是将输入数据转换为数据,这可以与您已经创建的equal函数一起使用。

final class Sequence {

    private final int[] values;

    public Sequence(int size) {
        values = new int[size];
    }

    public void set(int i, int n) {
        values[i] = n;
    }

    public static final BiPredicate<Sequence, Sequence> EQUALS = (seq1, seq2) -> Arrays.equals(seq1.values, seq2.values);

    public static final BiPredicate<Sequence, Sequence> EQUALS_IGNORE_ORDER_AND_DUPLICATES = (seq1, seq2) -> {
        Set<Integer> set1 = seq1 != null ? Arrays.stream(seq1.values).boxed().collect(Collectors.toSet()) : Collections.emptySet();
        Set<Integer> set2 = seq2 != null ? Arrays.stream(seq2.values).boxed().collect(Collectors.toSet()) : Collections.emptySet();
        return set1.equals(set2);
    };

}

测试:

int[] val1 = { 1, 1, 4, 9, 16, 9, 7, 4, 9, 11 };
int[] val2 = { 11, 7, 9, 16, 7, 4, 1 };

Sequence seq1 = new Sequence(val1.length);
Sequence seq2 = new Sequence(val2.length);

for (int i = 0; i < val1.length; i++)
    seq1.set(i, val1[i]);

for (int i = 0; i < val2.length; i++)
    seq2.set(i, val2[i]);

boolean res1 = Sequence.EQUALS.test(seq1, seq2);    // false
boolean res2 = Sequence.EQUALS_IGNORE_ORDER_AND_DUPLICATES.test(seq1, seq2);   // true