Sobes.tech
Middle

Как можно организовать быстрый поиск в неотсортированном массиве целых чисел, содержащем миллионы значений?

sobes.tech MI

Válasz az MI-től

Hashing. Létrehozhatsz HashSet vagy HashMap-et egy tömb elemeiből.

import java.util.HashSet;
import java.util.Random;

public class SearchExample {

    public static void main(String[] args) {
        int size = 1000000;
        int[] array = new int[size];
        Random random = new Random();
        for (int i = 0; i < size; i++) {
            array[i] = random.nextInt(size * 10); // Véletlenszerű számokkal töltjük fel
        }

        // Gyors keresés szervezése HashSet segítségével
        HashSet<Integer> set = new HashSet<>(size);
        for (int value : array) {
            set.add(value);
        }

        int target = array[size / 2]; // Egy elem keresése a tömbből

        long startTime = System.nanoTime();
        boolean found = set.contains(target); // Átlagosan O(1)
        long endTime = System.nanoTime();
        System.out.println("Találva: " + found);
        System.out.println("Keresési idő HashSet-ben (ns): " + (endTime - startTime));

        // Lineáris keresés összehasonlításként - O(n)
        startTime = System.nanoTime();
        boolean foundLinear = false;
        for (int value : array) {
            if (value == target) {
                foundLinear = true;
                break;
            }
        }
        endTime = System.nanoTime();
        System.out.println("Találva (lineáris): " + foundLinear);
        System.out.println("Lineáris keresési idő (ns): " + (endTime - startTime));
    }
}

Továbbá, ha megengedett a tömb módosítása és többszöri keresésre van szükség, egyszerűen rendezheted a tömböt (Arrays.sort()) és utána használhatod a bináris keresést (Arrays.binarySearch()). A rendezés $O(n \log n)$-t vesz igénybe, minden további keresés pedig $O(\log n)$.

import java.util.Arrays;
import java.util.Random;

public class SortedSearchExample {

     public static void main(String[] args) {
        int size = 1000000;
        int[] array = new int[size];
        Random random = new Random();
        for (int i = 0; i < size; i++) {
            array[i] = random.nextInt(size * 10); // Véletlenszerű számokkal töltjük fel
        }

        int target = array[size / 2]; // Keresett elem

        // Egyszeri rendezés - O(n log n)
        long startTime = System.nanoTime();
        Arrays.sort(array);
        long endTime = System.nanoTime();
        System.out.println("Rendezési idő (ns): " + (endTime - startTime));

        // Bináris keresés - O(log n)
        startTime = System.nanoTime();
        int index = Arrays.binarySearch(array, target);
        endTime = System.nanoTime();
        boolean found = index >= 0;
        System.out.println("Találva: " + found);
        System.out.println("Bináris keresés idő (ns): " + (endTime - startTime));
    }
}

A választás a hash-elés és a rendezés között attól függ, hogy milyen gyakran fog történni a keresés és hogy megengedhető-e a tömb módosítása. Egyszeri vagy ritka keresés esetén a hash-elés gyorsabb lehet (a rendezés hiánya miatt), de extra memóriát igényel. Többszöri keresés esetén a rendezés utáni bináris keresés hatékonyabb minden keresésnél.