2015-04-21 78 views
5

我已經成功實現了一個java程序,該程序使用兩種常見數據結構:TreeStack以及一個接口,該接口允許用戶輸入樹節點標識並獲得有關它的信息給其父母。你可以看一下這個方案在這裏的最新版本at my GitHub src for this program比較java中的結構化數據

背景

這個特設程序我寫的是在由文件數據進行比較,來研究在數百生物的基因流的演化作者:FeatureIDs = String基元(進一步下來,它們在第一列中列爲"ATM-0000011","ATM-0000012"等),並且由與它們在樹中的特定節點上的存在或缺失相關聯的分數組成,並且這些分數是double原語。

下面是數據文件的樣子:

"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,... 

的問題

此之前,它是不夠好,才使從數據文件雙打的二維數組(數組排除文件和FeatureID中的第一行,因爲它們是Strings),然後使用2D數組來製作double堆棧。根據用戶輸入和Tree確定父組和子組節點的堆棧。

然後,父級和子級堆棧中的數據將同時彈出(從而確保相同的FeatureID正在進行比較,而實際上不必將這些數據包含在DS中),並根據是否進行比較他們遇到了一個確定的條件(即如果兩個值都大於等於0.75)。如果他們做了,櫃檯會增加。一旦比較結束(堆棧爲空),程序將返回計數。

現在我想要做的,而不是僅僅計數,是做一個功能標識符符合比較標準的列表。因此,我不希望返回符合條件的節點A和節點B之間有4100個FeatureID的計數器,而是希望獲得滿足節點A和節點B之間比較條件的全部4100個功能ID Strings的列表。我要稍後將該列表保存爲文件,但這不在意。這意味着我可能不得不放棄以前工作得很好的double二維陣列/ double堆棧方案。

問題

知道問題是什麼,是有一個聰明的修復這個問題,我可以做出改變,以輸入的數據文件,或者某個地方在我的代碼(tlacMain.java),無將更多的數據添加到流程中?我只需要想法。

+0

如果您計算featureIDs,爲什麼不將它們添加到列表結構(如ArrayList)? –

+0

(這也適用於@felixbr)該方法的問題在於,用於比較的方法需要父類和子類Stack,它不包含FeatureID信息。在Github的代碼中查看實現https://github.com/asobin/sobin/blob/master/PhyloTLaC/src/tlacMain.java#L253 –

回答

2

我不太確定如果我正確理解您的問題,但不是遞增計數器,而是將當前比較的FeatureID添加到ArrayList中,然後將其寫入文件。

如果您需要列表進行每次比較,您可以使用類似HashMap<Comparison, ArrayList<String>>的東西。

編輯:我看了你的評論,並試圖拿出一個解決方案,無需改變太多:

 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; 

在你getFile()這部分功能,你讀了CSV成一個雙矩陣。對於矩陣中的每個列i,我們還需要相應的featureID。要返回雙精度矩陣和帶有featureID的列表,您需要一個容器類。

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

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

現在我們可以更改上面的代碼來返回兩者。

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); 

在您的主函數中,您現在可以提取兩個結構。因此,而不是

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

你可以寫

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

現在,您可以使用featureIds陣列在你的計算與矩陣的列匹配起來。相反,增加的intaddedInternal的,你可以創建一個每場比賽的ArrayList<Integer>add(id)。然後返回ArrayList,以便您可以將其用於該功能之外的報告。

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