Go语言力扣刷题-字符串转换整数|Go主题月

506 阅读5分钟

发现掘金的一个小彩蛋: 个人主页,鼠标放置在头像上,头像会转动,越转越快,调皮的程序员O(∩_∩)O~。

  1. 字符串转整数

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

  • 读入字符串并丢弃无用的前导空格
  • 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
  • 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  • 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
  • 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
  • 返回整数作为最终结果。

注意: 本题中的空白字符只包括空格字符 ' ' 。 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/st… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

嗯,出个题连算法都给出来,就挺离谱另外,既然是解决文档,当然排除使用Go中的Atoi函数,即strconv包。

本题可以学到的Go知识包括:

  1. Go中如何将字符转换为对应的数字,即'2'如何转换为数字2:
package main
import (
    "bytes"
    "encoding/binary"
    "fmt"
)
func main()  {
	s := "0123"
	s_w1 := int(s[0]) // 直接显示转换
	fmt.Println(s_w1) // 48, 即'0'在ASCII中的10进制数字
	// 修正后我们采用如下方式可将字符'0'-'9'转换为对应的int数字
	s_w2 := int(s[0] - '0') 
	fmt.Println(s_w2)
    // 查找文档得出的方法:错误方法
	// fmt.Println(ByteToInt(s[0]))
}

/**
* 这个是我理解错误,这个是错误的,错误的!!!
*/
// func ByteToInt(bys byte) int {
// 	temp := make([]byte, 1)
// 	temp[0] = bys
//     bytebuff := bytes.NewBuffer(temp)
//     var data int64
//     binary.Read(bytebuff, binary.BigEndian, &data)
//     return int(data)
// }

为什么删除呢,因为我最初错误的理解为一个byte字节通过二进制操作可转换为int类型,并非如此。在我借鉴的程序中,ByteToInt的形参并非是一个byte,而是[]byte,即多个byte才能够转换为一个int才对,而'2',ASCII码0011 0010转换为整数2,从本质上说,确实为'2'与'0'的差值。

代码中涉及到关于大小端模式:大端模式,数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。而小端模式则是数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。初学的我们不要纠结这些细节,暂时只需要记住“通常,golang中采用的是大端模式”

比如对于数据:0x12345678,从高字节到低字节为:12345678,从低字节到高字节为:78563412。 按照大端模式从低位buf[0]到高位buf[3]则应该为: 12, 34, 56, 78。 按照小端模式从低位buf[0]到高位buf[3]则应该为: 78,56,34,12。

go语言中大小端模式的个人理解

  1. Go中如何表示数字边界:在整数反转中我们详细介绍了Go中的整数类型,以及如何表示32位整数的数字边界。
const MAX_UINT32 = ^uint32(0)
const MIN_UINT32 = 0
// 最大无符号去掉符号位
const MAX_INT32 = int(MAX_UINT32 >> 1)
const MIN_INT32 = - MAX_INT32 - 1
  1. Go中如何使用正则表达式:关于正则表达式详细可参考Google关于正则表达式的RE2语法文档,以及维基百科正则表达式。Go常用的正则方法可参考掘金文章:Go正则表达式使用,示例代码如下
package main
import (
    "fmt"
    "regexp"
)
func main() {
    buf := "weialfidnd8930232jdjfkdjka09232"
    //解析正则表达式,如果成功返回解释器
    reg1 := regexp.MustCompile(`\d.\d`)
    if reg1 == nil {
        fmt.Println("regexp err")
        return
    }

    //提取,第二个参数表示只查找前n个匹配项,如果n<0, 则查找所有匹配内容
    result1 := reg1.FindAllStringSubmatch(buf, -1)
	// result1 := reg1.FindAllString(buf, -1)
	fmt.Println("result1 = ", result1)
	for _, v := range result1 {
		fmt.Println("find = ", v[0])
	}

	// 第二个参数返回的error,无错误时返回nil
	match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
    fmt.Println(match)
}

个人认为,能够熟练使用正则表达式,网络API,处理集合与列表,是“精通一门语言”的前提,Java也应该包括熟练使用stream库。

查看力扣官网给出的有限状态自动机来解决,也容易理解,不多阐述。我们给出Go语言的正则表达式的解法,参考了力扣中的一个python解法:

import (
	"regexp"
	"strings"
)

const MAX_UINT32 = ^uint32(0)	
	const MIN_UINT32 = 0
	// 最大无符号去掉符号位
	const MAX_INT32 = int(MAX_UINT32 >> 1)
	const MIN_INT32 = - MAX_INT32 - 1


func stringToInt(s string) int  {

	i, num := 0, 0
	if s[0] == '-' || s[0] == '+' {
		i = 1
	}

	for ; i < len(s); i++ {
		popNum := int(s[i] - '0')
		if (num > MAX_INT32/10) || (num == MAX_INT32/10 && popNum > 7) || (num < MIN_INT32/10) || (num == MIN_INT32/10 && popNum < -8) {
			if s[0] == '-' {
				return MIN_INT32
			} else {
				return MAX_INT32
			}
		}
		num = num*10 + popNum
	}

	if s[0] == '-' {
		return -num
	} else {
		return num
	}
}


func myAtoi(s string) int {

	// 去除空格
	str := strings.TrimSpace(s)
	//  # 解释器:^表示子串开始,\d表示数字。表示子串以‘+’,‘-’或数字开头并跟后续至少一个数字
	reg1 := regexp.MustCompile(`^[\+\-]?\d+`)
	// 查找第一个匹配上的子串

	numArray := reg1.FindAllStringSubmatch(str, 1)
	if len(numArray) == 0 {
		return 0
	}
	num := stringToInt(numArray[0][0])
	// num = int(*num) #由于返回的是个列表,解包并且转换成整数
	return max(min(num,MAX_INT32), MIN_INT32)    //#返回值
	// return num
}

func min(num1, num2 int) int  {
	if num1 < num2 {
		return num1
	}
	return num2
}

func max(num1, num2 int) int  {
	if num1 < num2 {
		return num2
	}
	return num1
}

代码比想象中复杂o(╥﹏╥)o


Go语言力扣刷题系列文章 |Go主题月

  1. Go语言力扣刷题-两数之和|Go主题月
  2. Go语言力扣刷题-两数相加|Go主题月
  3. Go语言力扣刷题-无重复字符的最长子串|Go主题月
  4. Go语言力扣刷题-寻找两个正序数组的中位数|Go主题月
  5. Go语言力扣刷题-最长回文子串|Go主题月
  6. Go语言力扣刷题-Z字形变换|Go主题月
  7. Go语言力扣刷题-整数反转|Go主题月