0

I am currently stuck while comparing two list of strings. Here are the inputs:

First list : three, two, ten, five.
Second list: three, ten, two, five.

The order is important in both list in such a way that: if one element index is not same in other list, then it should put an empty line.

I have attached a screen shot for better clarity.

enter image description here

Here is my code

public static void main(String[] args) {

 List<String> list1 = new ArrayList<String>();
 List<String> list2 = new ArrayList<String>();


    list1.add("three");
    list1.add("two");
    list1.add("ten");
    list1.add("five");

    list2.add("three");
    list2.add("ten");
    list2.add("two");
    list2.add("five");

    for(int iIndex = 0, jIndex = 0; iIndex < list1.size() && jIndex < list2.size(); iIndex ++, jIndex++) {
        if(!list1.get(iIndex).contentEquals(list2.get(jIndex))) {
            list1.add(jIndex, "");
        }
    }

Note: I have searched and checked each listed topics before posting this question. Thank you for your help

StuckAgain
  • 13
  • 6

3 Answers3

0

If I understood your question correctly you need something like this

int size = list2.size();
for(int i = 0; i < size ; i++) {
    if(!list1.get(i).contentEquals(list2.get(i))) {
      if(list2.size() <= list1.size()) {
        list2.add(i, "XXX");
        size +=1;
      } else {
        list1.add(i, "XXX");
      } 
    }
}

And the output will be:

three   three
two     XXX
ten     ten
XXX     two
five    five

I've added XXX to view them easier. You should also check the case when the lists are not equal in size since it might change the expected output of your program.

UPDATE:

You can try to do something like this.

int size = list1.size();
for(int i = 0; i < size; i++) {
  if(list1.size() == i){
    list1.add(i, "XXX");
    continue;
  }
  if(list2.size() == i){
    list2.add(i, "XXX");
    continue;
  }
  if(!list1.get(i).contentEquals(list2.get(i))) {
    int next_index1 = list2.subList(i, list2.size()).indexOf(list1.get(i));
    int next_index2 = list1.subList(i, list1.size()).indexOf(list2.get(i));

    if (next_index1 == -1){
      list2.add(i, "XXX");
    }
    else if(next_index2 == -1){
      list1.add(i, "XXX");
    } 
    else if(next_index1 < next_index2) {
      list1.add(i, "XXX");
    } else {
      list2.add(i, "XXX");
    } 
  }
  size = list1.size() < list2.size() ? list2.size() : list1.size();
}
for(int i = 0; i < size ; i++) {
  System.out.println(list1.get(i) + "   " + list2.get(i));
}

In brief, it will check when is the closest occurrence of a string in the other list. For example if your lists are:

three   three
two     ten
ten     two
five    five

After the first elements in each list, because they are the same, it will find the distance between the current position in the first list and the index of the first occurrence of that element in the second list and the other way around. If the distances are equal then it will add space in the second list. So the result will be

three   three
two     XXX
ten     ten
XXX     two
five    five

But if your list are

three   three
two     ten
five     two

the output will be

three   three
XXX     ten
two     two
five    XXX
Andrei Stoicescu
  • 659
  • 1
  • 6
  • 11
  • thanks you for the reply but it does not give me the same output. I corrected the list above in question . There is not case sensitive (upper & lower) issues. – StuckAgain May 26 '20 at 12:24
  • it doesn't give you the same output on this particular case or on other ones? can you also add other test cases or some corner cases? – Andrei Stoicescu May 26 '20 at 12:32
  • Here is other set of inputs: list1 : root, recognize, difficult, twenty, social, aside list2 : root, twenty, social, recognize, difficult, aside – StuckAgain May 26 '20 at 12:59
  • And the output should be this? list1 : root, recognize, difficult, twenty, social, x x aside list2 : root, x, x, twenty, social, recognize, difficult, aside – Andrei Stoicescu May 26 '20 at 13:15
  • Andrei Stoicescu yes, – StuckAgain May 26 '20 at 13:29
  • Can you tell me what is the output for this? list1: root, recognize, difficult list2: root,twenty, recognize – Andrei Stoicescu May 26 '20 at 14:24
  • Here is the result of your code : List 1 :root | List 2 :root List 1 :recognize | List 2 :XXX List 1 :XXX | List 2 :twenty List 1 :difficult | List 2 :XXX List 1 :XXX | List 2 :social List 1 :twenty | List 2 :XXX List 1 :XXX | List 2 :recognize List 1 :social | List 2 :XXX List 1 :XXX | List 2 :difficult List 1 :aside | List 2 :aside – StuckAgain May 26 '20 at 15:37
  • You can try the updated code to see if it suits as a point of start, but you should add in your question all the requirements for this diff algorithm (like what list should be modified first) and more examples in order for someone to help you with this. – Andrei Stoicescu May 26 '20 at 16:42
  • Thank you for help. It worked. Note: As I mentioned previously that I wanted the same behavior when you compare in NotePad++. I thought this could be enough to explain my need. – StuckAgain May 28 '20 at 07:50
  • There are cases where two consecutive elements are similar. Such as List1 = three, ten, ten, two and List2 = three, ten ,two – StuckAgain May 28 '20 at 10:17
  • Can I ask some questions on the same subject ? – StuckAgain Jun 12 '20 at 11:14
  • sure, you can ask away – Andrei Stoicescu Jun 12 '20 at 11:40
  • I have the following lists with inputs : list1 = { A="", B="1", B="2", C="4"} list1 = { A="", B="2", C="4"} I am not able to align B="2" from list1 to B="2" from list2 The output I am getting is : A="" | A="" B="1" | B="2" B="2" | C="" | C="" Actually, B="1" is missing from list2. – StuckAgain Jun 12 '20 at 12:32
  • in this if `if(!list1.get(i).contentEquals(list2.get(i))` you have to change that function in order to compare B with B and "1" with "2" – Andrei Stoicescu Jun 12 '20 at 13:45
  • I have a class X with property : name and value. So here name = B and value is 1 . The list is of type X – StuckAgain Jun 12 '20 at 14:00
  • it should work with `if(!list1.get(i).equals(list2.get(i))` – Andrei Stoicescu Jun 12 '20 at 14:04
  • I am stuck here. – StuckAgain Jun 12 '20 at 14:38
  • I added a screen shot for what I am trying to achieve – StuckAgain Jun 12 '20 at 14:44
  • yes, change form contentEquals to equals, in order to use the equals function from your X class. By default that equals function will compare if name == name and value == value. And when you add a new item to the list you will have to add a new X object. – Andrei Stoicescu Jun 12 '20 at 14:55
  • The thing is when I do that, it is doing the job but I need to align each by name and not by value. so If I have : A=1 | A=1 B=2 | B=2 B=2 | C=4 | C=5 Here C value is different by name. C name is same C value is different so no need to add empty line here. Did you get ? sorry I waste your time. You can tell me – StuckAgain Jun 12 '20 at 15:00
  • then you will have to add an extra condition if to compare by value only if there are more X objects with that value – Andrei Stoicescu Jun 12 '20 at 15:09
  • I will check it , Thanks – StuckAgain Jun 12 '20 at 17:13
0

The problem, as I see it is that there is no way to determine which list should be inserted with a blank line. So I would insert one in both. This presumes both lists are equal in length to start. When manipulating the size of a list within a loop I prefer to do it in reverse to ensure that any indices will remain in sync.

for (int i = list1.size()-1; i >= 0; i--) {
    if (list1.get(i) != list2.get(i)) {
        list1.add(i,"");
        list2.add(i+1,"");
    }
}

for (int i = 0; i < list1.size(); i++) {
    System.out.printf("%7s  %7s%n",list1.get(i),list2.get(i));
}

Prints

  three    three
             ten
    two         
             two
    ten         
   five     five

or it could have been like this.

 three    three
    two         
             ten
    ten         
             two
   five     five
WJS
  • 36,363
  • 4
  • 24
  • 39
  • Thank you for your help. Here I see that both "two" are not inline – StuckAgain May 26 '20 at 13:00
  • That's because they were not in line in the original lists. You don't provide enough criteria in your question to decide which list to modify. Why should the `twos` be lined up instead of the `tens`? See my update answer as an example. – WJS May 26 '20 at 13:16
0

As per the screenshot I can see that if the elements are not equal, then the elements have to be compared with the next element in the list. However, there is still one assumption that has to be made. That is the assumption of which element to choose if they are the same.

My assumption is that if the lists are equal in length, then the value of the first list will be chosen. Without this assumption, I don't think there is a solution to this problem.

//Assuming list1.size() == list2.size() from the start
int listSize = list1.size();

for(int i=0; i<listSize; i++){
    // If both are equal
    if(list1.get(i).equals(list2.get(i))){
        continue;
    }
    // If lists have the same size, pick value of list1
    if(list1.size() == list2.size()){
        System.out.println("Putting empty in list2");
        list2.add(i,"");
        listSize+=1;
    }
    else{
        System.out.println("Putting empty in list1");
        list1.add(i,"");
    }
}

Output:

Putting empty in list2
Putting empty in list1

three three
two 
ten   ten
      two
five  five
Diaco
  • 241
  • 1
  • 3
  • 15