[Leet-go]-判断字符串是否为数字

本文介绍如何使用有限状态自动机解决字符串表示数值(整数和小数)的问题,通过状态转移分析和代码示例展示了如何设计函数来验证输入字符串的有效性。

实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

题解分析

一个标识数字的字符串可能包括以下字符类型:

  • 空格;
  • 数组:0~9;
  • 正负号
  • 小数点
  • 幂符号:e/E;

为了解决此类问题,需要使用有限状态自动机,字符串有如下状态:

  • 0:开始的空格;
  • 1:幂符号前的正负号;
  • 2:小数点前的数字;
  • 3:小数点、小数点后的数字;
  • 4:小数点前为空格时:小数点、小数点后的数字;
  • 5:幂符号;
  • 6:幂符号后的正负号;
  • 7:幂符号后的数字;
  • 8:结尾的空格;

合法的结束状态有:2、3、7、8。

状态转移如下图所示:
State

复杂度分析:

  • 时间:需要遍历整个字符串的长度,且状态转移为O(1),所以为O(N);
  • 空间:只需常数额外空间,所以为O(1);

代码实现

状态使用字典列表表示,具体实现为:


func isNumber(strNum string) bool {
	state := []map[byte]int{
		{' ':0, 's':1, 'd':2, '.':4},	 // 0: start with 'blank'
		{'d':2, '.':4},					 // 1: 'sign' before e
		{'d':2, '.':3, 'e':5, ' ':8},	 // 2: 'digit' before '.'
		{'d':3, 'e':5, ' ':8},			 // 3: 'digit' after '.'
		{'d':3},						 // 4: 'digit' after '.'(‘blank’ before 'dot')
		{'s':6, 'd':7},					 // 5: 'e'
		{'d':7},						 // 6: 'sign' after 'e'
		{'d':7, ' ':8},					 // 7: 'digit' after e
		{' ':8},						 // 8: end with 'blank'
	}

	index := 0
	var key byte
	for _,ch := range strNum {
		if ch>='0' && ch <= '9'{
			key = 'd'
		}else {
			switch ch {
			case '+', '-':
				key = 's'
			case 'e', 'E':
				key = 'e'
			case '.', ' ':
				key = byte(ch)
			default:
				key = '?'
			}
		}

		if _,ok:=state[index][key]; !ok{
			return false
		}
		index = state[index][key]
	}

	switch index {
	case 2,3,7,8:
		return true
	default:
		return false
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值