mk-toolブログ

エンジニアと家のことをごちゃごちゃと書いてます

【Go】スタックを書く

概要

いまさらですがスタックを書きます。 元ネタは改訂第4版 C言語によるはじめてのアルゴリズム入門です。

本題

以下ソースコード

package main

import (
    "fmt"
)

const MAXSIZE = 5 // スタックの最大長
var stack [5]int
var sp int = 0 // スタックポインタ

func main() {
    var n int = 0
    for {
        fmt.Print("push(o) or pop(i)?")
        var operator string
        fmt.Scanf("%s", &operator)

        if(operator == "push" || operator == "o"){
            fmt.Print("number: ")
                fmt.Scanf("%d", &n)
            if(push(n) == -1){
                fmt.Println("スタックがいっぱいです")
            }
        }
        if(operator == "pop" || operator == "i"){
            if(pop(&n) == -1){
                fmt.Println("スタックは空です")
            }
        }
        show()
    }
}

func push(n int) int {
    if(sp < MAXSIZE){
        stack[sp] = n
        sp++
        return 0
    }
    return -1
}

func pop(n *int) int {
    if(sp > 0){
        sp--
        *n = stack[sp]
        fmt.Println("poped: ", *n)
        return 0
    }else{
        return -1
    }
}

func show() {
    fmt.Println("/////current stack/////")
    for i, v := range stack {
        if(i == (sp - 1)){
            fmt.Printf("*")         
        }
        fmt.Printf("%d ", v)
    }
    fmt.Println("")
    fmt.Println("")
}

使い方 push(o) or pop(i)?でpushしたい場合はpushoを入力、popしたい場合はpopiを入力。 pushの場合はnumberが聞かれるので数値を入力する。 そうすると、現在のスタックの状態が表示される。 なお*が付いている部分は現在のスタックポインタの位置。 popした際は、どの値がpopされたかを表示する。

出力結果

push(o) or pop(i)?o
number: 1
/////current stack/////
*1 0 0 0 0

push(o) or pop(i)?o
number: 2
/////current stack/////
1 *2 0 0 0

push(o) or pop(i)?o
number: 3
/////current stack/////
1 2 *3 0 0

push(o) or pop(i)?o
number: 4
/////current stack/////
1 2 3 *4 0

push(o) or pop(i)?o
number: 5
/////current stack/////
1 2 3 4 *5

push(o) or pop(i)?o
number: 6
スタックがいっぱいです
/////current stack/////
1 2 3 4 *5

push(o) or pop(i)?i
poped:  5
/////current stack/////
1 2 3 *4 5

push(o) or pop(i)?i
poped:  4
/////current stack/////
1 2 *3 4 5

push(o) or pop(i)?i
poped:  3
/////current stack/////
1 *2 3 4 5

push(o) or pop(i)?i
poped:  2
/////current stack/////
*1 2 3 4 5

push(o) or pop(i)?i
poped:  1
/////current stack/////
1 2 3 4 5

push(o) or pop(i)?i
スタックは空です
/////current stack/////
1 2 3 4 5