Question

I want to make a module in Mathematica that return true if the first list (L1) is in the second list (L2) assuming that the length of L2 is greater than the length of L1. I did it in this way, the problem is that always return False and I don't know why. EDIT: I have solved a problem: I wrote "if" instead of "If". Now I get an infinitely loop.

isSegment[L1_List, L2_List] := Module[{i, j},   For[i = 1, i + Length[L1] - 1 <= Length[L2],
       For[j = 1, j <= Length[L1],
    If[L2[[i + j - 1]] != L1[[j]], Break;];
    j++;
    ];
       If[j == Length[L1] + 1,
    Return[ True];];
       i++;    ];   Return [False];   ]
Was it helpful?

Solution

This is likely to be one of the cleanest and fastest general methods available:

isSegment[{L1__}, L2_List] := MatchQ[L2, {___, L1, ___}]

isSegment[{3, 4, 5}, Range@10]
True

For a list of all Real or Integer values you could adapt the methods shown here for maximum speed.


user writes:

Thanks, it is a good way, but what I want is to correct my code not to have a new one because it is an exercise for school and in the statement it is said that we must use For loops.

It appears that there is confusion over the syntax of Break[] and the function of Return. To correct the code I replaced Break with Break[] and Return with Throw & Catch.

isSegment[L1_List, L2_List] :=
 Catch @ Module[{i, j},
   For[i = 1, i + Length[L1] - 1 <= Length[L2],
    For[j = 1, j <= Length[L1], 
     If[L2[[i + j - 1]] != L1[[j]], Break[];]; j++;];
    If[j == Length[L1] + 1, Throw[True];];
    i++;]; Throw[False];
   ]

OTHER TIPS

I'd normally go about this problem using something like this:

SegmentQ[l1_List, l2_List] := MemberQ[Partition[l2, Length @ l1, 1], l1]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top