Reputation:
Is there a quickest way to find a sub array in an array ? For exemple with anonymous methods ?
In my case, the master array is a frame of bytes received from a device, the sub-array is the characteristic sequence of the beginning of the waited answer. The device is a Lidar, so the best is the quickest possible processing.
function findSubArray( master, sub, fromPos) {
let pos = null;
if ( ! fromPos) fromPos = 0;
do {
if (master.length < sub.length) break;
if (fromPos > (master.length - sub.length)) break;
for( m=fromPos; m < (master.length - sub.length - fromPos+1); m++) {
let masterPos = m;
for( s=0; s < sub.length; s++) {
if (sub[s] != master[m + s]) {
masterPos = -1;
break;
}
}
if (masterPos != -1) {
pos = masterPos;
break;
}
}
} while( false);
return pos;
}
Best regards.
Upvotes: 0
Views: 265
Reputation: 4337
Ok, assuming that you want to see a sub array's sequence in another array, here's an example(which really is JavaScript of the C answer given by Breno Alves)
EDIT: I cut down the first loop based on the sub array's length to optimise since it was slower.. you can run the tests a few times.. sometimes it says my code is faster, other times it says your code is faster, but your code is pretty fast either way ;-;
function isSubArray(possibleParent,possibleChild){
var toReturn=false //will remain false if possibleChild is NOT subArray
var [arr,sub]=[possibleParent,possibleChild]
if(arr.length<sub.length){return false} //the sub has to be smaller
for(let i=0;i<arr.length-(sub.length-1);i++){
var isSub=true //remains true if entire sub pattern matches
for(let j=0;j<sub.length;j++){
if(arr[j+i]!=sub[j]){isSub=false}
}
if(isSub){return true} //this means a sub pattern matched
}
return false //this means no sub pattern mashed
}
//examples
console.log( isSubArray([1,2,3,4,5,6,7],[4,5]) ) //true
console.log( isSubArray([1,2,3,4,5,6,7],[1,3]) ) //false
console.log( isSubArray([1,2,3],[1,2,3,4,5,6,7]) ) //false
console.log( isSubArray([1,2,3,4,5,6,7],[1,2,3,4,5,6,7]) ) //true
//speed testing
function test(fn){
var [arr1,arr2]=[[1,2,3,4,5,6,7],[1,3]]
var startTime=new Date()-0
for(let i=0;i<1e6;i++){
fn(arr1,arr2) //test to do 1 million times
}
return new Date()-startTime
}
var myCodeTime=test(isSubArray)
var yourCodeTime=test(findSubArray)
console.log("my code speed is",myCodeTime)
console.log("your code speed is",yourCodeTime)
<script>
//your function is here :D
function findSubArray( master, sub, fromPos) {
let pos = null;
if ( ! fromPos) fromPos = 0;
do {
if (master.length < sub.length) break;
if (fromPos > (master.length - sub.length)) break;
for( m=fromPos; m < (master.length - sub.length - fromPos+1); m++) {
let masterPos = m;
for( s=0; s < sub.length; s++) {
if (sub[s] != master[m + s]) {
masterPos = -1;
break;
}
}
if (masterPos != -1) {
pos = masterPos;
break;
}
}
} while( false);
return pos;
}
</script>
Upvotes: 0
Reputation: 11
You could look at geeksforgeeks for those type of problems.
I found this O(N) solution that could be applied for your problem.
https://www.geeksforgeeks.org/check-whether-an-array-is-subarray-of-another-array/
just store the first index when starting a new sub-sequence and you have the position.
Upvotes: 0