List of usage examples for java.util LinkedList listIterator
ListIterator<E> listIterator();
From source file:org.trnltk.experiment.morphology.ambiguity.DataDiffUtil.java
/** * Reduce the number of edits by eliminating semantically trivial equalities. * * @param diffs LinkedList of Diff objects. *//* w ww. j a v a 2s .co m*/ public void diff_cleanupSemantic(LinkedList<Diff<T>> diffs) { if (diffs.isEmpty()) { return; } boolean changes = false; Stack<Diff<T>> equalities = new Stack<Diff<T>>(); // Stack of qualities. List<T> lastequality = null; // Always equal to equalities.lastElement().text ListIterator<Diff<T>> pointer = diffs.listIterator(); // Number of characters that changed prior to the equality. int length_insertions1 = 0; int length_deletions1 = 0; // Number of characters that changed after the equality. int length_insertions2 = 0; int length_deletions2 = 0; Diff<T> thisDiff = pointer.next(); while (thisDiff != null) { if (thisDiff.operation == Operation.EQUAL) { // Equality found. equalities.push(thisDiff); length_insertions1 = length_insertions2; length_deletions1 = length_deletions2; length_insertions2 = 0; length_deletions2 = 0; lastequality = thisDiff.text; } else { // An insertion or deletion. if (thisDiff.operation == Operation.INSERT) { length_insertions2 += thisDiff.text.size(); } else { length_deletions2 += thisDiff.text.size(); } // Eliminate an equality that is smaller or equal to the edits on both // sides of it. if (lastequality != null && (lastequality.size() <= Math.max(length_insertions1, length_deletions1)) && (lastequality.size() <= Math.max(length_insertions2, length_deletions2))) { //System.out.println("Splitting: '" + lastequality + "'"); // Walk back to offending equality. while (thisDiff != equalities.lastElement()) { thisDiff = pointer.previous(); } pointer.next(); // Replace equality with a delete. pointer.set(new Diff(Operation.DELETE, lastequality)); // Insert a corresponding an insert. pointer.add(new Diff(Operation.INSERT, lastequality)); equalities.pop(); // Throw away the equality we just deleted. if (!equalities.empty()) { // Throw away the previous equality (it needs to be reevaluated). equalities.pop(); } if (equalities.empty()) { // There are no previous equalities, walk back to the start. while (pointer.hasPrevious()) { pointer.previous(); } } else { // There is a safe equality we can fall back to. thisDiff = equalities.lastElement(); while (thisDiff != pointer.previous()) { // Intentionally empty loop. } } length_insertions1 = 0; // Reset the counters. length_insertions2 = 0; length_deletions1 = 0; length_deletions2 = 0; lastequality = null; changes = true; } } thisDiff = pointer.hasNext() ? pointer.next() : null; } // Normalize the diff. if (changes) { diff_cleanupMerge(diffs); } diff_cleanupSemanticLossless(diffs); // Find any overlaps between deletions and insertions. // e.g: <del>abcxxx</del><ins>xxxdef</ins> // -> <del>abc</del>xxx<ins>def</ins> // e.g: <del>xxxabc</del><ins>defxxx</ins> // -> <ins>def</ins>xxx<del>abc</del> // Only extract an overlap if it is as big as the edit ahead or behind it. pointer = diffs.listIterator(); Diff<T> prevDiff = null; thisDiff = null; if (pointer.hasNext()) { prevDiff = pointer.next(); if (pointer.hasNext()) { thisDiff = pointer.next(); } } while (thisDiff != null) { if (prevDiff.operation == Operation.DELETE && thisDiff.operation == Operation.INSERT) { List<T> deletion = prevDiff.text; List<T> insertion = thisDiff.text; int overlap_length1 = this.diff_commonOverlap(deletion, insertion); int overlap_length2 = this.diff_commonOverlap(insertion, deletion); if (overlap_length1 >= overlap_length2) { if (overlap_length1 >= deletion.size() / 2.0 || overlap_length1 >= insertion.size() / 2.0) { // Overlap found. Insert an equality and trim the surrounding edits. pointer.previous(); pointer.add(new Diff<T>(Operation.EQUAL, insertion.subList(0, overlap_length1))); prevDiff.text = deletion.subList(0, deletion.size() - overlap_length1); thisDiff.text = insertion.subList(overlap_length1, insertion.size()); // pointer.add inserts the element before the cursor, so there is // no need to step past the new element. } } else { if (overlap_length2 >= deletion.size() / 2.0 || overlap_length2 >= insertion.size() / 2.0) { // Reverse overlap found. // Insert an equality and swap and trim the surrounding edits. pointer.previous(); pointer.add(new Diff<T>(Operation.EQUAL, deletion.subList(0, overlap_length2))); prevDiff.operation = Operation.INSERT; prevDiff.text = insertion.subList(0, insertion.size() - overlap_length2); thisDiff.operation = Operation.DELETE; thisDiff.text = deletion.subList(overlap_length2, deletion.size()); // pointer.add inserts the element before the cursor, so there is // no need to step past the new element. } } thisDiff = pointer.hasNext() ? pointer.next() : null; } prevDiff = thisDiff; thisDiff = pointer.hasNext() ? pointer.next() : null; } }
From source file:org.trnltk.experiment.morphology.ambiguity.DataDiffUtil.java
/** * Look for single edits surrounded on both sides by equalities * which can be shifted sideways to align the edit to a word boundary. * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came. * * @param diffs LinkedList of Diff objects. */// ww w .j a v a2 s . c o m public void diff_cleanupSemanticLossless(LinkedList<Diff<T>> diffs) { List<T> equality1, edit, equality2; List<T> commonString; int commonOffset; int score, bestScore; List<T> bestEquality1, bestEdit, bestEquality2; // Create a new iterator at the start. ListIterator<Diff<T>> pointer = diffs.listIterator(); Diff<T> prevDiff = pointer.hasNext() ? pointer.next() : null; Diff<T> thisDiff = pointer.hasNext() ? pointer.next() : null; Diff<T> nextDiff = pointer.hasNext() ? pointer.next() : null; // Intentionally ignore the first and last element (don't need checking). while (nextDiff != null) { if (prevDiff.operation == Operation.EQUAL && nextDiff.operation == Operation.EQUAL) { // This is a single edit surrounded by equalities. equality1 = prevDiff.text; edit = thisDiff.text; equality2 = nextDiff.text; // First, shift the edit as far left as possible. commonOffset = diff_commonSuffix(equality1, edit); if (commonOffset != 0) { commonString = edit.subList(edit.size() - commonOffset, edit.size()); equality1 = equality1.subList(0, equality1.size() - commonOffset); edit = ListUtils.union(commonString, edit.subList(0, edit.size() - commonOffset)); equality2 = ListUtils.union(commonString, equality2); } // Second, step character by character right, looking for the best fit. bestEquality1 = equality1; bestEdit = edit; bestEquality2 = equality2; bestScore = diff_cleanupSemanticScore(equality1, edit) + diff_cleanupSemanticScore(edit, equality2); while (edit.size() != 0 && equality2.size() != 0 && edit.get(0).equals(equality2.get(0))) { equality1 = ListUtils.union(equality1, Arrays.asList(edit.get(0))); edit = ListUtils.union(edit.subList(1, edit.size()), Arrays.asList(equality2.get(0))); equality2 = equality2.subList(1, equality2.size()); score = diff_cleanupSemanticScore(equality1, edit) + diff_cleanupSemanticScore(edit, equality2); // The >= encourages trailing rather than leading whitespace on edits. if (score >= bestScore) { bestScore = score; bestEquality1 = equality1; bestEdit = edit; bestEquality2 = equality2; } } if (!prevDiff.text.equals(bestEquality1)) { // We have an improvement, save it back to the diff. if (bestEquality1.size() != 0) { prevDiff.text = bestEquality1; } else { pointer.previous(); // Walk past nextDiff. pointer.previous(); // Walk past thisDiff. pointer.previous(); // Walk past prevDiff. pointer.remove(); // Delete prevDiff. pointer.next(); // Walk past thisDiff. pointer.next(); // Walk past nextDiff. } thisDiff.text = bestEdit; if (bestEquality2.size() != 0) { nextDiff.text = bestEquality2; } else { pointer.remove(); // Delete nextDiff. nextDiff = thisDiff; thisDiff = prevDiff; } } } prevDiff = thisDiff; thisDiff = nextDiff; nextDiff = pointer.hasNext() ? pointer.next() : null; } }
From source file:org.trnltk.experiment.morphology.ambiguity.DataDiffUtil.java
/** * Reduce the number of edits by eliminating operationally trivial equalities. * * @param diffs LinkedList of Diff objects. */// www . j a v a 2 s . c o m public void diff_cleanupEfficiency(LinkedList<Diff<T>> diffs) { if (diffs.isEmpty()) { return; } boolean changes = false; Stack<Diff> equalities = new Stack<Diff>(); // Stack of equalities. List<T> lastequality = null; // Always equal to equalities.lastElement().text ListIterator<Diff<T>> pointer = diffs.listIterator(); // Is there an insertion operation before the last equality. boolean pre_ins = false; // Is there a deletion operation before the last equality. boolean pre_del = false; // Is there an insertion operation after the last equality. boolean post_ins = false; // Is there a deletion operation after the last equality. boolean post_del = false; Diff<T> thisDiff = pointer.next(); Diff<T> safeDiff = thisDiff; // The last Diff that is known to be unsplitable. while (thisDiff != null) { if (thisDiff.operation == Operation.EQUAL) { // Equality found. if (thisDiff.text.size() < Diff_EditCost && (post_ins || post_del)) { // Candidate found. equalities.push(thisDiff); pre_ins = post_ins; pre_del = post_del; lastequality = thisDiff.text; } else { // Not a candidate, and can never become one. equalities.clear(); lastequality = null; safeDiff = thisDiff; } post_ins = post_del = false; } else { // An insertion or deletion. if (thisDiff.operation == Operation.DELETE) { post_del = true; } else { post_ins = true; } /* * Five types to be split: * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del> * <ins>A</ins>X<ins>C</ins><del>D</del> * <ins>A</ins><del>B</del>X<ins>C</ins> * <ins>A</del>X<ins>C</ins><del>D</del> * <ins>A</ins><del>B</del>X<del>C</del> */ if (lastequality != null && ((pre_ins && pre_del && post_ins && post_del) || ((lastequality.size() < Diff_EditCost / 2) && ((pre_ins ? 1 : 0) + (pre_del ? 1 : 0) + (post_ins ? 1 : 0) + (post_del ? 1 : 0)) == 3))) { //System.out.println("Splitting: '" + lastequality + "'"); // Walk back to offending equality. while (thisDiff != equalities.lastElement()) { thisDiff = pointer.previous(); } pointer.next(); // Replace equality with a delete. pointer.set(new Diff(Operation.DELETE, lastequality)); // Insert a corresponding an insert. pointer.add(thisDiff = new Diff(Operation.INSERT, lastequality)); equalities.pop(); // Throw away the equality we just deleted. lastequality = null; if (pre_ins && pre_del) { // No changes made which could affect previous entry, keep going. post_ins = post_del = true; equalities.clear(); safeDiff = thisDiff; } else { if (!equalities.empty()) { // Throw away the previous equality (it needs to be reevaluated). equalities.pop(); } if (equalities.empty()) { // There are no previous questionable equalities, // walk back to the last known safe diff. thisDiff = safeDiff; } else { // There is an equality we can fall back to. thisDiff = equalities.lastElement(); } while (thisDiff != pointer.previous()) { // Intentionally empty loop. } post_ins = post_del = false; } changes = true; } } thisDiff = pointer.hasNext() ? pointer.next() : null; } if (changes) { diff_cleanupMerge(diffs); } }
From source file:org.trnltk.experiment.morphology.ambiguity.DataDiffUtil.java
/** * Reorder and merge like edit sections. Merge equalities. * Any edit section can move as long as it doesn't cross an equality. * * @param diffs LinkedList of Diff objects. *//*from www .ja va 2s. c o m*/ public void diff_cleanupMerge(LinkedList<Diff<T>> diffs) { diffs.add(new Diff<T>(Operation.EQUAL, new ArrayList<T>())); // Add a dummy entry at the end. ListIterator<Diff<T>> pointer = diffs.listIterator(); int count_delete = 0; int count_insert = 0; List<T> text_delete = new ArrayList<T>(); List<T> text_insert = new ArrayList<T>(); Diff thisDiff = pointer.next(); Diff prevEqual = null; int commonlength; while (thisDiff != null) { switch (thisDiff.operation) { case INSERT: count_insert++; text_insert = ListUtils.union(text_insert, thisDiff.text); prevEqual = null; break; case DELETE: count_delete++; text_delete = ListUtils.union(text_delete, thisDiff.text); prevEqual = null; break; case EQUAL: if (count_delete + count_insert > 1) { boolean both_types = count_delete != 0 && count_insert != 0; // Delete the offending records. pointer.previous(); // Reverse direction. while (count_delete-- > 0) { pointer.previous(); pointer.remove(); } while (count_insert-- > 0) { pointer.previous(); pointer.remove(); } if (both_types) { // Factor out any common prefixies. commonlength = diff_commonPrefix(text_insert, text_delete); if (commonlength != 0) { if (pointer.hasPrevious()) { thisDiff = pointer.previous(); assert thisDiff.operation == Operation.EQUAL : "Previous diff should have been an equality."; thisDiff.text = ListUtils.union(thisDiff.text, text_insert.subList(0, commonlength)); pointer.next(); } else { pointer.add(new Diff(Operation.EQUAL, text_insert.subList(0, commonlength))); } text_insert = text_insert.subList(commonlength, text_insert.size()); text_delete = text_delete.subList(commonlength, text_delete.size()); } // Factor out any common suffixies. commonlength = diff_commonSuffix(text_insert, text_delete); if (commonlength != 0) { thisDiff = pointer.next(); thisDiff.text = ListUtils.union( text_insert.subList(text_insert.size() - commonlength, text_insert.size()), thisDiff.text); text_insert = text_insert.subList(0, text_insert.size() - commonlength); text_delete = text_delete.subList(0, text_delete.size() - commonlength); pointer.previous(); } } // Insert the merged records. if (text_delete.size() != 0) { pointer.add(new Diff(Operation.DELETE, text_delete)); } if (text_insert.size() != 0) { pointer.add(new Diff(Operation.INSERT, text_insert)); } // Step forward to the equality. thisDiff = pointer.hasNext() ? pointer.next() : null; } else if (prevEqual != null) { // Merge this equality with the previous one. prevEqual.text = ListUtils.union(prevEqual.text, thisDiff.text); pointer.remove(); thisDiff = pointer.previous(); pointer.next(); // Forward direction } count_insert = 0; count_delete = 0; text_delete = new ArrayList<T>(); text_insert = new ArrayList<T>(); prevEqual = thisDiff; break; } thisDiff = pointer.hasNext() ? pointer.next() : null; } if (diffs.getLast().text.size() == 0) { diffs.removeLast(); // Remove the dummy entry at the end. } /* * Second pass: look for single edits surrounded on both sides by equalities * which can be shifted sideways to eliminate an equality. * e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC */ boolean changes = false; // Create a new iterator at the start. // (As opposed to walking the current one back.) pointer = diffs.listIterator(); Diff<T> prevDiff = pointer.hasNext() ? pointer.next() : null; thisDiff = pointer.hasNext() ? pointer.next() : null; Diff nextDiff = pointer.hasNext() ? pointer.next() : null; // Intentionally ignore the first and last element (don't need checking). while (nextDiff != null) { if (prevDiff.operation == Operation.EQUAL && nextDiff.operation == Operation.EQUAL) { // This is a single edit surrounded by equalities. if (endsWith(thisDiff.text, prevDiff.text)) { // Shift the edit over the previous equality. thisDiff.text = ListUtils.union(prevDiff.text, thisDiff.text.subList(0, thisDiff.text.size() - prevDiff.text.size())); nextDiff.text = ListUtils.union(prevDiff.text, nextDiff.text); pointer.previous(); // Walk past nextDiff. pointer.previous(); // Walk past thisDiff. pointer.previous(); // Walk past prevDiff. pointer.remove(); // Delete prevDiff. pointer.next(); // Walk past thisDiff. thisDiff = pointer.next(); // Walk past nextDiff. nextDiff = pointer.hasNext() ? pointer.next() : null; changes = true; } else if (startsWith(thisDiff.text, nextDiff.text)) { // Shift the edit over the next equality. prevDiff.text = ListUtils.union(prevDiff.text, nextDiff.text); thisDiff.text = ListUtils.union( thisDiff.text.subList(nextDiff.text.size(), thisDiff.text.size()), nextDiff.text); pointer.remove(); // Delete nextDiff. nextDiff = pointer.hasNext() ? pointer.next() : null; changes = true; } } prevDiff = thisDiff; thisDiff = nextDiff; nextDiff = pointer.hasNext() ? pointer.next() : null; } // If shifts were made, the diff needs reordering and another shift sweep. if (changes) { diff_cleanupMerge(diffs); } }
From source file:ru.runa.wfe.extension.orgfunction.DemoSubordinateRecursive.java
/** * @param list/* w w w .ja v a 2 s . co m*/ * @param subordinatesList * @param demoChiefFunction * @throws OrgFunctionException */ private void findIndirectSubordinates(LinkedList<Actor> list, LinkedList<Actor> subordinatesList, DemoChiefFunction demoChiefFunction) throws OrgFunctionException { int flag = -1; while (flag != 0) { LinkedList<Actor> newGeneratedSubordinates = new LinkedList<Actor>(); for (ListIterator<Actor> iter = subordinatesList.listIterator(); iter.hasNext();) { findDirectSubordinates(list, newGeneratedSubordinates, iter.next(), demoChiefFunction); } flag = addNotContainedElements(subordinatesList, newGeneratedSubordinates); } }
From source file:ru.runa.wfe.extension.orgfunction.DemoSubordinateRecursive.java
/** * @param subordinatesList/* w ww . j a v a2 s .c o m*/ * @param flag * @param newSubordinates * @return */ private int addNotContainedElements(LinkedList<Actor> subordinatesList, LinkedList<Actor> newGeneratedSubordinates) { int flag = 0; for (ListIterator<Actor> iter = newGeneratedSubordinates.listIterator(); iter.hasNext();) { Actor acurr = iter.next(); if (!subordinatesList.contains(acurr)) { subordinatesList.add(acurr); flag = -1; } } return flag; }