Soluzione SQL
Potresti caricare tutti i dati demografici in un database SQL:
CREATE TABLE PERSON(Id integer PRIMARY KEY, zip text, birth date, gender char /*... */);
...
Purtroppo l'istruzione di importazione dei file non è standard SQL (ad esempio BULK INSERT
per SQLServer, LOAD DATA INFILE
per mysql oppure usa SQL*Loader per Oracle).
Il modo più semplice ed efficiente sarebbe quindi quello di utilizzare le funzioni di aggregazione con una clausola GROUP BY
per contare numero di persone che condividono gli stessi valori per le colonne di raggruppamento e mantenendo solo quelli con i duplicati, utilizzando un HAVING
clausola:
SELECT zip, birth, gender, count(*) FROM PERSON
GROUP BY zip, birth, gender
HAVING count(*)>1;
Demo online
Soluzione di file ordinati
Puoi anche ordinare il tuo file di censimento per zip, nascita e sesso. Quindi è possibile leggere i dati, confrontare ogni record letto con quello precedente e, se lo stesso, contare fino a quando questo valore non cambia per un record.
Pseudocodice:
lastrecord = { };
counter = 1;
while there's a record to read {
read record
if (record.zip == lastrecord.zip
and record.birth==lastreacord.birth
and record.gender == lastrecord.gender) {
counter = counter +1;
}
else {
if (counter>1) { // output the count of duplicates
write lastrecord.zip, lastrecord.birth, lastrecord.gender, counter
}
counter =1;
}
lastrecord = record;
}
if (counter>1) { // output the count of duplicates
write lastrecord.zip, lastrecord.birth, lastrecord.gender,
}
Mappa associativa
Un ultimo modo, qui sarebbe quello di leggere ogni record come viene, e memorizzare i 3 valori di tupla in una mappa:
- memorizza 1 se la tupla non è stata ancora caricata
- incrementa il valore della tupla esistente se esiste già
Alla fine, iterate attraverso la mappa ed elaborate gli elementi con un conteggio maggiore di 1. Ok, questo vi costerà un po 'di memoria ;-)