Home > Software engineering >  How to solve this Javascript recursion problem finding number of occurrence of letter in a array
How to solve this Javascript recursion problem finding number of occurrence of letter in a array

Time:04-27

I know there is some problem with the return statement but I cant figure out what.

let arr = ['a', 'b', 'c', 'a']
let size = arr.length - 1
let counter = 0

function findOcc(arr, size, x) {
  if (size === 0) {
    return counter
  } else {
    if (arr[size] === x) return counter  
      findOcc(arr, size - 1, 'a')
  }
}

console.log(findOcc(arr, size, "a"))

CodePudding user response:

It seems you got the logic right in your head, but didn't implement it well.

  • So for the base condition you say if (size===0) return counter. This means that you just return counter but arr[0] is a valid check. So what you want really when you are checking elements is arr[size-1] in the next line i.e. else

  • For the else condition you meant to increment the counter which is right, but you should n't return. Instead you return the value of the next call with size-1

  • Also your declaration of size should be let size = arr.length

  • Also the last argument should be x and not a inside the recursive call.

With that the code is:

let arr = ['a', 'b', 'c', 'a']
let size = arr.length
let counter = 0

function findOcc(arr,size,x) {
  if (size === 0) return counter
  if(arr[size-1]===x)    counter
  return findOcc(arr,size-1,x)
}

console.log(findOcc(arr, size, "a"))

CodePudding user response:

If one is okay with mutating the original array, then the function may be simplified like below:

const origArr = ['a', 'b', 'c', 'a'];

// a simpler implementation of the same recursive function
function findOcc(arr, x) {
  return (
    arr.length                // if "arr" length is 1 or more
    ? arr.pop() === x         // ".pop()" the last elt & compare with "x"
      ? 1   findOcc(arr, x)   // add 1 & recurse using the shorted/mutated "arr"
      : findOcc(arr, x)       // do not add 1, but recurse using the mutate "arr"
    : 0                       // no more elements in "arr", so return 0
  )
}

// using "..." spread to avoid "arr" from being changed
console.log('number of times "a" occurs is: ', findOcc([...origArr], "a"))

console.log(
  `"d" occurs in ["${origArr.join('", "')}"] ${findOcc([...origArr], "d")} times...`
)

CodePudding user response:

A simpler recursive version uses array destructuring to test the first value against the target value, adding one if it matches, and zero if it doesn't, then recurring on the remainder of the array. We stop when the value is undefined, meaning we've run out of elements in the array.

const countOcc = (target) => ([x, ...xs]) =>
  x == undefined ? 0 : (x == target ? 1 : 0)   countOcc (target) (xs)

const arr = ['a', 'b', 'c', 'a']

console .log (countOcc ('a') (arr))
console .log (countOcc ('b') (arr))
console .log (countOcc ('c') (arr))
console .log (countOcc ('d') (arr))

While we could alter this to make it tail-recursive, current JS engines still do not do tail-call optimization, so it seems a bit pointless. If you were going to do this on large arrays, you would probably need to rewrite with iteration in place of recursion.

  • Related