I try to solve a problem since 2 days and my algorithm seems too complex. I need to produce 1 list of data that merge 2 ordered lists (named below "list A" and "list B") This merge must be based on a reference ordered list to identify where each element will be placed. If List A and List B contain same value for a rank, I need to keep only one of them
Ex :
Reference list : 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
List A : 2 | 4 | 6
List B : 1 | 4Expected result : 1 | 2 | 4 | 6
Code
private static List<String> mergeListsUsingRef(final List<String> listRef, final List<String> listA, final List<String> listB) { final List<String> res = new ArrayList<>(); final Iterator<String> listRefIterator = listRef.iterator(); final Iterator<String> listAIterator = listA.iterator(); final Iterator<String> listBIterator = listB.iterator(); String a = listAIterator.hasNext() ? listAIterator.next() : null; String b = listBIterator.hasNext() ? listBIterator.next() : null; while (listRefIterator.hasNext() && (a != null || b != null)) { final String ref = listRefIterator.next(); if (a != null && ref.equals(a)) { res.add(a); if (b != null && ref.equals(b)) { b = listBIterator.hasNext() ? listBIterator.next() : null; } a = listAIterator.hasNext() ? listAIterator.next() : null; } else if (b != null && ref.equals(b)) { res.add(b); b = listBIterator.hasNext() ? listBIterator.next() : null; } } return res; } Now I have to complexify the initial problem. The main difficulty comes from the possibility of having same values several times into each list. This means finding which positions are allowed for duplicate values.
Let's imagine some examples to illustrate that (with 4 that appear two times into the reference list)
Reference list : 1 | 2 | 3 | 4 | 5 | 6 | 4 | 7 | 8
List A : 2 | 3 | 5 | 4 | 7
List B : 4 | 7 | 8Expected result : 2 | 3 | 5 | 4 | 7 | 8
Explaination :
In List A : regarding to reference list, 4 is between 5 and 7 so 4 can be placed only at the second rank
In List B : regarding to reference list, I can't determine where 4 is (first or second rank)
So, List A determine the 4's position at the second rank
Reference list : 1 | 2 | 3 | 4 | 5 | 6 | 4 | 7 | 8
List A : 2 | 3 | 4 | 5 | 7
List B : 4 | 7 | 8Expected result : 2 | 3 | 4 | 5 | 7 | 8
Explaination :
In List A : regarding to reference list, 4 is between 3 and 5 so 4 can be placed only at the first rank
In List B : regarding to reference list, I can't determine where 4 is (first or second rank)
So, List A determine the 4's position at the first rank
Reference list : 1 | 2 | 3 | 4 | 5 | 6 | 4 | 7 | 8
List A : 2 | 3 | 4 | 5 | 7
List B : 6 | 4 | 7 | 8Expected result : 2 | 3 | 4 | 5 | 6 | 4 | 7 | 8
Explaination :
In List A : regarding to reference list, 4 is between 3 and 5 so 4 can be placed only at the first rank
In List B : regarding to reference list, 4 is between 6 and 7 so 4 can be placed only at the second rank
So, 4 must be placed at the first and second rank
Reference list : 1 | 2 | 3 | 4 | 5 | 6 | 4 | 7 | 8
List A : 2 | 3 | 4 | 5 | 7
List B : 6 | 7 | 8Expected result : 2 | 3 | 4 | 5 | 6 | 7 | 8
Explaination :
In List A : regarding to reference list, 4 is between 3 and 5 so 4 can be placed only at the first rank
In List B : 0 occurrence of 4 So, List A determine the 4's position at the first rank
My previous code does not work to deal with these difficult cases. Does anyone know how to help me to advance its implementation ? :)
EDIT : Main Java to validate the implementation :D
public static void main(String[] args) { System.out.println("EX 1 : "); List<String> refList = Arrays.asList("1", "2", "3", "4", "5", "6", "4", "7", "8"); List<String> listA = Arrays.asList("2", "3", "5", "4", "7"); List<String> listB = Arrays.asList("4", "7", "8"); List<String> mergeListsUsingRef = mergeListsUsingRef(refList, listA, listB); System.out.println("Expected : 2 | 3 | 5 | 4 | 7 | 8 "); System.out.print("Actual : "); for (String res : mergeListsUsingRef) { System.out.print(res + " | "); } System.out.println(""); System.out.println("----------------------------------"); System.out.println("EX 2 : "); refList = Arrays.asList("1", "2", "3", "4", "5", "6", "4", "7", "8"); listA = Arrays.asList("2", "3", "4", "5", "7"); listB = Arrays.asList("4", "7", "8"); mergeListsUsingRef = mergeListsUsingRef(refList, listA, listB); System.out.println("Expected : 2 | 3 | 4 | 5 | 7 | 8 "); System.out.print("Actual : "); for (String res : mergeListsUsingRef) { System.out.print(res + " | "); } System.out.println(""); System.out.println("----------------------------------"); System.out.println("EX 3 : "); refList = Arrays.asList("1", "2", "3", "4", "5", "6", "4", "7", "8"); listA = Arrays.asList("2", "3", "4", "5", "7"); listB = Arrays.asList("6", "4", "7", "8"); mergeListsUsingRef = mergeListsUsingRef(refList, listA, listB); System.out.println("Expected : 2 | 3 | 4 | 5 | 6 | 4 | 7 | 8 "); System.out.print("Actual : "); for (String res : mergeListsUsingRef) { System.out.print(res + " | "); } System.out.println(""); System.out.println("----------------------------------"); System.out.println("EX 4 : "); refList = Arrays.asList("1", "2", "3", "4", "5", "6", "4", "7", "8"); listA = Arrays.asList("2", "3", "4", "5", "7"); listB = Arrays.asList("6", "7", "8"); mergeListsUsingRef = mergeListsUsingRef(refList, listA, listB); System.out.println("Expected : 2 | 3 | 4 | 5 | 6 | 7 | 8 "); System.out.print("Actual : "); for (String res : mergeListsUsingRef) { System.out.print(res + " | "); } }