我已经成功地实现了一个使用两种常见数据结构的 java 程序:一个 Tree
和一个 Stack
以及一个允许用户输入树的接口(interface)节点 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,...
问题
以前,只需从数据文件中创建一个 double 的二维数组就足够了(该数组排除了文件中的第一行和 FeatureID,因为它们是字符串),然后使用该二维数组制作双
堆栈。堆栈将根据用户输入和 Tree
确定的父节点和子节点创建。
然后,父堆栈和子堆栈中的数据将同时弹出(从而确保比较相同的 FeatureID,而不必实际将该数据包含在 DS 中)并根据它们是否比较它们的值满足定义的条件(即如果两个值都 >= 0.75)。如果他们这样做了,计数器就会增加。一旦比较完成(堆栈为空),程序将返回计数。
现在我要做的不是仅仅计算,而是列出符合比较标准的 FeatureID。因此,我没有返回表示节点 A 和节点 B 之间有 4100 个 FeatureID 符合条件的计数器,而是我想要一个包含所有 4100 个 FeatureID Strings
的列表,这些列表满足节点 A 和节点之间比较的条件B. 稍后我会将该列表保存为文件,但这与这里无关。这意味着我可能不得不放弃以前运行良好的 double
二维数组/double
堆栈方案。
问题
知道问题出在哪里,是否有解决此问题的巧妙方法,我可以更改输入数据文件或我的代码 (tlacMain.java) 中的某处,而无需向流程中添加更多数据?我只需要想法。
最佳答案
我不太确定我是否正确理解了您的问题,但您可以将当前比较的 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 读入 double 矩阵。对于每列 i
在矩阵中,我们还需要相应的 featureID。要同时返回 double 矩阵和包含 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);
关于java - 比较java中的结构化数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29783095/