I have a few arrays of strings like:
$big = ['html', 'body', 'div', 'table', 'tbody', 'tr', 'td'];
$small = ['body', 'div', 'td'];
$wrong = ['td', 'body', 'div'];
I need to check whether $small
and $wrong
are to be found in $big
. However I need the order to be the same. So my function should return true
for $small
and false
for $wrong
. It should be fairly trivial to do it manually but I need the code to be fast. So ideally if there is a built in that achieves this I would rather use that.
So the question is mainly whether such a built in exists. Here is the code I have come up with in case it doesn't:
/**
* Returns whether the substack is contained in the stack in the correct order.
*
* @param string[] $stack The substack to check
* @param string[] $subStack The substack to check
* @return bool
*/
function stackInStack(array $stack, array $subStack)
{
// First let's do a simple array diff to save time on an ordered diff;
// TODO: Check if this actually improves average performance.
if (count(array_diff($subStack, $stack)) !== 0) return false;
$stackSize = count($stack);
$subStackSize = count($subStack);
$stackIndex = 0;
for ($subIndex = 0; $subIndex < $subStackSize; $subIndex++) {
while (
$stackIndex < $stackSize &&
$stack[$stackIndex] !== $subStack[$subIndex]
) {
$stackIndex++;
}
if ($stackIndex == $stackSize) {
if ($subIndex <= $subStackSize - 1) {
return false;
} elseif ($subIndex > $subStackSize - 1) {
throw new Exception('Very Strange Exception: subIndex has outgrown subStacksize');
}
} elseif ($stackIndex > $stackSize) {
throw new Exception('Very Strange Exception: index has outgrown stacksize');
break;
}
}
return true;
}
Provided a built in doesn't exist or is slow, any tips to improve the efficiency of the above code (other than to rewrite it in c) would also be greatly appreciated.