我已成功实现了一个使用两种常见数据结构的java程序:Tree
和Stack
以及允许用户输入树节点ID并获取有关信息的接口它与其父母有关。您可以在at my GitHub src for this program
背景
我写的这个临时程序用于通过比较文件中的数据来研究数百种生物体中基因流的演变: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,因为它们是字符串),然后使用2D数组制作double
堆栈。将根据用户输入和Tree
确定父节点和子节点的堆栈。
然后,父和子堆栈中的数据将同时弹出(从而确保比较相同的FeatureID而不必在DS中包含该数据)并根据它们是否比较它们的值满足定义的条件(即,如果两个值都> = 0.75)。他们做了,计数器会增加。比较完成后(堆栈为空),程序将返回计数。
现在我想要做的不仅仅是计数,而是制作一个符合比较标准的列表。因此,我没有返回表示节点A和节点B之间有4100个FeatureID符合条件的计数器,而是希望列出满足在节点A和节点B之间进行比较的标准的所有4100 FeatureID Strings
。我打算稍后将该列表保存为文件,但这并不重要。这意味着我可能不得不放弃以前运作良好的double
2D数组/ double
堆栈方案。
问题
知道问题是什么,是否有一个聪明的解决方法,我可以对输入数据文件或代码中的某个地方(tlacMain.java)进行更改,而无需向进程添加更多数据?我只需要想法。
答案 0 :(得分: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数组将其与计算中的矩阵列进行匹配。您可以为每场比赛创建int
和addedInternal
,而不是在ArrayList<Integer>
内增加add(id)
。然后返回ArrayList
,以便您可以将其用于该功能之外的报告。
ArrayList<Integer> addedFeatureIds = addedInternal(parentStackOne, childStackOne, featureIdStack);