Home Hardware Networking Programmazione Software Domanda Sistemi
Conoscenza del computer >> Programmazione >> Java Programming >> .

Come posso gestire e manipolare in modo efficiente grandi quantità di dati utilizzando il cumulo in Java?

I cumuli sono eccellenti strutture di dati per gestire e manipolare in modo efficiente i dati quando è necessario trovare ripetutamente l'elemento minimo o massimo. In Java, la classe `PriorityQueue` fornisce un'implementazione di heap (min-heap per impostazione predefinita). Ecco come è possibile utilizzare efficacemente il mucchio per gestire e manipolare set di dati di grandi dimensioni:

1. Comprensione delle basi

* Proprietà heap: Un heap mantiene un ordine specifico. In un minimo, la chiave del nodo genitore è sempre inferiore o uguale alle chiavi dei suoi figli. In un heap massimo, la chiave del nodo genitore è sempre maggiore o uguale alle chiavi dei suoi figli.

* `priorityQueue` in Java: `PriorityQueue` implementa un minimo per impostazione predefinita. Puoi personalizzarlo per essere un massimo che utilizza un "comparatore" personalizzato.

* Complessità temporale:

* `aggiungi (elemento)`:o (log n) in media (dove n è il numero di elementi nel heap)

* `remove ()` (Rimuove la radice, min o max):O (log n)

* `peek ()` (restituisce la radice):o (1)

* `contiene (elemento)`:o (n) nel caso peggiore. I cumuli non sono * efficienti per la ricerca di elementi arbitrari.

* Costruire un mucchio da un array:O (n)

2. Tecniche core e casi d'uso

* Trovare gli elementi K più piccoli/più grandi: Questa è un'applicazione classica di heap.

* k più piccolo:

1. Crea un heap massimo di dimensioni `k` dai primi elementi` k` del tuo set di dati.

2. Iterare attraverso gli elementi rimanenti. Se un elemento è più piccolo della radice del heap massimo, rimuovere la radice e inserire il nuovo elemento.

3. Dopo aver elaborato tutti gli elementi, il massimo conterrà gli elementi più piccoli.

* k più grande:

1. Crea un minimo di dimensioni `k` dai primi elementi` k` del tuo set di dati.

2. Iterare attraverso gli elementi rimanenti. Se un elemento è più grande della radice del minimo, rimuovere la radice e inserire il nuovo elemento.

3. Dopo aver elaborato tutti gli elementi, il minimo conterrà i maggiori elementi di K`.

`` `Java

import java.util.priorityqueue;

import java.util.cparator;

import java.util.list;

import java.util.arraylist;

Classe pubblica heapexamples {

Elenco statico pubblico findklarges (int [] nums, int k) {

PriorityQueue MinHeap =new PriorityQueue <> (); // min-heap per impostazione predefinita

per (int num:nums) {

if (minHeap.size () MinHeap.Add (num);

} else if (num> minHeap.peek ()) {

MinHeap.Poll (); // rimuovi il più piccolo

MinHeap.Add (num); // Aggiungi il nuovo elemento più grande

}

}

// converti l'heap in un elenco (opzionale, per ordini specifici)

Elenco klargest =new ArrayList <> (MinHeap);

klargest.sort (comparatore.reversoutder ()); // Ordina la discesa per il più grande al più piccolo

restituire klargest;

}

Elenco statico pubblico findksmallest (int [] nums, int k) {

PriorityQueue maxHeap =new priorityQueue <> (comparatore.ReverseOrder ()); // max-heap

per (int num:nums) {

if (maxHeap.size () maxHeap.add (num);

} else if (num maxHeap.Poll (); // rimuovi il più grande

maxHeap.add (num); // Aggiungi il nuovo elemento più piccolo

}

}

// converti l'heap in un elenco (opzionale, per ordini specifici)

Elenco ksMallest =new ArrayList <> (maxHeap);

ksMallest.sort (comparatore.naturalorder ()); // Ordina ascendente per il più piccolo a più grande

restituire ksmallest;

}

public static void main (string [] args) {

int [] data ={5, 2, 9, 1, 5, 6};

int k =3;

Elenco più grande =findklargest (dati, k);

System.out.println ("k più grande:" + più grande); // output:k più grande:[9, 6, 5]

Elenco più piccolo =findksmallest (dati, k);

System.out.println ("k più piccolo:" + più piccolo); // output:k più piccolo:[1, 2, 5]

}

}

