Найти все вхождения строк в срезе байта [] - PullRequest
0 голосов
/ 06 октября 2018

Я хочу найти индекс всех вхождений строки, содержащейся в байтовом массиве.

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() достаточно просто, но как мне найти all из них идиоматическим способом без использования ненужной памяти?

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

Как показывает ответ ishaan , вы можете назначить 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`, ` `}))
}

print

map[foo:[0 4 12] hey:[8]  :[3 7 11]]
0 голосов
/ 06 октября 2018

Хорошо, вот решение из моего комментария, читая 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
}

Надеюсь, это поможет!:)

...