сравнить пары, хранящиеся в хэш-таблице Java - PullRequest
0 голосов
/ 03 октября 2010

сначала у меня есть двумерный массив, хранящий много чисел, а затем я использовал массив таблиц hushtable для хранения пар, образованных числами каждой строки двумерного массива.например, в первой строке массива 2d числа равны 1 2 3 4 5, тогда пары должны быть 1,2 1,3 1,4, 1,5 и т. д. код для генерации пар и сохранения в хеш-таблице:

     Hashtable [] table=new Hashtable [lineCounter];
    int [] pairCounter=new int[lineCounter];
    for(int i=0;i<lineCounter;i++)
  {
     table[i]=new Hashtable();
     for (int j=0;j<lineitem2[i]-1;j++)
     {
         for(int t=j+1;t<lineitem2[i];t++)
         {
             int firstnum=freItem[i][j];
             int secnum=freItem[i][t];
             String value=firstnum+":"+secnum;
             //System.out.println(firstnum+"``"+secnum);
             table[i].put(pairCounter[i],value);
             pairCounter[i]++;
             //System.out.println(i+":::"+table[i].get(firstnum));
         }
     }
 }

после сохранения каждой пары каждой строки, я хочу сравнить каждую пару в каждой строке с другими, чтобы узнать, сколько раз эта пара появляется, код:

Hashtable resulttable=new Hashtable();
   int [] pairresult=new int [lineCounter];

   for(int i=0;i<lineCounter;i++)
   {
           //Set set1 = table[i].entrySet();
        //Iterator it1 = set1.iterator();
        Enumeration keys = table[i].keys();


       //for(int j=i+1;j<lineCounter;j++)
       //{


         while (keys.hasMoreElements())
             {
                int pairs=0;
               //Map.Entry entry1 = (Map.Entry) it1.next();
               int key = (Integer)keys.nextElement();
               String curvalue = (String)table[i].get( key );

               for(int j=i+1;j<lineCounter;j++)
               {

                 //Set set2 = table[j].entrySet();
                 //Iterator it2 = set2.iterator();
                 Enumeration keys2 = table[j].keys();

                 while (keys2.hasMoreElements())
                 {

                   //Map.Entry entry2 = (Map.Entry) it2.next();
                   //System.out.println(entry2.getKey() + " and " + entry2.getValue());
                   int key2 = (Integer)keys2.nextElement();
                   String curvalue2 = (String)table[j].get( key2 );
                   if(curvalue.equals(curvalue2))
                   {
                       pairs++;
                       table[j].remove(key2);
                   }
                 }

                 }
                if(pairs>=0.02*lineCounter)
                {
                  resulttable.put(curvalue,pairs);
                }







            }


   //    }


   }

но после запуска его с входным файлом я получил ошибку:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.lang.StringBuilder.toString(StringBuilder.java:430)

Что-то не так с моим методом сравнения пар?и почему я получил эту ошибку, пожалуйста, помогите спасибо.

Ответы [ 2 ]

2 голосов
/ 04 октября 2010

Хорошо, предположим, у вас есть класс Pair следующим образом:

public class Pair {

    private final int value1;
    private final int value2;

    public Pair(int value1, int value2) {
        this.value1 = value1;
        this.value2 = value2;
    }

    public int value1() {
        return value1;
    }

    public int value2() {
        return value2;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + value1;
        result = prime * result + value2;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Pair other = (Pair) obj;
        if (value1 != other.value1)
            return false;
        if (value2 != other.value2)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "(" + value1 + ", " + value2 + ")";
    }

}

Обратите внимание, что важно правильно реализовать методы equals(Object) и hashCode(), если вы ожидаете, что экземпляры класса Pair будут работать правильно при использовании в основанном на хэше структуры данных (например: Hashtable, HashMap, HashSet, HashMultimap, HashMultiset ** 1026).

Теперь этот код будет читаться в файле (требуется библиотеки Guava ) :

    File file = ...;

    final Map<Pair, Collection<Integer>> lineNumbersByPair = new HashMap<Pair, Collection<Integer>>();

    /*
     * Step 1: Read in the lines, one by one.
     */
    Reader reader = new FileReader(file);
    try {
        BufferedReader bufferedReader = new BufferedReader(reader);
        try {
            String line;

            int lineNumber = 0;
            while ((line = bufferedReader.readLine()) != null) {
                lineNumber++;

                String[] tokens = line.split("\\s+");
                int[] values = new int[tokens.length];

                for (int i = 0; i < tokens.length; i++) {
                    values[i] = Integer.parseInt(tokens[i]);
                }

                for (int i = 0; i < values.length; i++) {
                    for (int j = i + 1; j < values.length; j++) {
                        Pair pair = new Pair(values[i], values[j]);

                        Collection<Integer> lineNumbers;
                        if (lineNumbersByPair.containsKey(pair)) {
                            lineNumbers = lineNumbersByPair.get(pair);
                        } else {
                            lineNumbers = new HashSet<Integer>();
                            lineNumbersByPair.put(pair, lineNumbers);
                        }
                        lineNumbers.add(lineNumber);
                    }
                }
            }
        } finally {
            bufferedReader.close();
        }
    } finally {
        reader.close();
    }

    /*
     * Step 2: Identify the unique pairs. Sort them according to how many lines they appear on (most number of lines to least number of lines).
     */
    List<Pair> pairs = new ArrayList<Pair>(lineNumbersByPair.keySet());
    Collections.sort(
            pairs,
            new Comparator<Pair>() {
                @Override
                public int compare(Pair pair1, Pair pair2) {
                    Integer count1 = lineNumbersByPair.get(pair1).size();
                    Integer count2 = lineNumbersByPair.get(pair2).size();
                    return count1.compareTo(count2);
                }
            }
        );
    Collections.reverse(pairs);

    /*
     * Step 3: Print the pairs and their line numbers.
     */
    for (Pair pair : pairs) {
        Collection<Integer> lineNumbers = lineNumbersByPair.get(pair);
        if (lineNumbers.size() > 1) {
            System.out.println(pair + " appears on the following lines: " + lineNumbers);
        }
    }

В тесте код читается в файле с 20000 строк, каждая строка содержит 10 чисел в диапазоне от 0 до 1000.

0 голосов
/ 03 октября 2010

Если ваш код работает с меньшим набором данных, возможно, просто недостаточно 64Mb по умолчанию, который использует JVM, работает ли он, когда вы передаете -Xmx512m в качестве аргумента командной строке Java?

...