With code changes that do not affect the order of complexity, any candidate improvements need profiling (tests that measure the performance) to verify.
The following is still a O(n*m), yet with reduced coefficient as it can step through b[]
faster if a[]
has repeated values that also exist in b[]
. This speeds the inner b[]
loop where the majority of time is consumed.
Look at the a[]
pattern for distinct values to so j
may be advanced faster.
Example:
#define x 0
bool Pattern3(const int *a, size_t size_a, const int *b, size_t size_b) {
static const unsigned char deltas[2][2][2][2] = { //
// What type of pattern is a[0], a[1], a[2]?
{ { { 1, 1 }, // X Y Z
{ 1, 1 } }, // X Y Y
{ { 1, 2 }, // X Y X
{ x, x } } }, // not possible
{ { { 2, 1 }, // X X Y
{ x, x } }, // not possible
{ { x, x }, // not possible
{ 2, 3 } } } }; // X X X
for (unsigned i = 0; i + 2 < size_a; i++) {
const unsigned char *delta23 = deltas[a[0] == a[1]][a[0] == a[2]][a[1] == a[2]];
for (unsigned j = 0; j + 2 < size_b;) {
if (a[0] != b[j]) {
j++;
} else if (a[0 + 1] != b[j + 1]) {
j += delta23[0];
} else if (a[0 + 2] != b[j + 2]) {
j += delta23[1];
} else {
return true;
}
}
a++;
}
return false;
}
Other minor changes which may help.
In the above, swap a,b
when size_a > size_b
.
Use const
as lesser compilers can optimized on that.
// int consecutiveInts(int *a, int sizeA, int *b, int sizeB){
int consecutiveInts(const int *a, int sizeA, const int *b, int sizeB){
Iterate from 2. Adjust indexing accordingly.
for (i = 2 ; i < sizeA ; i++){
...