Java, int dizisinin int içerip içermediğini kontrol edin


96

Temelde arkadaşım, int dizisinin int içerip içermediğini kontrol etmenin farklı bir yolunu kullanarak kodumu kısaltabileceğimi söylüyordu, ancak bana bunun ne olduğunu söylemiyor: P.

Akım:

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}

Bunu da denedim, ancak bazı nedenlerden dolayı her zaman yanlış döndürüyor.

public boolean contains(final int[] array, final int key) {
    return Arrays.asList(array).contains(key);
}

Birisi bana yardım edebilir mi?

Teşekkür ederim.


8
Arrays.asList (...) çağrınız bir vararg alır, yani bir Listede buna iletebileceğiniz rastgele sayıda argümanı sarar. Sizin durumunuzda, tek elemanlı dizilerin bir listesini alıyorsunuz ve bu liste açıkça int'i içermiyor.
sarcan

Yorumunuz şimdi ne anlama geliyor?
sarcan

kontrol Hashsettabanlı yeniden yargılama mekanizması yanıtı. En hızlı yoldur.
Amit Deshpande

Argümanınız ilkel bir dizi olduğundan ve kodunuz çok açık ve anlaşılır olduğundan, orijinal kodunuzu kısaltmanın bir anlamı yok. ArrayListuygulama aynı şeyi yapıyor.
Genzer

Kodunuzu kısaltmam. (1) dizi listesi sizin yaptığınız şeyi yapar. (2) - daha önemli olan şey, Arrays.asList kullanan kısaltılmış kodun, bazı performans kritik kodlarında sorun olabilecek yeni nesne oluşturmasıdır. İlk kod parçacığı yapabileceğiniz en iyi şeydir.
Martin Podval

Yanıtlar:


41

İşte Java 8 çözümü

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}

64

Sadece kullanabilirsiniz ArrayUtils.containsgelen Apache Commons Lang library.

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}

1
ArrayUtils'i kullandığınız sürece, ArrayUtils.contains'i
mjohnsonengr

2
Sebep yok :)
Reimeus

20
Bunun kütüphanenin bir ArrayUtils.contains()parçası olduğunu belirtmekte fayda var Apache Commons Lang. Bu harika bir kitaplık olsa da, dizinin bir öğe içerip içermediğini kontrol etmek için dış bağımlılık eklemek muhtemelen hala iyi bir fikir değildir: D
Krzysiek

2
ArrayUtils geçmişte kaldı. Java 8+ ve Guava'nın oldukça harika özellikleri var !!
TriCore

34

Çünkü Arrays.asList(array)dönüş List<int[]>. arrayargüman, vararg olarak değil, kaydırmak istediğiniz tek bir değer olarak ele alınır (dizi dizilerinin listesini alırsınız).

Not o does nesne türleri (değil ilkel) ile çalışmalarını:

public boolean contains(final String[] array, final String key) {
    return Arrays.asList(array).contains(key);
}

ya da:

public <T>  boolean contains(final T[] array, final T key) {
    return Arrays.asList(array).contains(key);
}

Ancak sahip List<int>olamazsınız ve burada otomatik kutulama çalışmıyor.


1
Otomatik kutulama neden çalışmıyor, nihai olarak ilan edildiği için mi?
subhashis

19

Guava, ilkel türler için ek yöntemler sunar. Bunların arasında sizinkiyle aynı argümanları alan bir yöntem içerir.

public boolean contains(final int[] array, final int key) {
    return Ints.contains(array, key);
}

Ayrıca guava sürümünü statik olarak içe aktarabilirsiniz.

Guava İlkellerinin Açıklamasını Görün


18

Farklı bir yol:

public boolean contains(final int[] array, final int key) {  
     Arrays.sort(array);  
     return Arrays.binarySearch(array, key) >= 0;  
}  

Bu, geçirilen diziyi değiştirir. Diziyi kopyalama ve orijinal dizi üzerinde çalışma seçeneğiniz olacaktır, yani int[] sorted = array.clone();
bu sadece bir kısa kod örneğidir. Çalışma zamanı O(NlogN)sizin yolunuzdaykenO(N)


30
Dizimi bir containsyöntem değiştirirse şaşırırdım.
Zong

@ZongLi: Biz kusur arayan varsa bu OP.Updated OP için sadece bir örnektir
Kratilus'unda

5
BinarySearch () javadoc'undan: "dönüş değeri, ancak ve ancak anahtar bulunursa> = 0 olacaktır." bu nedenle Arrays.binarySearch (dizi, anahtar)> = 0 döndürülmelidir!
icza

Ek: BinarySearch () işlevinin dönüş değeri (- (ekleme noktası) - 1) eğer anahtar bulunmazsa, muhtemelen -1'den farklı bir değer olabilir.
icza

Bu -1doğru olma niyetindeyse olamaz. "Ekleme noktası, anahtarın listeye ekleneceği nokta olarak tanımlanır: anahtardan büyük olan ilk öğenin dizini veya listedeki tüm öğeler belirtilen anahtardan küçükse list.size (). ". Söylemem gerek >= 0.
Brian


1

1. tek seferlik kullanımlar

List<T> list=Arrays.asList(...)
list.contains(...)

