5

我已经成功实现了一个使用两种常见数据结构的 java 程序:aTree和 aStack以及一个允许用户输入树节点 ID 并获取与其父节点相关的信息的接口。您可以在我的 GitHub src 中查看该程序的最新版本

背景

我编写的这个特设程序用于通过比较文件中的数据来研究数百种生物体中基因流的进化,该文件包含以下内容:FeatureIDs = StringPrimitives(再往下,这些在第一列中列为"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)。如果他们这样做了,则计数器将增加。一旦比较完成(堆栈为空),程序将返回计数。

现在我想做的不仅仅是计算,而是列出哪些 FeatureID 符合比较标准。因此,与其返回表示节点 A 和节点 B 之间有 4100 个符合条件的 FeatureID 的计数器,我想要一个所有 4100 个Strings符合在节点 A 和节点 B 之间比较的条件的 FeatureID 的列表。我要保存稍后将该列表作为文件列出,但这里不关心。这意味着我可能不得不放弃以前运行良好的double2D 数组/堆栈方案。double

问题

知道问题出在哪里,是否有一个巧妙的解决方案来解决这个问题,我可以在不向进程添加更多数据的情况下更改输入数据文件或代码(tlacMain.java)中的某处?我只需要想法。

4

1 回答 1

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 数组将其与计算中的矩阵列匹配。您可以为每个匹配项创建一个and ,而不是增加一个intinside 。然后返回,以便您可以在该函数之外使用它进行报告。addedInternalArrayList<Integer>add(id)ArrayList

ArrayList<Integer> addedFeatureIds = addedInternal(parentStackOne, childStackOne, featureIdStack);
于 2015-04-21T21:18:14.917 回答