0

I am having trouble comparing two linked lists, I have 2 lists for arguments sake list1 contains {1,2,3,4,5} and list2 contains {1,3,4,5,6}

I am not using linkedlistnodes for a start which is why I am asking the question here, I did try switch to notes but a lot of my other work would then have to be re-written to make it work which I don't really want to do.

Anyway here is my code thus far, I am trying to use 2 loops to cycle and compare each value. The problem is that it doesn't work in the way I intended as I didn't think that it will compare the first value of list1 against all values in list2 before moving on. It stumped me how to get this working or if I am even going about it in the right way.

bool c = false;
foreach (int s in list1) {
    foreach (int t in list2)
        if (s == t) {
            c = true;
            //The console write line in this part of the code is for testing
            Console.WriteLine("Both Lists Match  {0}, {1}", s, t);
            break;
        } else {
            c = false;
            //The console write line in this part of the code is for testing
            Console.WriteLine("Not a Match {0}, {1}", s, t);
        }
}

if (c == true) {
   Console.WriteLine("Both Lists Match");
} else {
    Console.WriteLine("Not a Match");
}
Grundy
  • 13,356
  • 3
  • 35
  • 55
Matt Farrell
  • 191
  • 1
  • 1
  • 13
  • Do you know they are sorted when you begin? Do you need to just determine whether they are equal? If not equal, do you want all the differences (found in a not b, found in b not a)? – MrWonderful Mar 19 '15 at 18:24
  • i do as its the way i generate it but if there is a way to compare it regardless i would be much more in favour of that. – Matt Farrell Mar 19 '15 at 18:25
  • 8
    Can you use LINQ? `list1.SequenceEqual(list2)` should give you the right answer... – Jon Skeet Mar 19 '15 at 18:26
  • What are you trying to determine about these lists? Whether any of the elements in either are equal to its corresponding index's value in the other list? – a p Mar 19 '15 at 18:26
  • You should look at http://stackoverflow.com/questions/12795882/quickest-way-to-compare-two-list to see if it is helpful for your situation. – MrWonderful Mar 19 '15 at 18:28
  • ill have a look to see if im allowed to used linq but i am simply trying to test if all elements of list1 are in list2 – Matt Farrell Mar 19 '15 at 18:29
  • Do you care about duplicates and order? – Magnus Mar 19 '15 at 18:47
  • there wont be any duplicates – Matt Farrell Mar 19 '15 at 19:01
  • i guess the problem is you don't exit the for loops after setting c to false (in case there is no match), start with default true, if one fails, set c to false, and exit both for loops? also, maybe check before if the length of the list matches, if not it will never be equal... – Icepickle Mar 19 '15 at 19:33

1 Answers1

4

You indicated that "i am simply trying to test if all elements of list1 are in list2".

This can be solved using two nested loops where you compare the elements of the list, as you are trying with the code you have posted with your question, but there are a few problems with the posted code.

In terms of approach, the easiest way of thinking about this problem might be:

  1. Assume list2 contains all elements from list1
  2. Compare each element s in list1 with the elements t in list2
  3. If s != t, for each t in list2, you know the assumption was not true and you can stop searching.

You could solve this (making minimal changes to your existing code), in the following manner:

    bool c = true; // assume each 's' is in 'list2'
    foreach (int s in list1)
    {
        bool contains_s = false; // 's' in 'list2' ?
        foreach (int t in list2)
        {
            if (s == t)
            {
                // found 's' in 'list2'.
                contains_s = true;
                //The console write line in this part of the code is for testing
                Console.WriteLine("Both Lists Match  {0}, {1}", s, t);
                break; // breaks out of the inner loop.
            }
        }
        if (!contains_s) // if 's' not found we are done.
        {
            c = false;
            break; // breaks out of the outer loop
        }
    }

    if (c == true)
    {
        Console.WriteLine("Both Lists Match");
    }
    else
    {
        Console.WriteLine("Not a Match");
    }

If you are using LINQ, you can replace this with a much simpler statement, that basically does the same thing as the above loop.

var doesNotContainAllElements = list1.Any(s => !list2.Contains(s));

or

var containsAllElements = list1.All(s => list2.Contains(s));
Alex
  • 13,024
  • 33
  • 62
  • 1
    BTW: why would someone use `O(n*n)` algorithm when it can be done in a linear time. – EZI Mar 19 '15 at 20:45
  • @EZ1, this does work for {1, 2} and {1, 2, 3}. Please remove your misleading comment about this not working. Also, regarding your second comment: given OPs question and posted code, it seemed reasonable to me to provide an answer that was in line with what he was already trying to do, as this would be easier to understand. You may not be familiar with the saying 'first make it work, if needed make it work faster'. Also, please post your O(n) solution, I would be most interested in how that is possible. – Alex Mar 19 '15 at 21:23
  • given `list1={1,2}` and `list2={1,2,3}` your code returns `Both Lists Match`. So what is misleading? (For `list2={1,2}` and `list1={1,2,3}` it returns `Not a Match` :)) ) **MySolution:** Read Jon Skeet's comment.. – EZI Mar 19 '15 at 21:28
  • 2
    You may wish to read OPs replies on questions in the comments. OPs question (as indicated in the first line of my answer) appears to be *not* whether the lists are equal, but whether `list2` contains each of the items in `list1`. – Alex Mar 19 '15 at 21:30
  • As you said (`I hope I understood your question correctly`), it is only your assumption. – EZI Mar 19 '15 at 21:33
  • 2
    Yes, that is what his comment "ill have a look to see if im allowed to used linq but i am simply trying to test if all elements of list1 are in list2" implies. For that question, this answer is correct. – Alex Mar 19 '15 at 21:35
  • Put `list2` in a `HashSet` before doing the linq query for better performance. – Magnus Mar 23 '15 at 17:50
  • @Magnus, I agree that in the general case (in terms of algorithmic complexity), this would be an improvement. In the question we are dealing with a list of ints, that we sequentially iterate over in a tight loop. If the list is not huge, then due to L1 cache locality and the predictable sequential access pattern this should perform pretty well. – Alex Mar 23 '15 at 19:23