go语言源码——strings

2 篇文章 0 订阅

strings.Contains

输入: 原字符 判断的字符
返回: true or false

// Contains reports whether substr is within s.
func Contains(s, substr string) bool {
		//判断substr在s中出现的下表位置
        return Index(s, substr) >= 0
}

strings.Index

输入: 源 子串
返回 substr在s中出现第一次的下标值 int

// Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
func Index(s, substr string) int {
		//获取子串的长度
        n := len(substr)
        switch {
        case n == 0:
                return 0
        //n为1,说明所传入的子串字符为单字符,可转入一个字符在字符串出现的首次位置
        case n == 1:
                return IndexByte(s, substr[0])
        //如果长度和源字符长度相同,则可通过判断两个字符是否相等,相等则返回0,否则为-1
        case n == len(s):
                if substr == s {
                        return 0
                }
                return -1
        //所确定的子串字符长度是够超出原字符串
        case n > len(s):
                return -1
        //判断获取的位置:子串在原字符的位置 可想到的方式为:游标卡尺的方式()
        case n <= bytealg.MaxLen:

                if len(s) <= bytealg.MaxBruteForce {
                        return bytealg.IndexString(s, substr)
                }
                c0 := substr[0]
                c1 := substr[1]
                i := 0
                t := len(s) - n + 1
                fails := 0
                for i < t {
                        if s[i] != c0 {

                                o := IndexByte(s[i:t], c0)
                                if o < 0 {
                                        return -1
                                }
                                i += o
                        }
                        if s[i+1] == c1 && s[i:i+n] == substr {
                                return i
                        }
                        fails++
                        i++

                        if fails > bytealg.Cutover(i) {
                                r := bytealg.IndexString(s[i:], substr)
                                if r >= 0 {
                                        return r + i
                                }
                                return -1
                        }
                }
                return -1
        }
        c0 := substr[0]
        c1 := substr[1]
        i := 0
        t := len(s) - n + 1
        fails := 0
        for i < t {
                if s[i] != c0 {
                        o := IndexByte(s[i:t], c0)
                        if o < 0 {
                                return -1
                        }
                        i += o
                }
                if s[i+1] == c1 && s[i:i+n] == substr {
                        return i
                }
                i++
                fails++
                if fails >= 4+i>>4 && i < t {

                        j := indexRabinKarp(s[i:], substr)
                        if j < 0 {
                                return -1
                        }
                        return i + j
                }
        }
        return -1
}

strings.Split

输入:原字符串 需要分割的字符
返回:[]string

// Split slices s into all substrings separated by sep and returns a slice of
// the substrings between those separators.
//如果原字符串不包含需要切割的字符,且seq不为空,将返回长度为1且元素为s的切片
// If s does not contain sep and sep is not empty, Split returns a
// slice of length 1 whose only element is s.
//如果seq为空,则将返回一个空切片
// If sep is empty, Split splits after each UTF-8 sequence. If both s
// and sep are empty, Split returns an empty slice.
//
// It is equivalent to SplitN with a count of -1.
func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }

// Generic split: splits after each instance of sep,
//在子数组中包含 sep 的 sepSave 字节
// including sepSave bytes of sep in the subarrays.
func genSplit(s, sep string, sepSave, n int) []string {
        if n == 0 {
                return nil
        }
        if sep == "" {
                return explode(s, n)
        }
        if n < 0 {
       			//创建已存在seq+1的数组
                n = Count(s, sep) + 1
        }

        a := make([]string, n)
        //遍历去寻找seq存在的位置,需要n--
        n--
        i := 0
        for i < n {
                m := Index(s, sep)
                if m < 0 {
                        break
                }
                //获取seq位置之前的字符
                a[i] = s[:m+sepSave]
                //s为已经获得的之后的字符
                s = s[m+len(sep):]
                i++
        }
        a[i] = s
        return a[:i+1]
}

strings.Join

输入:字符串数组 需要连接的字符
返回: string

// Join concatenates the elements of a to create a single string. The separator string
// sep is placed between elements in the resulting string.
func Join(a []string, sep string) string {
		//判断数组长度,如果长度为0 返回空字符或者长度为1 返回数组本身
        switch len(a) {
        case 0:
                return ""
        case 1:
                return a[0]
        }
        n := len(sep) * (len(a) - 1)
        for i := 0; i < len(a); i++ {
                n += len(a[i])
        }
		//Builder:结构体
        var b Builder
        //长度增长设置
        b.Grow(n)
        b.WriteString(a[0])
        for _, s := range a[1:] {
                b.WriteString(sep)
                b.WriteString(s)
        }
        return b.String()
}

持续更新…

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值