【问题标题】:Find all occurrences of strings in a []byte slice在 []byte 切片中查找所有出现的字符串
【发布时间】:2019-03-11 15:54:43
【问题描述】:

我想查找包含在字节数组中的所有字符串的索引。

func findAllOccurrences(data []byte, searches []string) map[string][]int {
    var results map[string][]int

    for _, search := range searches {
        firstMatch = bytes.Index(data, []byte(search))
        results[search] = append(results[search], firstMatch)

        // How do I find subsequent the rest of the matches?
    }

    return results
}

找到第一个Index() 很简单,但是我怎样才能以惯用的方式找到所有个而不消耗不必要的内存?

【问题讨论】:

  • 我看到还有一个名为LastIndex 的方法,你可以使用它,并为下一次迭代不断减小字节数组的大小。它返回最后一个匹配的索引,所以你总是有一个少一个的数组,你可以保留一个计数或匹配任何东西。

标签: string go byte


【解决方案1】:

正如ishaan's answer 所示,您可以将data 分配给每次搜索的另一个切片变量,然后在每次匹配后重新切片该变量。分配只复制长度、容量和指针。重新切片只会改变切片变量的长度和指针:它不会影响底层数组,也不是新的分配。我添加了这个答案以澄清内存效率,并证明您仍然可以使用 bytes.Index 并且您可以将其用作传统 for 循环中的起点和增量器:

package main

import (
    "bytes"
    "fmt"
)

func findAllOccurrences(data []byte, searches []string) map[string][]int {
    results := make(map[string][]int)
    for _, search := range searches {
        searchData := data
        term := []byte(search)
        for x, d := bytes.Index(searchData, term), 0; x > -1; x, d = bytes.Index(searchData, term), d+x+1 {
            results[search] = append(results[search], x+d)
            searchData = searchData[x+1 : len(searchData)]
        }
    }
    return results
}

func main() {
    fmt.Println(findAllOccurrences([]byte(`foo foo hey foo`), []string{`foo`, `hey`, ` `}))
}

打印

map[foo:[0 4 12] hey:[8]  :[3 7 11]]

【讨论】:

    【解决方案2】:

    好的,这是我的评论中的解决方案,通过阅读LastIndex 而不是首先阅读,不确定它是否有效,但这确实有效,您只需按倒序获取索引,您可以随时修复阅读时间。

    package main
    
    import (
        "fmt"
        "bytes"
    )
    
    func main() {
        str1:= "foobarfoobarfoobarfoobarfoofoobar"
        arr := make([]string, 2)
        arr[0]="foo"
        arr[1]="bar"
        res:=findAllOccurrences([]byte(str1), arr)
        fmt.Println(res)
    }
    
    
    func findAllOccurrences(data []byte, searches []string) map[string][]int {
        results:= make(map[string][]int,0)
    
        for _, search := range searches {
        index := len(data)
        tmp:=data
        for true{
            match := bytes.LastIndex(tmp[0:index], []byte(search))
            if match==-1{
                break
            }else{
                index=match
                results[search]=append(results[search], match)
                }
            }
        }
    
        return results
    }
    

    希望这会有所帮助! :)

    【讨论】:

      猜你喜欢
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-23
      • 2013-03-22
      • 1970-01-01
      相关资源
      最近更新 更多