2. Birden fazla kullanıyorsanız performans değerlendirmesi için HashSet kullanın.

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)

1

Bunu dene:

public static void arrayContains(){
    int myArray[]={2,2,5,4,8};

    int length=myArray.length;

    int toFind = 5;
    boolean found = false;

    for(int i = 0; i < length; i++) {
        if(myArray[i]==toFind) {
            found=true;
        }
    }

    System.out.println(myArray.length);
    System.out.println(found); 
}

1

Aşağıdaki Java 8 kodunu kullanarak ilkel int dizinizi bir Tamsayılar dizisi listesine dönüştürebilirsiniz,

List<Integer> arrayElementsList = Arrays.stream(yourArray).boxed().collect(Collectors.toList());

contains()Listenin belirli bir öğe içerip içermediğini kontrol etmek için yöntemi kullanın.

boolean containsElement = arrayElementsList.contains(key);

0

bu java 8'de çalıştı

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}

İlk eşleşmede hemen geri dönmelidir, bunun yerine bu, eşleşmeyi bulsa bile dizideki tüm öğeleri taramaya devam edecektir. (Bir dizi üç parçayı düşünün)
TriCore

Haklısınız, bu genel statik boolean içerir (son int [] dizi, son int anahtar) {return Arrays.stream (dizi) .anyMatch (n-> n == anahtar); }
Farhad Baghirov

Java 8 akışı anyMatch, kısa devre işlemidir ve dizideki tüm öğeleri taramaz.
LordParsley

@LordParsley Yukarıdaki kodun amacı dizideki öğeyi kontrol etmektir, dizinin tüm öğelerini taramak değildir.
Farhad Baghirov

Üzgünüm, cevabın düzenlendiğini görüyorum. Tek bir yol bulursa hepsini taramaya gerek kalmayacağı için doğru olduğunu yineliyordum.
LordParsley

0

Aşağıdaki yöntemlerle bir nesnedeki java.util.Arraysdiziyi dönüştürmek için sınıfı kullanabilirsiniz :T[?]List<T>contains

Arrays.asList(int[] array).contains(int key);

-1

İnt dizinizin ne kadar büyük olacağına bağlı olarak, koleksiyonları kullanırsanız ve .containsher seferinde bir öğe dizisi üzerinde yinelemek yerine çok daha iyi performans elde edersiniz :

import static org.junit.Assert.assertTrue;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

public class IntLookupTest {

int numberOfInts = 500000;
int toFind = 200000;
int[] array;

HashSet<Integer> intSet;

@Before
public void initializeArrayAndSet() {
    array = new int[numberOfInts];
    intSet = new HashSet<Integer>();
    for(int i = 0; i < numberOfInts; i++) {
        array[i] = i;
        intSet.add(i);
    }
}

@Test
public void lookupUsingCollections() {
    assertTrue(intSet.contains(toFind));
}

@Test
public void iterateArray() {
    assertTrue(contains(array, toFind));

}

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}
}

-1

1.Çözüm

Asıl soru yalnızca basitleştirilmiş bir çözüm istediğinden (daha hızlı değil), işte tek satırlık bir çözüm:

public boolean contains(int[] array, int key) {
    return Arrays.toString(array).matches(".*[\\[ ]" + key + "[\\],].*");
}

Açıklama: Javadoc Arrays.toString(), sonucun köşeli parantez içine alındığını ve bitişik öğelerin "," karakterleriyle ayrıldığını belirtir (virgül ve ardından boşluk). Böylece buna güvenebiliriz. Önce arraybir dizgeye çeviririz ve sonra keybu dizgede olup olmadığını kontrol ederiz . Elbette "alt sayıları" kabul edemeyiz (örn. "1234", "23" içerir), bu nedenle keyönünde bir açılış parantezi veya bir boşluk ve ardından bir kapanış parantezi veya bir virgül geldiği modelleri aramalıyız .

Not: Kullanılan regexp kalıbı ayrıca negatif sayıları doğru bir şekilde işler (dize temsili eksi işaretiyle başlar).

2.Çözüm

Bu çözüm zaten yayınlandı ancak hatalar içeriyor, bu yüzden doğru çözümü gönderiyorum:

public boolean contains(int[] array, int key) {
    Arrays.sort(array);
    return Arrays.binarySearch(array, key) >= 0;
}

Ayrıca bu çözümün bir yan etkisi vardır: değiştirir array(sıralar).


String handlig genellikle pahalıdır, neden birisi karakterleri string olarak ele alsın?
Denys Vitali

@DenysVitali Çünkü operasyonun zaten çalışan, verimli bir çözümü var ve daha kısa bir çözüm arıyor . Ve bunlar daha kısa. Bu soru performansla ilgili değil.
icza

O zaman soruyu yanlış anlamalıydım, sorduğum için üzgünüm
Denys Vitali

-5

Bunu Integer.parseInt()yapmayı dene .....

public boolean chkInt(final int[] array){
    int key = false;

    for (Integer i : array){


          try{

                   Integer.parseInt(i);
                   key = true;
                   return key;

             }catch(NumberFormatException ex){

                   key = false;

                   return key;

              }


     }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.