2015-04-21 53 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);