Go语言—字符串操作/转换
程序员文章站
2022-03-21 18:16:03
...
字符串在开发中经常用到,包括用户的输入,数据库读取的数据等,我们经常需要对字符串进行分割、连接、转换等操作,我们可以通过Go标准库中的strings和strconv两个包中的函数进行相应的操作。
字符串操作常用方法总结
package main
import (
"fmt"
"strings"
)
func main() {
// func Contains(s, substr string) bool
// Contains 字符串s中是否包含substr,返回bool值
fmt.Println(strings.Contains("seafood", "foo"))
fmt.Println(strings.Contains("seafood", "bar"))
// func Join(a []string, sep string) string
// Join 字符串连接,将slice a通过sep连接
fmt.Println(strings.Join([]string{"I", "Love", "You"}, "-->"))
// func Index(s, substr string) int
// Index 在字符串s中查找substr所在的位置,返回位置值,找不到返回-1
fmt.Println(strings.Index("zhaoxu", "ox"))
fmt.Println(strings.Index("zhaoxu", "oocc"))
// func Repeat(s string, count int) string
// Repeat 重复s,count次,返回重复的字符串
fmt.Println(strings.Repeat("Love", 5))
// func Replace(s, old, new string, n int) string
// Replace 在字符串s中,把old字符串替换成new字符串,替换n次(n<0表示全部替换),最后返回替换后的字符串
fmt.Println(strings.Replace("ccoo ccoo ccoo", "co", "xo", 2))
fmt.Println(strings.Replace("ccoo ccoo ccoo", "co", "xo", -1))
// Split(s, sep string) []string
// Split 把字符串按照sep分割,返回分割后的slice
fmt.Println(strings.Split("I love you", " "))
fmt.Println(strings.Split(" zxy ", ""))
// Trim(s string, cutset string) string
// Trim 将s字符串的首尾去除cutset指定的字符串
fmt.Println(strings.Trim("!!!!!I Love you!!!!!", "!"))
// func Fields(s string) []string
// Fields 去除s字符串的空格字符,并按照空格分割返回slice
fmt.Println(strings.Fields(" I love you ! "))
}
// 运行结果
// true
// false
// I-->Love-->You
// 3
// -1
// LoveLoveLoveLoveLove
// cxoo cxoo ccoo
// cxoo cxoo cxoo
// [I love you]
// [ z x y ]
// I Love you
// [I love you !]
字符串转换常用方法总结
package main
import (
"fmt"
"strconv"
)
func checkError(e error) {
if e != nil {
fmt.Println(e)
}
}
func main() {
// Append 系列函数将整数等转换成字符串后,添加到现有的字节数组中
str := make([]byte, 0, 100)
// func AppendInt(dst []byte, i int64, base int) []byte
str = strconv.AppendInt(str, 123, 10)
fmt.Println(string(str))
// func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte
str = strconv.AppendFloat(str, 3.141592, 'f', 4, 64) // 'f'换成'e'便是科学计数法
fmt.Println(string(str))
// func AppendBool(dst []byte, b bool) []byte
str = strconv.AppendBool(str, false) // <==> append(str, "false"...)
fmt.Println(string(str))
// func AppendQuote(dst []byte, s string) []byte
str = strconv.AppendQuote(str, "hello world") // 包括双引号
fmt.Println(string(str))
// func AppendQuoteRune(dst []byte, r rune) []byte
str = strconv.AppendQuoteRune(str, '当')
fmt.Println(string(str))
// Format 系列函数把其他类型转换成字符串
// func FormatBool(b bool) string
a := strconv.FormatBool(true) // bool类型转换成字符串
// func FormatInt(i int64, base int) string
b := strconv.FormatInt(10, 2) // 整数10转换成二进制的字符串
// func FormatUint(i uint64, base int) string
c := strconv.FormatUint(123, 10) // 无符号intint类型转换成十进制的字符串
// func Itoa(i int) string
d := strconv.Itoa(10) // <==> strconv.FormatInt(int64(i), 10)
fmt.Println(a, b, c, d)
// Parse 系列函数把字符串转换为其他类型
// func ParseBool(str string) (bool, error)
aa, err := strconv.ParseBool("false")
checkError(err)
// func ParseFloat(s string, bitSize int) (float64, error)
bb, err := strconv.ParseFloat("123.23", 64)
checkError(err)
// func ParseInt(s string, base int, bitSize int) (i int64, err error)
cc, err := strconv.ParseInt("1011", 2, 64)
checkError(err)
// func ParseUint(s string, base int, bitSize int) (uint64, error)
dd, err := strconv.ParseUint("12345", 10, 64)
checkError(err)
// func Atoi(s string) (int, error)
ee, err := strconv.Atoi("1023") // <==> ParseInt(s, 10, 0)
checkError(err)
fmt.Println(aa, bb, cc, dd, ee) //false 123.23 11 12345 1023
}
// 运行结果
// 123
// 1233.1416
// 1233.1416false
// 1233.1416false"hello world"
// 1233.1416false"hello world"'当'
// true 1010 123 10
// false 123.23 11 12345 1023
在LeetCode找了两个题目简单的练练手
package main
import (
"fmt"
"strconv"
"strings"
)
/*
【字符串操作】
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
*/
func lengthOfLongestSubstring(s string) int {
var Length int // 最大长度
var s1 string // 不含重复字符的字符串
// 双指针想法,检查s中的字符是否在s1中,如果不在,则记录在s1中并计算长度,否则左指针定位在重复字符的位置
for left, right := 0, 0; right < len(s); right++ {
if index := strings.IndexByte(s1, s[right]); index != -1 {
left += index + 1
}
s1 = s[left : right+1]
if len(s1) > Length {
Length = len(s1)
}
}
return Length
}
/*
【本来是想用字符串转换做的,但是对于较大数会出现溢出的情况!!】
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
解题思路:
9 8
× 2 1
-------------
(9)(8) <---- 第1趟: 98×1的每一位结果
(18)(16) <---- 第2趟: 98×2的每一位结果
-------------
(18)(25)(8) <---- 这里就是相对位的和,还没有累加进位
*/
// BigMulti 大数相乘
func BigMulti(a, b string) string {
if a == "0" || b == "0" {
return "0"
}
// string转换成[]byte,容易取得相应位上的具体值
bsi := []byte(a) // 强制类型转换
bsj := []byte(b)
//两数相乘,结果位数不会超过两乘数位数和,即temp的长度只可能为 len(num1)+len(num2) 或 len(num1)+len(num2)-1
temp := make([]int, len(bsi)+len(bsj)) // [0 0 0 ... 0 0]
// 选最大的,免得位数不够
for i := 0; i < len(bsi); i++ {
for j := 0; j < len(bsj); j++ {
// 对应每个位上的乘积,直接累加存入 temp 中相应的位置
temp[i+j+1] += int(bsi[i]-'0') * int(bsj[j]-'0')
}
}
// 统一处理进位
for i := len(temp) - 1; i > 0; i-- {
temp[i-1] += temp[i] / 10 // 取整:对该结果进位(进到前一位)
temp[i] = temp[i] % 10 // 取余:对个位数保留
}
// a 和 b 较小的时候,temp的首位为0
// 为避免输出结果以0开头,需要去掉temp的0首位
if temp[0] == 0 {
temp = temp[1:]
}
// 转换结果:将[]int类型的temp转成[]byte类型,
// 因为在未处理进位的情况下,temp每位的结果可能超过255(go中,byte类型实为uint8,最大为255),
// 所以temp选用[]int类型
// 但在处理完进位后,不再会出现溢出
res := make([]byte, len(temp)) //res 存放最终结果的ASCII码
for i := 0; i < len(temp); i++ {
res[i] = byte(temp[i] + '0')
}
return string(res)
}
func main() {
s := "abcabcbb"
fmt.Println(s[0:0] == "")
n := lengthOfLongestSubstring(s)
fmt.Println(n)
a := "498828660196"
b := "840477629533"
res := BigMulti(a, b)
fmt.Println(res)
// 字符串相乘(小数),使用字符串转换即可
str1 := "98"
str2 := "21"
n1, _ := strconv.ParseInt(str1, 10, 64)
n2, _ := strconv.ParseInt(str2, 10, 64)
result := n1 * n2
res = strconv.FormatInt(result, 10)
fmt.Println(res)
}
// 运行结果:
// 3
// 419254329864656431168468
// 2058
当然,大数相乘,有一种投机的方式,使用Python的内置函数eval,一行代码就可解决…
class Solution(object):
def multiply(self, num1, num2):
"""
:type num1: str
:type num2: str
:rtype: str
"""
return str(eval(num1 + "*" + num2))
但是执行用时和内存消耗,跟Go语言没法比。