(1)Go实现栈和leetcode-20解答

栈是一种线性结构,遵循先进后出的原则

在操作上类似数组的子集

只能从一端添加元素,也只能从一端取出元素

这一端成为栈顶

应用地方:撤销操作,程序调用的系统栈,括号匹配等等


// 栈类定义和操作方法的实现

package stack

import (
	"github.com/pkg/errors"
)

type arrayStack []interface{}

func NewArrayStack() *arrayStack {
	return &arrayStack{}
}

func (i *arrayStack) Push(char interface{}) {
	*i = append(*i, char)
}

func (i *arrayStack) Pop() (interface{}, error) {
	j := *i
	l := len(j)
	c := cap(j) / 4

	if l == 0 {
		return nil, errors.New(
			"Failed to pop, stack is empty ")
	}

	// 如果长度小于容量的1/4,将容量缩短1/2
	if l <= c {
		buffer := make(arrayStack, 0, 2*c)
		for i := 0; i < l; i++ {
			buffer = append(buffer, j[i])
		}
		j = buffer
	}

	value := j[l-1]
	*i = j[:l-1]
	return value, nil
}

func (i *arrayStack) Top() (interface{}, error) {
	j := *i
	if len(j) == 0 {
		return nil, errors.New("Out of index,len is 0 ")
	}
	return j[len(j)-1], nil
}

func (i *arrayStack) Len() int {
	return len(*i)
}

func (i *arrayStack) Cap() int {
	return cap(*i)
}

func (i *arrayStack) IsEmpty() bool {
	return len(*i) == 0
}
// 做测试

func main() {
	test()
}

func test() {
	a := stack.NewArrayStack()

	for i := 0; i < 5; i++ {
		a.Push("hello world-" + strconv.Itoa(i))
	}

	fmt.Printf("isEmpty: %v, len=%v, cap=%v, pop=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Pop()))
	fmt.Printf("isEmpty: %v, len=%v, cap=%v, top=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Top()))
	fmt.Printf("isEmpty: %v, len=%v, cap=%v, pop=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Pop()))
	fmt.Printf("isEmpty: %v, len=%v, cap=%v, pop=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Pop()))
	fmt.Printf("isEmpty: %v, len=%v, cap=%v, pop=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Pop()))
	fmt.Printf("isEmpty: %v, len=%v, cap=%v, pop=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Pop()))
	fmt.Printf("isEmpty: %v, len=%v, cap=%v, pop=%v\n",
		a.IsEmpty(), a.Len(), a.Cap(), fmt.Sprintln(a.Pop()))
}
最终输出结果如下
isEmpty: false, len=5, cap=8, pop=hello world-4 <nil>
isEmpty: false, len=4, cap=8, top=hello world-3 <nil>
isEmpty: false, len=4, cap=8, pop=hello world-3 <nil>
isEmpty: false, len=3, cap=8, pop=hello world-2 <nil>
isEmpty: false, len=2, cap=8, pop=hello world-1 <nil>
isEmpty: false, len=1, cap=4, pop=hello world-0 <nil>
isEmpty: true, len=0, cap=2, pop=<nil> Failed to pop, stack is empty 
例题:
给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

示例 1:        示例 2:            示例 3:          示例 4:         示例 5:
输入: "()"     输入 "()[]{}"     输入: "(]"        输入: "([)]"    输入: "{[]}"
输出: true     输出: true        输出: false       输出: false     输出: true
// 解题思路:遍历字符串,将左括号放放入栈中,如果是右括号,就将栈顶括号取出来,看能否闭合,
无法闭合就返回false,能闭合并且最终栈为空就返回true

func isMatch(str string) bool {
	a := stack.NewArrayStack()

	for _, k := range str {
		v := string(k)
		switch v {
		case "(":
			a.Push(v)
		case "[":
			a.Push(v)
		case "{":
			a.Push(v)
		case ")":
			top, err := a.Pop()
			if err != nil || top != "(" {
				return false
			}
		case "]":
			top, err := a.Pop()
			if err != nil || top != "[" {
				return false
			}
		case "}":
			top, err := a.Pop()
			if err != nil || top != "{" {
				return false
			}
		}
	}
	if a.Len() != 0 {
		return false
	}
	return true
}
// 测试
func main() {
	var (
		str1 = "({}{}())" //true
		str2 = "({{)}}()" //false
		str3 = "(}"       //false
		str4 = "({})"     //true
		str5 = "(({})"    //false
	)

	fmt.Println(isMatch(str1))
	fmt.Println(isMatch(str2))
	fmt.Println(isMatch(str3))
	fmt.Println(isMatch(str4))
	fmt.Println(isMatch(str5))
}
// 测试结果
true
false
false
true
false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值