Java HashSet(长整数与整数)

时间:2017-06-04 04:33:29

标签: java long-integer hashset

我正在解决这个问题,(来自Project Euler的41个),我注意到,与Integer相比,包含HashSet的方法对于Long的工作方式不同(我可能在这里错了,请纠正我,如果我的话)。

问题是 -

  

如果使用的话,我们会说n位数是pandigital   所有数字1到n恰好一次。例如,2143是4位数   pandigital也是主要的。

     

存在的最大n位数pandigital素数是什么?

我检查号码是否为Pandigital的代码是 -

private static boolean isPan(Long n) {
        HashSet<Long> list = new HashSet<Long>();
        int count = 0;
        while(n != 0){
            list.add(n%10);
            count++;
            n /= 10;
        }
        for(int i = 9; i>count; i--){
            if(list.contains(i)) return false;
        }
        for(int i = 1; i<= count; i++){
            if(!list.contains(i)) return false;
        }
        return true;
    }

这段代码给了我一个无限循环。所以,我改变了我的代码 -

private static boolean isPan(Long n) {
        HashSet<Integer> list = new HashSet<Integer>();
        int count = 0;
        while(n != 0){
            list.add((int) (n%10));
            count++;
            n /= 10;
        }
        for(int i = 9; i>count; i--){
            if(list.contains(i)) return false;
        }
        for(int i = 1; i<= count; i++){
            if(!list.contains(i)) return false;
        }
        return true;
    }

我刚刚更改了HashSet<Long>HashSet<Integer>list.add(n%10)list.add((int) n%10)

这给了我正确答案,7652413。那么,有人可以解释为什么与Long相比,包含方法对Integer的工作方式有所不同吗?

2 个答案:

答案 0 :(得分:3)

contains(Object o)方法对LongInteger的工作方式不同。它完全相同,即

  

如果此set包含指定的元素,则返回true。更正式的是,当且仅当此集合包含元素true时才返回e(o == null?e == null:o.equals(e))。

请注意,该方法接受Object作为参数类型,而不是E。这意味着您可以使用任何类型的对象调用它。当然,E以外的任何对象类型都会导致它返回false,因为equals()对于不同类型的对象(有一些例外)会失败。

因此,当您致电contains(x),而x原语时,它会根据x的类型自动装箱,<对于E的类型,em> not 。因此,如果xintELong,则它始终会返回false

当您将contains()更改为Long时,突然有效的Integer不是contains()。通过将传递给Long的值的类型与集合中的元素类型正确匹配,您的代码可以有所不同。

<强>更新

您的代码效率不高:

  • 它需要n作为参数,但最高9本质上是int,并且Long可以存储9位数而不会溢出,所以不需要使用HashSet和使用拳击。

  • 它为每个被检查的值分配一个新的contains(),并自动检测找到的每个数字,加上int次调用的9次。

相反,这可以使用位操作来完成,因为32位found值可以轻松存储10个布尔值(标志),指示是否存在数字。

下面的代码将建立两个位掩码expectedfound,它们将指示是否找到一个数字,以及是否应该找到一个数字。由于解决方案应仅使用数字1-n,我们将声明数字0存在并且预期(使逻辑更简单,无需对0进行特殊检查)

如果一个数字出现两次(或数字0出现一次),则另一个预期数字将丢失,expected将不等于private static boolean isPandigital(int number) { int found = 1, expected = 1; for (int n = number; n != 0; n /= 10, expected = (expected << 1) | 1) found |= 1 << (n % 10); return (found == expected); }

{{1}}

答案 1 :(得分:0)

如果您希望代码正常运行,请查看listHashSet<Long>的代码:

for(int i = 1; i<= count; i++){
    if(!list.contains(i)) return false;
}

您可以将变量i的类型更改为long,或将if(!list.contains(i)) return false;更改为if(!list.contains(Long.valueOf(i))) return false;

由于contains将按元素的方法equals检查元素。在上面的代码中,变量i自动装箱到Integer实例,因为变量i是原始int。 并查看整数equals

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

但您的list元素的类型为Long,因此行if(!list.contains(i)) return false;将始终返回false。