0

好的,所以我在这个文件中有大约 1000 个重复的短语,所以手动执行此操作不是一种选择。请注意,这些是短语,而不是行或单词,每个“短语”大约有 10 行长。

我试图摆脱重复的短语,但唯一使“项目”(或短语)重复的是位置语法。例如:

    class Item0
    {
        position[]={4347.6001,0,3214.6399};
        azimut=128.81599;
        special="NONE";
        id=1;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4347.6, 3214.64, 0]; this setDir 128.816;";
    };
    class Item1
    {
        position[]={4347.6001,0,3214.6399};
        azimut=128.81599;
        special="NONE";
        id=2;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4347.6, 3214.64, 0]; this setDir 128.816;";
    };

现在前面两个词组是重复的,但是 ID 和 ITEM# 是不同的,所以识别重复词组的唯一方法是通过 position[]={} 参数。当 2 个短语具有相同的位置时,这两个短语是重复的,无论 ID 或 ITEM#。

所以我的目标是使用某种类型的代码、脚本、程序或正则表达式来删除所有重复的短语,但不影响第一个重复的短语。因此,如果存在三个重复,则留下一个短语,但删除两个短语。我该怎么做呢?


所需输入/输出的示例:

输入:

    class Item0
    {
        position[]={4347.6001,0,3214.6399};
        azimut=128.81599;
        special="NONE";
        id=1;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4347.6, 3214.64, 0]; this setDir 128.816;";
    };
        class Item1
    {
        position[]={4682.6001,0,3847.6399};
        azimut=128.81599;
        special="NONE";
        id=2;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4682.6, 3847.64, 0]; this setDir 128.816;";
    };
        class Item2
    {
        position[]={4347.6001,0,3214.6399};
        azimut=128.81599;
        special="NONE";
        id=3;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4347.6, 3214.64, 0]; this setDir 128.816;";
    };

输出:

    class Item0
    {
        position[]={4347.6001,0,3214.6399};
        azimut=128.81599;
        special="NONE";
        id=1;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4347.6, 3214.64, 0]; this setDir 128.816;";
    };
        class Item1
    {
        position[]={4682.6001,0,3847.6399};
        azimut=128.81599;
        special="NONE";
        id=2;
        side="EMPTY";
        vehicle="Land_fortified_nest_small";
        lock="UNLOCKED";
        skill=0.2;
        init="this setPos [4682.6, 3847.64, 0]; this setDir 128.816;";
    };
4

3 回答 3

0

如果它是类类型,那么您可以考虑使用 SET 并添加类元素。

      Set<Item> itemSet  = new HashSet<Item>;
      itemSet.add(new Item());

在添加所有项目结束时,您将只保留独特的项目。

您可以将 id 排除在争用之外,并且仍然通过检查项目是否已插入来检查插入的 id。考虑到 ID 是有序的,这将起作用。为了将 id 排除在外,请使用具有相同数据成员(不包括 id)的新类。

我使用了一个不同的例子(它很容易构建)希望它有所帮助

    int item[] = null;
    int offset = 0;
    int counter = 0;
    ArrayList<Integer> duplicateids = new ArrayList<Integer>();
    Set<Integer> afterDups= new HashSet<Integer>();
    for (int i : item) {
        counter++;
        //you can create a new class excluding the id and initialize it here
        if(!afterDups.add(i))
            duplicateids.add(counter);
    }

编辑 :

好的,我错过了从文件中挑选的东西,所以添加了这个答案。您可以检查每一行,并且鉴于您的文件是这种形式,您不会喜欢比较Class Item0id=1;行。休息一下,您可以逐行读取文件并将其放在字符串中。一旦一个类完成(由行的开头表示为class),您可以设置为文本创建另一个字符串。您将数据与凭证(idclass)分开。使用分隔符,您可以从中再次拆分字符串并重新创建文件。

public static void main(String args[])
{
    try{
        FileInputStream fstream = new FileInputStream("file.txt");
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String strLine;
        String seperator = "$$";
        //this contains the $$ seperated class data items
        String currentClassText = "";
        //this contains the $$ seperated class name the opening braces and the closing braces
        String  currentClassCredentilas= "";
        Set<String> texts = new HashSet<String>();
        ArrayList<String> credentials = new ArrayList<String>();
        while ((strLine = br.readLine()) != null)   {
            if(strLine.contains("id=") || strLine.contains("class") || strLine.contains("};"))
                currentClassCredentilas.concat(strLine + seperator);
            else
                currentClassText.concat(strLine + seperator);

            //check if the class has completed
            if(strLine.contains("};")){
                //text is not a duplicate
                if(texts.add(currentClassText)){
                    credentials.add(currentClassCredentilas + seperator);
                }
                //set everything back to empty for the next round
                currentClassCredentilas = currentClassText = "";
            }
            System.out.println (strLine);
        }
        in.close();
    }catch (Exception e){
        System.err.println("Error: " + e.getMessage());
    }
}
于 2012-04-06T17:12:32.473 回答
0

我会生成每个短语的哈希值并将其存储到地图中。继续添加新短语,如果已经存在则忽略。哈希码和映射值始终是唯一的,因此您不会有重复项。

于 2012-04-06T17:34:36.290 回答
0

我最初的方法是:

  1. 创建一个数组来存储唯一位置
  2. 解析文件,如果位置在数组中,则跳过。否则,输出到文件并存储在数组中。
  3. 循环直到EOF

这将为您提供您想要的,但不是最佳解决方案。考虑存储第一次遇到的项目的方法,以及稍后如何检查它(扫描数组可能需要一段时间)。

于 2012-04-06T16:59:45.223 回答