2015-04-21 14 views
5

Ho implementato con successo un programma java che utilizza due strutture di dati comuni: uno Tree e uno Stack insieme a un'interfaccia che consente a un utente di immettere un ID nodo dell'albero e ottenere informazioni su di esso in relazione al suo genitore. Potete guardare l'ultima versione di questo programma at my GitHub src for this programconfrontando i dati strutturati in java

Sfondo

Questo programma ad hoc che ho scritto è usato per studiare l'evoluzione del flusso genico tra centinaia di organismi confrontando i dati in un file che consiste of: FeatureIDs = String primitive (più in basso queste sono elencate nella prima colonna come "ATM-0000011", "ATM-0000012" e così via) e sono costituite dai punteggi associati alla loro presenza o assenza in un nodo particolare nell'albero e questi sono double primitivi.

Ecco ciò che il file di dati si presenta come:

"FeatureID","112","115","120","119","124",...//this line has all tree node IDs 
"ATM-0000011",2.213e-03,1.249e-03,7.8e-04,9.32e-04,1.472e-03,... //scores on these lines 
"ATM-0000012",2.213e-03,1.249e-03,7.8e-04,9.32e-04,1.472e-03,...//correspond to node ID 
"ATM-0000013",0.94,1.249e-03,7.8e-04,9.32e-04,1.472e-03,...//order in the first line 
... //~30000 lines later 
"ATM-0036186",0.94,0.96,0.97,0.95,0.95,... 

Il problema

In precedenza, era abbastanza buono per fare solo una matrice 2D delle doppie a partire da file di dati (l'array esclusa la prima riga nel file e i FeatureIDs, perché sono stringhe) e utilizzare l'array 2D per creare stack double. Gli stack verranno creati per i nodi padre e figlio come determinato dall'input dell'utente e dallo Tree.

I dati negli stack padre e figlio verrebbero quindi eliminati contemporaneamente (garantendo in tal modo che gli stessi FeatureIDs fossero confrontati senza dover effettivamente includere tali dati nel DS) e confrontati i loro valori in base al fatto hanno incontrato una condizione definita (cioè se entrambi i valori erano> = 0,75). Sì, lo hanno fatto, un contatore sarebbe stato incrementato. Una volta terminati i confronti (le pile erano vuote) il programma restituiva i conteggi.

Ora quello che voglio fare invece di contare, è fare una lista di cui ID di funzionalità hanno soddisfatto i criteri di confronto. Quindi, invece di restituire il contatore che dice che ci sono 4100 ID funzione tra il nodo A e il nodo B che soddisfano i criteri, voglio un elenco di tutti 4100 FeatureID Strings che soddisfano i criteri confrontati tra il nodo A e il nodo B. Ho intenzione di salva questa lista come file più tardi, ma non è un problema qui. Ciò significa che probabilmente dovrò abbandonare lo schema stack double 2D/double che in precedenza aveva funzionato così bene.

La questione

Sapendo qual è il problema, c'è una correzione intelligente a questo problema in cui ho potuto fare una modifica al file di dati di input, o da qualche parte nel mio codice (tlacMain.java), senza aggiungendo molti più dati al processo? Ho solo bisogno di idee.

+0

Dove si contano i featureID, perché non li si aggiunge a una struttura di List come un ArrayList? –

+0

(questo vale anche per @felixbr) il problema con questo approccio è che i metodi utilizzati per i confronti contengono una pila padre e figlio di tipo che non contiene le informazioni ID caratteristica. Vedere l'implementazione nel mio codice su Github https://github.com/asobin/sobin/blob/master/PhyloTLaC/src/tlacMain.java#L253 –

risposta

2

Non sono sicuro di aver compreso correttamente la domanda, ma invece di incrementare un contatore è sufficiente aggiungere il FeatureID attualmente comparato a un ArrayList e in seguito scriverlo in un file.

Se hai bisogno di un elenco per ogni confronto potresti avere qualcosa come HashMap<Comparison, ArrayList<String>>.

edit: Ho letto il tuo commento e ha cercato di trovare una soluzione senza cambiare troppo:

 String[] firstLine = sc.nextLine().split(regex); 
     //line is the line of input being read in thru the inputFile 
     int line = 0; 
     //array of doubles will hold the data to be put in the stacks 
     double [][] theData = new double [28420][firstLine.length]; 
     while(sc.hasNext()) 
     { 
      String lineIn = sc.nextLine(); 
      String[] lineInAsString = lineIn.split(regex); 
      for(int i = 1; i < lineInAsString.length; i++) 
      { 
       theData[line][i] = Double.parseDouble(lineInAsString[i]); 
      } 
      line++; 
     } 

     sc.close(); 

     return theData; 

In questa parte della vostra funzione getFile(), si legge il csv in una doppia matrice. Per ogni colonna i nella matrice è necessario anche il corrispondente ID funzione. Per restituire sia la matrice dei doppi che una lista con ID funzionalità, è necessaria una classe contenitore.

class DataContainer { 
    public double[][] matrix; 
    public int[] featureIds; 

    public DataContainer(double[][] matrix, int[] featureIds) { 
     this.matrix = matrix; 
     this.featureIds = featureIds; 
    } 
} 

Ora possiamo modificare il codice sopra per restituire entrambi.

String[] firstLine = sc.nextLine().split(regex); 
    // array of ids 
    int[] featureIds = new int[firstLine.length]; 

    for(int i = 1; i < lineInAsString.length; i++) 
    { 
     featureIds[i] = Integer.parseInt(firstLine[i]); 
    } 

    // ... same stuff as before 

    return new DataContainer(newMatrix, featureIds); 

Nella funzione principale è ora possibile estrarre entrambe le strutture. Così, invece di

double newMatrix[][] = getFile(args); 

è possibile scrivere

DataContainer data = getFile(args); 
double[][] newMatrix = data.matrix; 
int[] featureIds = data.featureIds; 

È ora possibile utilizzare la matrice featureIds per abbinare in su con le colonne della matrice nei calcoli. Invece di incrementare uno all'interno di addedInternal, è possibile creare un ArrayList<Integer> e add(id) per ogni partita. Quindi restituire il ArrayList, in modo da poterlo utilizzare per la segnalazione al di fuori di tale funzione.

ArrayList<Integer> addedFeatureIds = addedInternal(parentStackOne, childStackOne, featureIdStack);