算法4-检查左右括号是否匹配

题目:
给定一串字符串,是由左右括号组成,要求判断左右括号是否匹配,不匹配的删除多于的括号使其匹配,返回正确的字符串

解题思路:
1定义两个指针check和delete,表示检查点和删除点,对应检查到哪个idx和应该删除哪个idx
2定义一个int型变量count,记录分数,遇到左括号+1,遇到右括号-1,当count=-1,表示右括号多出一个,就要删除右括号
3执行2之后,删除哪一个右括号,从头找,遇到第一个右括号且它的左边是左括号,就是删除点,删除
4,删除后形成一个新字符串,递归调用检查函数,知道检查完删除完
5右括号检查完,将字符串反转,同样逻辑开始检查左括号,知道左右括号都合规

代码:

package main

import(
	"fmt"
)
//"(()))(()()))"
//第一次从左往右遍历,先检查右括号
func barcket(str string,check,delete int,par []string)string{
	// check:=0
	// delete:=0
	// par:=[]string{"(",")"}
	count:=0
	//查找第一个多于括号的循环
	//依然还是要循环
	for i:=check;i<len(str)-1;i++{
		// fmt.Printf("len==================%v\n",len(str))
		// fmt.Printf("iiiiiiiiiiiiiii===%v\n",i)
		// fmt.Println(string(str))
		// fmt.Println(string(str[i]))
		//先从左边往右找左括号“(”,找到+1,找到右括号-1,
		if string(str[i])==par[0]{
			count++
		}
		if string(str[i])==par[1]{
			count--
		}
		fmt.Printf("count=====%v\n",count)
		//count值变成-1,说明就找到了第一个多余的右括号,
		if count<0{
			//查找删除点的循环
			//这个for循环里先找删除位置,即遇到的第一个左边是左括号的右括号
			for j:=delete;j<=i;j++{
				if string(str[j])==par[1] && string(str[j-1])==par[0] && j<len(str){
					fmt.Println(string(str[j]),string(str[j-1]),j)
					//找到后将其删除,跳出查找删除点的循环
					str=string(str[0:j])+string(str[j+1:len(str)])
					fmt.Println(str)
					break
				}
			}
			fmt.Printf("after delete =new str==%v\n",str)
			//递归调用,传值是新的字符串和检查点删除点是0值的指针
			barcket(str,0,0,par)
			return str//return//这里一定要break或者return,不然递归出来后就又接着进入最外层for循环的下一个idx继续执行了


		}
	}
	fmt.Println(str)
	// par=[]string{")","("}
	fmt.Println(check,delete)
	//前面第一个for循环表示正序检查完-删除完,或者没有多余的右括号需要删除了,就要进行下一步,反转字符串,检查左括号是否多于
	//这里加if判断,就是要判断执行到哪一步,是执行检查左括号还是右括号,检查完右括号之后str[0]肯定是“(”才能进入下一步反转进行检查左括号
	//否则就是左右检查都执行完了,直接返回return
	if par[0]=="("{
		par=[]string{")","("}
		barcket(reverseString([]byte(str)),check,delete,par)
		reverseString([]byte(str))
		fmt.Println(str)

	}else{
		return str
	}


	return str

	
}

func reverseString(r []byte) string{
	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	// fmt.Printf("after delete =new str==%v\n",string(r))

	return string(r)
}
func main(){
	str:="(()))(()()))"
	check:=0
	delete:=0
	par:=[]string{"(",")"}
	// par:=[]string{")","("}

	barcket(str,check,delete,par)
	// reverseString([]byte(str))
	// barcket(reverseString([]byte(str)),check,delete,par)

}

执行过程:

在这里插入图片描述

这里有几个我遇到的小坑点总结下:
1 删除点循环for里面的return,如果没有这个return,就会从0删除所有负荷删除条件的括号
2代码第一个递归调用要在检查删除点循环的外层调用,即循环完了break出来再递归
3第一次调用递归后面一定要加上return,不然递归出来后会接着从进入删除点前的idx再来一遍循环
4右括号检查完反转进行左括号检查前,一定要加判断,如过par[0]是“(”才进,这就控制了检查左括号还是右括号

以上就是我看左神视频自己用go实现的代码,不得不佩服大神的代码,记录下来供自己学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值