`` `

* Fusione di elenchi ordinati K:

1. Crea un minimo per archiviare il primo elemento da ogni elenco. Ogni elemento nel heap dovrebbe archiviare il valore * e * l'indice dell'elenco da cui proveniva.

2. Rimuovere ripetutamente l'elemento minimo dal mucchio. Questo è il prossimo elemento nell'elenco ordinato unito.

3. Se l'elenco da cui è arrivato l'elemento rimosso ha più elementi, aggiungi l'elemento successivo da quell'elenco al mucchio.

4. Continua fino a quando il mucchio è vuoto.

`` `Java

import java.util.priorityqueue;

import java.util.list;

import java.util.arraylist;

Classe pubblica MergesortedLists {

Node di classe statica privata implementa {

valore int;

int listIndex;

int elementIndex;

nodo pubblico (valore int, int listIndex, int elementIndex) {

this.value =value;

this.ListIndex =listIndex;

this.elementIndex =elementIndex;

}

@Override

public int comparazione (nodo altro) {

return integer.compare (this.value, altro.value);

}

}

Elenco statico pubblico MergeksortedLists (elenco > liste) {

Elenco MalgedList =new ArrayList <> ();

PriorityQueue minHeap =new priorityQueue <> ();

// Aggiungi il primo elemento da ogni elenco al mucchio

per (int i =0; i if (! lists.get (i) .isempty ()) {

MinHeap.Add (nuovo nodo (lists.get (i) .get (0), i, 0));

}

}

while (! minHeap.isempty ()) {

Nodo corrente =minHeap.Poll ();

MEDGEDLIST.Add (Current.Value);

int listIndex =current.ListIndex;

int elementIndex =current.elementIndex;

// Aggiungi l'elemento successivo dallo stesso elenco se esiste

if (elementIndex + 1 MinHeap.Add (nuovo nodo (lists.get (listIndex) .get (elementIndex + 1), listIndex, elementIndex + 1));

}

}

restituzione di un ficcanaso;

}

public static void main (string [] args) {

Lista > list =new ArrayList <> ();

lists.add (list.of (1, 4, 7));

lists.add (list.of (2, 5, 8));

lists.add (list.of (3, 6, 9));

Elenco unito =MergekSortedLists (elenchi);

System.out.println ("Elenco unito:" + unito); // output:elenco unito:[1, 2, 3, 4, 5, 6, 7, 8, 9]

}

}

`` `

* Applicazioni in coda prioritaria:

* Pianificazione delle attività: Dai la priorità alle attività basate sull'urgenza ed eseguile in ordine.

* Algoritmi grafici (Dijkstra, A*): Conservare i nodi da visitare in base alla loro distanza stimata dalla fonte.

* Simulazione dell'evento: Eventi di processo in ordine cronologico.

3. Considerazioni importanti per i dati di grandi dimensioni

* Gestione della memoria: Se il tuo set di dati è * estremamente * grande e non si adatta alla memoria, considera:

* Ordinamento esterno (unisciti con un mucchio): Rompi i dati in blocchi più piccoli che si adattano alla memoria, ordina ogni pezzo (usando un mucchio o altri metodi), quindi unisci i blocchi ordinati usando un mucchio. Ciò comporta la lettura e la scrittura di dati sul disco.

* Algoritmi di streaming: Algoritmi progettati per elaborare i dati in un unico passaggio, minimizzando l'utilizzo della memoria. Mentre un mucchio puro potrebbe non essere adatto per lo streaming in tutti i casi, è possibile utilizzare tecniche come il campionamento del serbatoio in combinazione con il cumulo.

* Comparatore personalizzato: Per oggetti complessi, implementa un `comparatore` che definisce il modo in cui i tuoi oggetti dovrebbero essere confrontati nel heap.

* Collezione dei rifiuti: I cumuli di grandi dimensioni possono esercitare pressione sul collettore della spazzatura. Sii consapevole della creazione e dello smaltimento degli oggetti per evitare colli di bottiglia.

* Profilazione: Usa gli strumenti di profilazione per identificare gli hotspot delle prestazioni nel codice. Questo può aiutarti a determinare se le operazioni di heap sono il collo di bottiglia e se è necessario ottimizzarle ulteriormente.

* Tipi primitivi (quando possibile): Se stai lavorando con tipi primitivi (ad esempio, `int`,` double`), considera di usare un `int []` o `doppio []` come archiviazione sottostante per il tuo heap, piuttosto che oggetti `interi 'o` double`. Ciò può ridurre le spese generali di memoria e migliorare le prestazioni. Quindi implementeresti tu stesso la logica heap (usando gli indici dell'array). Ciò è necessario solo in scenari estremamente sensibili alle prestazioni.

