Esiste un modello che aiuterà questa struttura dati

5

Sto facendo un progetto java. La mia struttura principale contiene 2 liste con elementi di tipo A, l'altro tipo B. B stesso contiene una lista di oggetti che possono contenere elementi di A.

Deve essere che quando un elemento dalla lista di A viene rimosso deve essere rimosso da tutti i sottoelementi della lista B. anche se un possibile membro della lista A è aggiunto ad una B dovrebbe anche essere aggiunto ad A. E anche Ho bisogno di un modo per trovare gli oggetti parent contenenti un A.

Finora ho un'implementazione "funzionante" - usando molti loop. Mi chiedo: puoi suggerire schemi che mi aiuteranno in questo compito?

maggiori dettagli.

Penso che il mio problema principale sia che ho oggetti A con più genitori. E quando aggiungo / rimuovi da un genitore ho bisogno di aggiustare altri genitori.

Non posso fare a meno di credere che un simile problema sia già risolto.

per chiarire: ho un List<A> principale e ogni B contiene un List<A>

Quando una A viene rimossa dall'elenco principale, deve essere rimossa da tutti B. Ma non quando viene rimossa da una B. È essenziale che tutte le A utilizzate nell'applicazione siano presenti nell'elenco principale.

    
posta bdecaf 18.02.2012 - 11:51
fonte

4 risposte

2

Non penso che tu abbia bisogno di uno schema particolarmente complesso per questo. Fare il giro delle strutture e apportare le modifiche più ovvie dovrebbe funzionare (supponendo che non si verifichino problemi di concorrenza)

Alcune idee da considerare:

  • Crea gli oggetti List<A> in HashMap<A, Set<B>> , dove la chiave è un oggetto di tipo A e il valore è un insieme di tutti gli oggetti B genitore.
  • Quindi puoi facilmente trovare tutti i genitori di una data A e, se rimuovi un'istanza di A, puoi trovare rapidamente tutti gli oggetti B di cui hai bisogno anche per rimuovere l'istanza di A.
  • Ovviamente dovrai aggiornare questa struttura ogni volta che aggiungi una A a una B, ma questa è solo un'operazione O (1).
  • Gli oggetti B dovrebbero avere una funzione remove(A a) che incapsula tutto il codice richiesto per rimuovere una determinata istanza A dalla struttura dati interna. Questo dovrebbe chiamare ricorsivamente una funzione di rimozione simile in qualsiasi sottostruttura.
risposta data 18.02.2012 - 16:20
fonte
3

Potresti farlo con riferimenti deboli . Avvolgi un List<WeakReference<A>> e il wrapper ha un riferimento alla struttura dei dati master (pensando a un set ma non è sicuro) che mantiene i riferimenti reali a ogni A. Quando elimini da una struttura avvolta, rimuovi il riferimento debole e cancelli dal set, che dovrebbe essere l'unico riferimento reale a ciascuna A. Ciò ha alcuni problemi con il lavoro con gli elenchi a causa dell'eliminazione dei riferimenti deboli.

    
risposta data 18.02.2012 - 15:41
fonte
0

per qualche strano reasone non posso aggiungere commenti sotto la tua domanda. Quindi ho intenzione di commentare qui. Per favore non votare questo se non ti piace. Non ho scelta .

Sembra che questo sia molto simile ai problemi nel database sql. Ad esempio

create table A
(
    id int not null primary key,
    val varchar(20) not null
);

create table B (
    id int not null primary key,
    val varchar(20) not null
);

create table BA (
    b_id int not null ,
    a_id int not null,
    constraint ba_b_fk foreign key (b_id) references B(id),
    constraint ba_a_fk foreign key (a_id) references A(id) on delete CASCADE  ,
    constraint ba_pk primary key (b_id , a_id)
);

drop table ba;

insert a (id, val) values (1 , 'a1');
insert a (id, val) values (2 , 'a2');
insert a (id, val) values (3 , 'a3');
insert a (id, val) values (4 , 'a4');

insert b (id, val) values (1 , 'b1');
insert b (id, val) values (2 , 'b2');

insert ba (b_id , a_id) values (1 , 2);
insert ba (b_id , a_id) values (1 , 3);

delete a where a.id = 2

select * from ba;
--  only ( 1 , 3) left in ba

Non ho familiarità con java (ma lavoro in C #). Comunque qualche pseudo-codice qui che potrebbe aiutare. Ho finito il tempo per implementarlo. (si prega di notare che ATable, BTable sono singleton)

class RecA {
    public int id;
    public string val;
    public override bool Equal(object x) { ... }
    public override int GetHashCode() { return ... }
}
class RecB {
    public int id;
    public string b_val;
    public HashSet<A> listA;



}
class ATable extends HashSet<RecA> {

}

class BTable extends HashSet<RecB> {

    public static Dictionary<A, List<B>> dict = new Dictionary<A, List<B>>() ; // to track relationship between BTable and ATable
    public override void Add(RecB) {
    }

    public void addA_to_BTable(RecA) {
        // use the dictionary to track it
    }

    public void delete_A(RecA) {
    }
}
    
risposta data 18.02.2012 - 15:18
fonte
0

Se la tua lista principale contiene solo A che sono in alcune B, puoi calcolare l'elenco principale delle B che hai. (Puoi in seguito pensare a mettere in cache la lista principale.)

    
risposta data 18.02.2012 - 15:49
fonte

Leggi altre domande sui tag