views:

109

answers:

2

I have a list of integers that I would like to search for a sequence.

For example, if i have a master list: 1, 2, 3, 4, 9, 2, 39, 482, 19283, 19, 23, 1, 29

And I want to find sequence: 1, 2, 3, 4

I would like some easy way to fill a subset list with: 1, 2, 3, 4 + the next five integers in the master list

And then remove the integers in the subset list from the master list so at the end of the operation, my lists would look like this:

Master list: 19, 23, 1, 29

Subset list: 1, 2, 3, 4, 9, 2, 39, 482, 19283

Hope that makes sense. I'm guessing maybe linq would be good for something like this, but I've never used it before. Can anyone help?

A: 

HINT

you can try something like this along with an iterator:

        List<int> n = new List<int>() { 1, 2, 3, 4, 9, 2, 39, 482, 19283, 19, 23, 1, 29 };
        List<int> toFind = new List<int>() { 1, 2, 3, 4 };

        if (n.Skip(indextostart).Take(4).ToList()==toFind)
        {
            n.RemoveRange(indextostart,4);
        }
Luiscencio
My intuition tells me this is O(n*m) instead of O(n), where n and m are the sizes of list to search and the list to find, respectively.
Brian
...¿¿¿and???...
Luiscencio
@Brian: yes, that is the worst case of the naive search solution. There are more clever algorithms that are O(n+m) but they involve heavily preprocessing the sequences to identify patterns that can be used to speed up the search. In practice, the "constant factor" burden on the asymptotically faster algorithms outweighs the raw speed of the naive algorithm. The pathological cases that lead to bad performance in the naive algorithm are actually rare.
Eric Lippert
+2  A: 

You could start with writing a function IndexOfSublist that can find a sublist inside a list. This has been asked many times before.

Assuming you have implemented IndexOfSublist, use it to find the first element of your result, then you could use GetRange to select the elements that you want to keep and then RemoveRange to remove the elements from the original list.

List<int> l = new List<int> { 1, 1, 2, 3, 4, 9, 2, 39, 482, 19283, 19, 23, 1, 29 };
List<int> needle = new List<int> { 1, 2, 3, 4 };

int i = indexOfSubList(l, needle);
if (i != -1)
{
    // TODO: What should we do if there are fewer than four
    // elements left after the needle? Currently we just throw.
    List<int> result = l.GetRange(i, needle.Count + 4);
    l.RemoveRange(i, result.Count);
    // TODO: Do something with the result;
}
Mark Byers