Implementing the infix to postfix algorithm in JavaScript with a linked list stack

I have been honing my skills in data structures with JavaScript and recently tackled the task of converting an infix expression to postfix using a linked list stack. While I am confident in my logic, two functions - isLetter() and precedence() might be causing some issues.

Current result: Postfix Expression: +21-43--56/
Expected result: Postfix Expression: 12+34--65-/

Current result: Postfix Expression: *-^^12242
Expected result: Postfix Expression: 24*221^^-

class Node {
  /* Creates a new node with given element and next node */
  constructor(e, n) {
    this.data = e;
    this.next = n;
  }
}

class LinkedStack {
  /* Initializes an empty stack */
  constructor() {
    this.top = null;
    this.size = 0;
  }

// Rest of the code has not been altered to keep it as close to original instructive content

let pToIn = new PostfixToInfix();
let sample1 = "(((1+2)-(3-4))/(6-5))";

console.log("Infix Expression: " + sample1);

/* Current result: Postfix Expression:     +21-43--56/
/* Expected result: Postfix Expression: 12+34--65-/
*/
console.log("Postfix Expression: " + pToIn.intoPost(sample1));

/* Current result: Postfix Expression:      *-^^12242
/* Expected result: Postfix Expression:  24*221^^-
*/

let sample2 = "2*4-2^2^1";
console.log("Infix Expression: " + sample2);
console.log("Postfix Expression : " + pToIn.intoPost(sample2));

/*
let stack = new LinkedStack();
stack.push(9);
console.log(stack.pop() + " was popped"); // 9 was popped
stack.push(12);
stack.push(15);
stack.push(7);
console.log("Is Stack Empty? " + stack.isEmpty()); // Is Stack Empty? false
console.log("Stack Length: " + stack.length()); // Stack Length: 2
console.log("Top value: " + stack.peek()); // Top value: 15
console.log("Stack Content: " + stack.toString()); // Stack content [15, 12]  */

Answer №1

One issue is that the input contains digits, which are not considered as letters by the isLetter test. To address this, you can switch to a different function that also recognizes digits, like using a regex match.

Alternatively, you could opt for the default action where letters, digits, and any other characters in the input are simply passed through to the output. This approach may be less efficient since it involves stacking and popping them immediately, but it greatly simplifies the inner loop.

Below is a streamlined version of your code with some unnecessary functions removed, such as isLetter. Note that the reduction loop ends when the incoming character matches the precedence level of the top character on the stack, signaling the presence of a closing parenthesis.

class Node {
  constructor(e, n) {
    this.data = e;
    this.next = n;
  }
}

class LinkedStack {
  constructor() {
    this.top = null;
    this.size = 0;
  }

  push = (elem) => {
    let v = new Node(elem, this.top);
    this.top = v;
    this.size++;
  };

  length = () => {
    return this.size;
  };

  isEmpty = () => {
    return this.size === 0;
  };

  peek = () => {
    if (this.isEmpty()) {
      console.log("Empty Stack");
    }
    return this.top.data;
  };

  pop = () => {
    if (this.isEmpty()) {
      console.log("Empty Stack");
    }
    const temp = this.top.data;
    this.top = this.top.next;
    this.size--;
    return temp;
  };

  toString = () => {
    let s = "[";
    let cur = null;
    if (this.length() > 0) {
      cur = this.top;
      s += cur.data;
    }

    if (this.length() > 1) {
      for (let i = 1; i <= this.length() - 1; i++) {
        cur = cur.next;
        s += ", " + cur.data;
      }
      s += "]";
      return s;
    }
  };
}

class PostfixToInfix {
  intoPost = (s = " ") => {
    let stack = new LinkedStack();
    stack.push('$');
    let output = "";

    for (let cur = 0; cur < s.length; cur++) {
      let c = s.charAt(cur);
      let prec = this.curValues(c);
      while (this.stackValues(stack.peek()) > prec) {
        output = output + stack.pop();
      }
      if (c == ')') {
        if (stack.peek() != '$') {
          stack.pop();
        }
      } else {
        stack.push(c);
      }
    }
    while (stack.peek() != '$') {
      output = output + stack.pop();
    }
    return output;
  };

  stackValues = (c = "") => {
    if (c === "(" || c == '$') {
      return 0;
    } else if (c === "^") {
      return 15;
    } else if (c === "*" || c === "/" || c === "%") {
      return 14;
    } else if (c === "+" || c === "-") {
      return 12;
    }
    return 90;
  };

