Bläddra i källkod

Replace custom bubblesort with standard API permutation generation.

Timur Sağlam 5 år sedan
förälder
incheckning
1c14ce1d25

+ 19 - 35
jplag/src/main/java/de/jplag/JPlagComparison.java

@@ -2,13 +2,15 @@ package de.jplag;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.stream.IntStream;
 
 /**
  * This method represents the whole result of a comparison between two submissions.
  */
-public class JPlagComparison implements Comparator<JPlagComparison> {
+public class JPlagComparison implements Comparator<JPlagComparison> { // FIXME TS: contains a lot of code duplication
 
     private static final int ROUNDING_FACTOR = 10;
 
@@ -248,42 +250,24 @@ public class JPlagComparison implements Comparator<JPlagComparison> {
         this.secondBaseCodeMatches = secondBaseCodeMatches;
     }
 
-    /*
-     * s==0 uses the start indexes of 1st submission as key for the sorting algorithm. Otherwise the start indexes of 2nd
-     * submission are used.
+    /**
+     * Creates a permutation for the matches based on the indices of the matched token groups.
+     * @param useFirst determines whether the start of the first or second submission is compared.
+     * @return the permutation indices.
      */
-    public final int[] sort_permutation(int s) {   // bubblesort!!!
-        int size = matches.size();
-        int[] perm = new int[size];
-        int i, j, tmp;
-
-        // initialize permutation array
-        for (i = 0; i < size; i++) {
-            perm[i] = i;
-        }
+    public final List<Integer> sort_permutation(boolean useFirst) {
+        List<Integer> indices = new ArrayList<>(matches.size());
+        IntStream.range(0, matches.size()).forEach(index -> indices.add(index));
+        Comparator<Integer> comparator = (Integer i, Integer j) -> {
+            return Integer.compare(selectStartof(i, useFirst), selectStartof(j, useFirst));
+        };
+        Collections.sort(indices, comparator);
+        return indices;
+    }
 
-        if (s == 0) {     // First Submission
-            for (i = 1; i < size; i++) {
-                for (j = 0; j < (size - i); j++) {
-                    if (matches.get(perm[j]).getStartOfFirst() > matches.get(perm[j + 1]).getStartOfFirst()) {
-                        tmp = perm[j];
-                        perm[j] = perm[j + 1];
-                        perm[j + 1] = tmp;
-                    }
-                }
-            }
-        } else {        // Second submission
-            for (i = 1; i < size; i++) {
-                for (j = 0; j < (size - i); j++) {
-                    if (matches.get(perm[j]).getStartOfSecond() > matches.get(perm[j + 1]).getStartOfSecond()) {
-                        tmp = perm[j];
-                        perm[j] = perm[j + 1];
-                        perm[j + 1] = tmp;
-                    }
-                }
-            }
-        }
-        return perm;
+    private int selectStartof(Integer index, boolean useFirst) {
+        Match match = matches.get(index);
+        return useFirst ? match.getStartOfFirst() : match.getStartOfSecond();
     }
 
     @Override

+ 7 - 6
jplag/src/main/java/de/jplag/reporting/Report.java

@@ -475,13 +475,14 @@ public class Report { // Mostly legacy code with some minor improvements.
      * getIndex() method of the token. It is meant to be used with the Character front end
      */
     private void writeIndexedSubmission(HTMLFile f, int i, JPlagComparison comparison, int j) throws ExitException {
-        Submission sub = (j == 0 ? comparison.getFirstSubmission() : comparison.getSecondSubmission());
+        boolean useFirst = j == 0;
+        Submission sub = (useFirst ? comparison.getFirstSubmission() : comparison.getSecondSubmission());
         String[] files = comparison.files(j);
         char[][] text = sub.readFilesChar(files);
-        TokenList tokens = (j == 0 ? comparison.getFirstSubmission() : comparison.getSecondSubmission()).getTokenList();
+        TokenList tokens = (useFirst ? comparison.getFirstSubmission() : comparison.getSecondSubmission()).getTokenList();
 
         // get index array with matches sorted in ascending order.
-        int[] perm = comparison.sort_permutation(j);
+        List<Integer> perm = comparison.sort_permutation(useFirst);
 
         int index = 0; // match index
         Match onematch = null;
@@ -504,7 +505,7 @@ public class Report { // Mostly legacy code with some minor improvements.
             for (int charNr = 0; charNr < buffer.length; charNr++) {
                 if (onematch == null) {
                     if (index < comparison.getMatches().size()) {
-                        onematch = comparison.getMatches().get(perm[index]);
+                        onematch = comparison.getMatches().get(perm.get(index));
                         start = tokens.getToken(j == 0 ? onematch.getStartOfFirst() : onematch.getStartOfSecond());
                         end = tokens.getToken((j == 0 ? onematch.getStartOfFirst() : onematch.getStartOfSecond()) + onematch.getLength() - 1);
                         index++;
@@ -514,8 +515,8 @@ public class Report { // Mostly legacy code with some minor improvements.
                 }
                 // begin markup
                 if (start != null && start.getIndex() == charNr) {
-                    f.print("<A NAME=\"" + perm[index - 1] + "\"></A>");
-                    f.print("<FONT color=\"" + Color.getHexadecimalValue(perm[index - 1]) + "\"><B>");
+                    f.print("<A NAME=\"" + perm.get(index - 1) + "\"></A>");
+                    f.print("<FONT color=\"" + Color.getHexadecimalValue(perm.get(index - 1)) + "\"><B>");
                     // "<A HREF=\"javascript:ZweiFrames('match"+i+"-"+(1-j)+
                     // ".html#"+index+"',"+(3-j)+",'match"+i+"-top.html#"+index+
                     // "',1)\">"+"<IMG SRC=\""+pics[j]+