Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

160
Views
Infinite loop on recursive call Javascript

This is a basic calculator function. It only does addition, subtraction, multiplication, division and parentheses.

I'm having an infinite loop on recursive call in while section which is checking the string whether has a parentheses or not. If i would've send a string with 2 or more parentheses to the function, it has been stucking in loop. I couldn't figure out what I have done wrong.

const operators = ['+', '-', '*', '/', '(', ')'];
const numbers = [];
let arr;
const array = [];
function Calculate(string) {
  string.split('').map(char => {
    if (!operators.includes(char)) {
      numbers.push(char);
    } else {
      arr = numbers.join('');
      numbers.splice(0);
      array.push(arr, char);
    }
  });
  arr = numbers.join('');
  const str = array.filter(char => char !== '').concat(arr);

  while (str.includes('(')) {  // Checking parentheses
    let indexOpen = str.findIndex(char => char === '(');
    let indexClose = indexOpen + 1;
    let count = 1;

    while (count !== 0) {
      if (str[indexClose] === '(') {
        count++;
      } else if (str[indexClose] === ')') {
        count--;
      }
      indexClose++;
    }

    if (
      !operators.includes(str[indexOpen - 1])
      // str[indexOpen - 1] !== '+' &&
      // str[indexOpen - 1] !== '-' &&
      // str[indexOpen - 1] !== '*' &&
      // str[indexOpen - 1] !== '/'
    ) {
      str.splice(indexOpen, 0, '*');
      indexOpen++;
      indexClose++;
    }

    const strPara = str
      .filter((_, i) => i < indexClose - 1 && i > indexOpen)
      .join('');
    str.splice(indexOpen, indexClose - indexOpen, Calculate(strPara));
  }

  let indexMul;  // Multiplication and division
  let indexDiv;
  while (str.includes('*') || str.includes('/')) {
    indexMul =
      str.findIndex(char => char === '*') === -1
        ? str.length
        : str.findIndex(char => char === '*');
    indexDiv =
      str.findIndex(char => char === '/') === -1
        ? str.length
        : str.findIndex(char => char === '/');
    if (indexMul < indexDiv) {
      str.splice(indexMul - 1, 3, +str[indexMul - 1] * +str[indexMul + 1] + '');
    } else if (indexDiv < indexMul) {
      str.splice(
        indexDiv - 1,
        3,
        Math.trunc(+str[indexDiv - 1] / +str[indexDiv + 1]) + ''
      );
    }
  }

  while (str.length !== 1) { // Addition and subtraction
    if (str[1] === '+') {
      str.splice(0, 3, +str[0] + +str[2] + '');
    }
    if (str[1] === '-') {
      str.splice(0, 3, +str[0] - +str[2] + '');
    }
  }

  return str;
}

console.log(Calculate('3(16-(10-4)+2)/2(4*2)+1'));

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I did this.
Be careful, this code does the calculations one after the other without managing operators precedence

The recursive way :

let strCalc = '3(16-(10-4)+2)/2(4*2)+1'
document.write(`${ strCalc } = ${ Calculate(strCalc) }`)
document.write(`<br><br>`)

strCalc = '5 ( -18.4 + 2 ) / ( -2 ( 4 * -.5 )) + 1'
document.write(`${ strCalc } = ${ Calculate(strCalc) }`)

function Calculate(str)
  {
  const ops = str
    .match(/[\(\)\+\-\*\/]|((\d+\.?\d*)|(\.\d+))/g)
    .reduce((r,v)=>
    {
    if (isNaN(v))
      {
      if (!r.opPrev || v==='(') 
        {
        r.res.push(v)
        r.opPrev = ( v!==')' )
        }
      else if (v==='-')   // check negatives values
        r.sign='-';
      }
    else
      {
      r.res.push(Number(`${r.sign}${v}`))
      r.sign   = ''
      r.opPrev = false
      }
    return r  
    }, { res:[], opPrev:true, sign:'' }).res  
    ;
  let Pos = 0
    ;
  return makeCalc()
    ;
  function makeCalc()
    {
    let result  = 0
      , operand = '+'
      , val
      ;
    while  ( Pos < ops.length  &&  ops[Pos] !== ')' )
      {
      val = ops[Pos]
        ;
      if ( val === '(' )
        {
        operand ??= '*'        // nullish assignement operator
        Pos++
        val = makeCalc()       // recurvive call
        }
      if ( isNaN(val) )
        operand = val
        ;
      else
        {
        switch (operand)
          {
          case '+' : result += val;  break; 
          case '-' : result -= val;  break; 
          case '/' : result /= val;  break;  // may do 0 divide! 
          case '*' : result *= val;  break; 
          }
        operand = null
        }
      Pos++
      }
    return result
    }
  }

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!