  curValues = (c = "") => {
    if (c === "(") {
      return 100;
    } else if (c == ")") {
      return 0;
    } else if (c === "^") {
      return 16;
    } else if (c === "*" || c === "/" || c === "%") {
      return 13;
    } else if (c === "+" || c === "-") {
      return 11;
    }
    return 90;
  };
}

let pToIn = new PostfixToInfix();
let sample1 = "(((1+2)-(3-4))/(6-5))";

console.log("Infix Expression: " + sample1);

/* My result is: Postfix Expression:     +21-43--56/
/* Answer should be: Postfix Expression: 12+34--65-/
*/
console.log("Postfix Expression: " + pToIn.intoPost(sample1));

/* My result is: Postfix Expression:      *-^^12242
/* Answer should be: Postfix Expression:  24*221^^-
*/

let sample2 = "2*4-2^2^1";
console.log("Infix Expression: " + sample2);
console.log("Postfix Expression : " + pToIn.intoPost(sample2));

/*
let stack = new LinkedStack();
stack.push(9);
console.log(stack.pop() + " was popped"); // 9 was popped
stack.push(12);
stack.push(15);
stack.push(7);
console.log("Is Stack Empty? " + stack.isEmpty()); // Is Stack Empty? false
console.log("Stack Length: " + stack.length()); // Stack Length: 2
console.log("Top value: " + stack.peek()); // Top value: 15
console.log("Stack Content: " + stack.toString()); // Stack content [15, 12]  */

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Verify if the jQuery library has an existing style attribute

I've been working on a script to loop through my form inputs and check for the presence of the style attribute. Despite feeling like I'm close to getting it right, there seems to be an issue with my code. There are actually only 2 inputs with the ...

Navigating through paginated data can be made easier by using Backbone.PageableCollection in conjunction with a personalized

I have developed an application that interacts with a database known as LeanCloud. Currently, I have configured a page to display all the users stored in the database. However, LeanCloud has a limitation where only 100 pieces of data can be retrieved per r ...

How to access an ejs variable within a Node.js environment using Javascript

As I experiment with my JavaScript code in an HTML file to interact with an ejs variable. Here is the Node.js code snippet: res.render('target.ejs', {data:user}); Everything works fine when I include this in my HTML file: <p> <h1> ...

Ensuring secure Firebase JSON database access through Firebase authentication

I am currently developing a mobile app using Ionic 3 with Angular, and I am utilizing the Facebook Native Cordova plugin for user login. In terms of Firebase database security, the documentation provides guidance on rules syntax like this: { "rules" ...

My Bootstrap 4 slider is malfunctioning and needs to be fixed

Help with my Bootstrap 4 slider issue! It's only displaying one image instead of three. <title> Welcome - Maqbool Solutions </title> <link rel="shortcut icon" href="images/favicon_Y13_5.ico" type="image/x-icon"> <link rel="st ...

Achieving Vertical Center Alignment in CSS for Dynamic Div Elements

I am currently working on vertically centering a div called container. It was successfully centered, but now I am using jQuery to add more divs to it like so: $("#add").on("click", function () { $(".elements").append("<div class='element' ...

Embarking on a fresh XR experience

As a newcomer to TypeScript, I am exploring how to create a functionality similar to a "double-click" event for a hand-input controller in my Three.js application. Here is my approach: - I monitor a click event - I check the timing between the last click ...

Move on to a different screen in a React Component once the data has been fetched

Currently, I am delving into the world of React and TypeScript and attempting to utilize "react-router-dom" in order to create a login component that will interact with my backend server. Essentially, my goal is to develop a "Login" class that, upon form ...

Using Angular Material 6 with Mat-Chip-List: when two mat-chip-list declarations are linked to identical data sources

Experimenting with Angular 6 and Angular Material, I am attempting to create 2 Auto-complete Chip Lists using distinct data sources. The modification of the previous example can be seen here: https://material.angular.io/components/chips/overview Yet, it a ...

Having trouble with jQuery events not triggering properly after dynamically inserting elements using an ajax request?

It's strange that all my jQuery events become unresponsive after an AJAX call. When I use a load function, once the JSP reloads, none of the events seem to work properly. Any suggestions? Below is the code that triggers the function call: $('#p ...

Encountered the issue: "Received the error message 'MongooseServerSelectionError: Server selection timed out after 30000 ms.'"

I encountered the following error: MongooseServerSelectionError: Server selection timed out after 30000 ms while working with MongoDB Atlas. I attempted changing the useUnifiedTopology setting to false, which prevented my application from crashing. However ...

Retrieve the $id value of a nested object using angularFire

I am facing a situation where I have to implement nested ng-repeat. While trying to retrieve the $id of the first ng-repeat, there is no issue. However, when attempting to access the $id of the second ng-repeat (highlighted in red in the image below), it r ...

Data object constructor is not triggered during JSON parsing

Currently, I am retrieving data from a server and then parsing it into TypeScript classes. To incorporate inheritance in my classes, each class must be capable of reporting its type. Let me explain the process: Starting with the base class import { PageE ...

Ways to determine if an object contains an array

Looking at the following data structure: [ 13, { a: [ [ '2988.30000', '0.19000000', '1549294216.653040' ] ] }, { b: [ [ '2988.30000', '0.00000000', '1549294216.653774&a ...

What is the correct way to incorporate scrollIntoView() using jQuery?

I'm trying to implement a jQuery function that will enable the last reply to scroll into view. This is my current code: function displayLastReply(replies){ replies.each(function() { if($(this).index() < nIniRep || afterReply){ $( ...

Is it advisable to include both the numerical value and the string representation of an enum in my API design?

Context In the development of a product, I am faced with managing various enumerated values to categorize different data types. This is particularly relevant in C programming for a microcontroller environment: typedef enum { Temperature = 100, ...

Angular's ng-submit directive does not use the most up-to-date scope available

I'm currently learning Angular and have been struggling with a particular issue. I have created a form to edit user details. Upon page load, I make an AJAX call to fetch the data of the selected user and populate the scope with the values. Initially, ...

Loading a webpage after clicking on an element using Puppeteer

I am facing a challenge with my puppeteer-loaded page where I have a list of elements that can be clicked to reveal additional data. It's similar to an accordion feature. Despite trying various approaches, such as: async function getSite(url) { con ...

Using requestAnimationFrame to animate several independent objects

I'm currently working on animating two different objects: a square and a circle. Each object has its own button to initiate the animation, which involves moving the object from left to right. However, I've run into an issue where clicking on one ...

Limit the input text to only numerical values and require a minimum length of 10 characters for phone numbers

How can I create a text box that only accepts numbers with a minimum length of 10, and another version that allows a + at the start followed by two or three sets of numbers separated by hyphens, like +91-123-456-7890? Below is the code snippet: <input ...