* Pre-allocazione: Se conosci la dimensione massima approssimativa del tuo heap in anticipo, pre-allocare il `priorityQueue` con quella capacità. Ciò può impedire alle operazioni di ridimensionamento, che possono essere costose.

Esempio:priorità alle voci del registro

Immagina di elaborare un file di registro di grandi dimensioni e devi estrarre le voci di registro più critiche in base a un punteggio di gravità.

`` `Java

import java.util.priorityqueue;

import java.util.cparator;

import java.util.list;

import java.util.arraylist;

class logentry {

Messaggio stringa;

int gravità;

public logentry (messaggio stringa, int gravità) {

this.message =messaggio;

this. severity =gravità;

}

@Override

public String toString () {

restituisce "Logentry {" +

"Message ='" + Message +' \ '' +

", severità =" + gravità +

'}';

}

}

classe pubblica loganalyzer {

Elenco statico pubblico Find Mostcritical (Elenco Logs, int n) {

PriorityQueue MinHeap =new PriorityQueue <> (comparatore.comPareningInt (Logentry ::getSeverity));

for (logentry log:logs) {

if (minHeap.size () MinHeap.Add (log);

} else if (log.getSeverity ()> minHeap.peek (). getSeVity ()) {

MinHeap.Poll ();

MinHeap.Add (log);

}

}

Elenco Criticallogs =new ArrayList <> (MinHeap);

criticallogs.sort (comparatore.comparingint (logentry ::getSeVity) .Reversed ());

restituire criticallog;

}

public static void main (string [] args) {

Elenco logs =new ArrayList <> ();

Logs.Add (nuovo Logentry ("Errore a bassa priorità", 1));

Logs.Add (nuovo Logentry ("Avviso di media priorità", 5));

Logs.Add (nuovo Logentry ("Errore critico - Crash di sistema", 10));

Logs.Add (nuovo Logentry ("Un altro evento a bassa priorità", 2));

Logs.Add (nuovo Logentry ("Problema di rete ad alta priorità", 8));

Logs.Add (nuovo Logentry ("Problema del database di media priorità", 6));

int n =3;

Elenco critical =find Mostcritical (logs, n);

System.out.println ("Log più critici:" + critico);

// output:registri più critici:[logentry {message ='critical Error - system crash', severità =10}, logentry {message ="esso di rete ad alta priorità", severità =8}, logentry {message ='Problema di database di priorità di media', severità =6}]

}

}

`` `

In sintesi:

I cumuli sono potenti per trovare valori estremi (min/max) e dare la priorità agli elementi in un set di dati. Quando si tratta di grandi quantità di dati, sii consapevole dell'utilizzo della memoria, considerare se necessario le tecniche di ordinamento esterne e profilare il codice per identificare e affrontare i colli di bottiglia delle prestazioni. La classe `PriorityQueue` in Java è un comodo punto di partenza, ma potrebbe essere necessario personalizzarlo o implementare la propria logica heap per casi d'uso specifici e vincoli di memoria.

 

Programmazione © www.354353.com