В приведенном вами простом тестовом примере ваш алгоритм работает.Ваш алгоритм не очень хорошо работает с реальным текстом.
Рассмотрим мой простой алгоритм:
func maxSentenceWords(s string) int {
maxWords, nWords := 0, 0
inWord := false
for _, r := range s {
switch r {
case '.', '?', '!':
inWord = false
if maxWords < nWords {
maxWords = nWords
}
nWords = 0
default:
if unicode.IsSpace(r) {
inWord = false
} else if inWord == false {
inWord = true
nWords++
}
}
if maxWords < nWords {
maxWords = nWords
}
}
return maxWords
}
Детская площадка: https://play.golang.org/p/OD8jNW1hyAa
Он проходит ваш простойтестовое задание.Короткий бенчмарк (Lorem Ipsum) работает очень быстро, а длинный бенчмарк (Шекспир) работает быстро
$ go test words_test.go -run=PeterSO -v -bench=PeterSO -benchmem -timeout=5m
=== RUN TestPeterSO
--- PASS: TestPeterSO (0.00s)
BenchmarkPeterSOL-4 300000 4027 ns/op 0 B/op 0 allocs/op
BenchmarkPeterSOS-4 20 54084832 ns/op 0 B/op 0 allocs/op
$
Рассмотрим ваш сложный алгоритм:
func MaxWordsInSentences(S string) (result int) {
r, _ := regexp.Compile("[.||?||!]")
count := strings.Count(S, ".") + strings.Count(S, "!") + strings.Count(S, "?") // Total sentaces
for i := 0; i < count; i++ {
sentence := r.Split(S, count)[i]
splitSentence := strings.Split(sentence, " ")
var R []string
for _, str := range splitSentence {
if str != "" {
R = append(R, str)
}
}
if len(R) > result {
result = len(R)
}
}
return
}
Детская площадка: https://play.golang.org/p/MCj-XxEid73
Он проходит ваш простой тест.Короткий бенчмарк (Lorem Ipsum) работает медленно, а длинный бенчмарк (Шекспир) работает очень долго (убит через 5 минут).
$ go test words_test.go -run=Ljubon -v -bench=Ljubon -benchmem -timeout=5m
=== RUN TestLjubon
--- PASS: TestLjubon (0.00s)
BenchmarkLjubonL-4 20000 78623 ns/op 6984 B/op 62 allocs/op
*** Test killed with quit: ran too long (6m0s).
$
test words_test.go
:
package main
import (
"fmt"
"io/ioutil"
"regexp"
"strings"
"testing"
"unicode"
)
var sentences = "One two three four five six seven eight. One two? One two three four five six seven eight nine? One two three! One two three four."
var loremipsum = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
`
var shakespeare = func() string {
// The Complete Works of William Shakespeare by William Shakespeare
// http://www.gutenberg.org/files/100/100-0.txt
data, err := ioutil.ReadFile(`/home/peter/shakespeare.100-0.txt`)
if err != nil {
panic(err)
}
return string(data)
}()
func maxSentenceWords(s string) int {
maxWords, nWords := 0, 0
inWord := false
for _, r := range s {
switch r {
case '.', '?', '!':
inWord = false
if maxWords < nWords {
maxWords = nWords
}
nWords = 0
default:
if unicode.IsSpace(r) {
inWord = false
} else if inWord == false {
inWord = true
nWords++
}
}
if maxWords < nWords {
maxWords = nWords
}
}
return maxWords
}
func TestPeterSO(t *testing.T) {
want := 9
got := maxSentenceWords(sentences)
if got != want {
t.Errorf("want %d; got %d", want, got)
}
}
func BenchmarkPeterSOL(b *testing.B) {
for N := 0; N < b.N; N++ {
maxSentenceWords(loremipsum)
}
}
func BenchmarkPeterSOS(b *testing.B) {
for N := 0; N < b.N; N++ {
maxSentenceWords(shakespeare)
}
}
// MaxWordsInSentences - return max words in one sentences
func MaxWordsInSentences(S string) (result int) {
r, _ := regexp.Compile("[.||?||!]")
count := strings.Count(S, ".") + strings.Count(S, "!") + strings.Count(S, "?") // Total sentaces
for i := 0; i < count; i++ {
sentence := r.Split(S, count)[i]
splitSentence := strings.Split(sentence, " ")
var R []string
for _, str := range splitSentence {
if str != "" {
R = append(R, str)
}
}
if len(R) > result {
result = len(R)
}
}
return
}
func TestLjubon(t *testing.T) {
want := 9
got := MaxWordsInSentences(sentences)
if got != want {
t.Errorf("want %d; got %d", want, got)
}
}
func BenchmarkLjubonL(b *testing.B) {
for N := 0; N < b.N; N++ {
MaxWordsInSentences(loremipsum)
}
}
func BenchmarkLjubonS(b *testing.B) {
for N := 0; N < b.N; N++ {
MaxWordsInSentences(shakespeare)
}
}
func main() {
s := "One two three four five six seven eight. One two? One two three four five six seven eight nine? One two three! One two three four."
max := maxSentenceWords(s) // 9
fmt.Println(max)
s = "One two three! One two three four"
max = maxSentenceWords(s) // 4
fmt.Println(max)
s = loremipsum
max = maxSentenceWords(s)
fmt.Println(max)
}
Я называю это законом инструмента, и его можно сформулировать следующим образом: Дайте маленькому мальчику молот, и он обнаружит, что все, с чем он сталкивается, нуждается в ударе.
Авраам Каплан, «Проведение расследования: методология поведенческих наук», 1964, стр. 28.
Является ли Go regexp
упаковкой вашего молотка, чтобы загнать любого и всехтекст