How to Use Arrays as Stacks in Go

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setup
  4. Creating an Array as a Stack
  5. Stack Operations
  6. Example: Reversing a String
  7. Conclusion


Introduction

In Go, arrays are fixed-size sequences of elements of the same type. While arrays have a fixed length, we can leverage them to implement data structures like stacks, which have dynamic sizes. In this tutorial, we will learn how to use arrays as stacks in Go. By the end of this tutorial, you will be able to create and manipulate arrays as stacks to perform common stack operations.

Prerequisites

Before starting this tutorial, you should have a basic understanding of the Go programming language, including variables, data types, and basic syntax.

Setup

To follow along with this tutorial, you need to have Go installed on your machine. You can download and install the latest version of Go from the official website (https://golang.org/dl/). Once installed, verify that Go is properly set up by running the following command in your terminal:

go version

This should display the installed version of Go.

Creating an Array as a Stack

To create an array as a stack in Go, we can use an existing array and define a variable to keep track of the current top of the stack. Here’s an example:

package main

import "fmt"

func main() {
  var stack [5]int // Create an array of size 5
  top := -1       // Initialize the top of the stack

  fmt.Println(stack)
}

In the above example, we create an array stack with a fixed size of 5 and initialize the top of the stack (top) to -1. The stack variable will be used to store the elements, and top will point to the index of the topmost element in the stack.

Stack Operations

Now that we have created an array as a stack, let’s look at common stack operations: push, pop, and peek.

Push

The push operation adds an element to the top of the stack. To implement the push operation for our array-based stack, we need to increment the top variable and assign the new element to the corresponding index in the stack array.

func push(stack *[5]int, top *int, element int) {
  // Check if the stack is full
  if *top >= len(*stack)-1 {
    fmt.Println("Stack Overflow!")
    return
  }

  *top++ // Increment the top
  (*stack)[*top] = element // Add the element to the top
}

In the push function above, we pass the stack array as a pointer to allow modifications and update the top variable accordingly. We first check if the stack is already full. If the top is equal to the length of the array minus 1, it means the stack is full and we cannot add more elements (stack overflow). Otherwise, we increment top, and then assign the new element to the stack at the updated top index.

Pop

The pop operation removes and returns the element from the top of the stack. To implement the pop operation, we need to return the element at the current top index and decrement the top variable.

func pop(stack *[5]int, top *int) (int, error) {
  // Check if the stack is empty
  if *top == -1 {
    return 0, fmt.Errorf("Stack Underflow!")
  }

  element := (*stack)[*top] // Get the element at the top
  *top-- // Decrement the top

  return element, nil
}

In the pop function above, we pass the stack array as a pointer to allow modifications and return the topmost element by retrieving it from the stack at the current top index. We also decrement top to point to the next lower element. If the top is -1, it means the stack is empty and we cannot perform the pop operation (stack underflow), hence we return an error.

Peek

The peek operation returns the element from the top of the stack without removing it. To implement the peek operation, we simply return the element at the current top index.

func peek(stack *[5]int, top int) (int, error) {
  // Check if the stack is empty
  if top == -1 {
    return 0, fmt.Errorf("Stack Underflow!")
  }

  element := (*stack)[top] // Get the element at the top

  return element, nil
}

In the peek function above, we receive the stack array as a pointer and the current value of top. We return the element at the top index of the stack. If the top is -1, it means the stack is empty and we cannot perform the peek operation (stack underflow), so we return an error.

Example: Reversing a String

Let’s use our array-based stack to implement a simple example: reversing a string. We will consider each character in the input string and push it onto the stack. Then, we will pop each character from the stack and concatenate them to form the reversed string.

func reverseString(input string) string {
  var stack [len(input)]rune // Create a stack of runes (characters)
  top := -1 // Initialize the top of the stack

  // Push each character onto the stack
  for _, char := range input {
    top++
    stack[top] = char
  }

  // Pop each character from the stack and build the reversed string
  reversed := ""
  for top >= 0 {
    char := stack[top]
    reversed += string(char)
    top--
  }

  return reversed
}

In the reverseString function above, we first create a stack stack of the same length as the input string to hold each character. We initialize top to -1, pointing to the empty stack. Then, we loop through each character in the input string, increment top, and push the character onto the stack.

Next, we declare an empty string reversed and iterate while top is not -1. In each iteration, we pop the top character from the stack, convert it to a string, and append it to reversed. Finally, we return reversed, which contains the reversed version of the input string.

To use this example, we can call the reverseString function with a sample string and print the result:

func main() {
  input := "Hello, world!"
  reversed := reverseString(input)
  fmt.Println(reversed)
}

Running the above code should output:

!dlrow ,olleH

Conclusion

In this tutorial, we learned how to use arrays as stacks in Go. We explored the implementation of common stack operations like push, pop, and peek. We also applied the array-based stack to create a simple example of reversing a string. Arrays as stacks provide a simple and efficient way to handle dynamic sizes in Go programs. By understanding the concepts and examples covered in this tutorial, you are now equipped to apply arrays as stacks in your own Go projects.