数据结构-字符串
字符串(string)
定义及操作
Go中的字符串是一个字节的切片。可以通过将其内容封装在 "" 中来创建字符串。Go中的字符串是Unicode兼容的,并且是UTF-8编码的,每一个字符都用一个或者多个字节表示(当字符为 ASCII 码表上的字符时则占用 1 个字节,其它字符根据需要占用 2-4 个字节)。
UTF-8 是一种被广泛使用的编码格式,是文本文件的标准编码,其中包括 XML 和 JSON 在内也都使用该编码。由于该编码对占用字节长度的不定性,在Go语言中字符串也可能根据需要占用 1 至 4 个字节,这与其它编程语言如java,python,c++等不同(Java 始终使用 2 个字节)。Go语言这样做不仅减少了内存和硬盘空间占用,同时也不用像其它语言那样需要对使用 UTF-8 字符集的文本进行编码和解码。
基本使用:
func main() {
name := "Hello World"
fmt.Println(name)
}
访问字符串中单个字节:
func main() {
s := "Hello World"
for i:= 0; i < len(s); i++ {
fmt.Printf("%d ", s[i]) // 十进制形式输出
}
fmt.Printf("\n")
for i:= 0; i < len(s); i++ {
fmt.Printf("%c ",s[i]) // 字符形式输出
}
}
比较函数:
在golang中字符串之间是可以用<,>,==,!=,<=,>= 进行比较的
可变性:
golang中的字符串是不可变的,但支持 + 级联操作和 += 追加操作
text1 := "Hello" + " GoLang"
text1 += " Java"
fmt.Println(text1) // 输出 Hello GoLang Java
注意,作为不可变字符串在修改字符串中字符时时间复杂度较高
转义字符:
符串中可以使用转义字符来实现换行、缩进等效果,常用的转义字符包括:
\n:换行符\r:回车符\t:tab 键\u或\U:Unicode 字符\\:反斜杠自身
相关包:
-
strings
-
strconv --- 字符串格式转换
字符索引:
与数组相同,采用标准索引法,但注意获取字符串中某个字节的地址属于非法行为,例如&str[1]
练习
二进制求和
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例 1:
输入: a = "11", b = "1"
输出: "100"
示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
提示:
- 每个字符串仅由字符
'0'或'1'组成。 1 <= a.length, b.length <= 10^4- 字符串如果不是
"0",就都不含前导零。 - 在Golang中,一个
数字字符与字符 0相减,得到的值就是这个数字字符的数值,即‘9’ - ‘0’ = 9
解:
func addBinary(a string, b string) string {
/*
算法没有使用 strconv.Itoa(int->string)与 strconv.Atoi(string -> int)
二进制求和,逐位计算,字符串从尾部向前遍历相加,
同时存储进位carry,将其累加到下一次计算。
*/
// 相加字符串
result := ""
// 存储进位
carry := 0
// 字符串长度
i, j := len(a)-1, len(b)-1
// 遍历两个字符串
for i >= 0 || j >= 0 {
t1, t2 := 0, 0 // 每次循环开始都置零(考虑到相加字符串长度不同)
// 将a,b中字符转换为数值
if i >= 0 {
t1 = int(a[i] - '0')
}
if j >= 0 {
t2 = int(b[j] - '0')
}
// 当前位相加 + 进位
sum := t1 + t2 + carry
// 按位相加的4种情况
switch sum {
case 3:
carry = 1
result = "1" + result
case 2:
carry = 1
result = "0" + result
case 1:
carry = 0
result = "1" + result
case 0:
carry = 0
result = "0" + result
}
// 每次遍历后,字符串长度-1
i--
j--
}
// 若遍历完字符串后依旧存在进位
if carry == 1 {
result = "1" + result
}
return result
}
实现 strStr()
实现strStr函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba"
输出: -1
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的strstr()以及 Java的indexOf()定义相符。
func strStr(haystack string, needle string) int {
/*
沿着字符换逐步移动滑动haystack字符串,将haystack内的子串与 needle 字符串比较
*/
h, n := len(haystack), len(needle)
for i := 0; i < h-n+1; i++ {
if haystack[i:i+n] == needle {
return i
}
}
return -1
}
最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
func longestCommonPrefix(strs []string) string {
/*
以第一个字符串为基准,依次在所有字符串进行比较,
比较时如果基准元素被字符串包含并在其首位(strings.Index(str,prefix) == 0),
则更新基准元素,直到所有的字符串拥有相同的基准元素,即最大前缀
*/
// 如果输入切片为空,则返回空字符串
if len(strs) < 1 {
return ""
}
// prefix为切片中首个字符串
prefix := strs[0]
// 遍历输入切片,str为字符串
for _, str := range strs {
// 判断在prefix在str中首次出现的位置,若=0,则prefix为最大前缀
for strings.Index(str, prefix) != 0 {
// 如果prefix长度减为0,证明各字符串没有相同前缀,返回空字符串
if len(prefix) == 0 {
return ""
}
// 删去尾部字符
prefix = prefix[:len(prefix)-1]
}
}
return prefix
}

浙公网安备 33010602011771号