我正在尝试检查文本文件是否包含某个单词。但是,即使字符串中的某些字母也会返回true。例如:
输入的字符串:gdo
找到计算机:kin gdo m
var word = strings.ToLower(string(a))
// read the whole file at once
b, err := ioutil.ReadFile("words.txt")
if err != nil {
panic(err)
}
s := string(b)
// Check whether s contains substring text
if strings.Contains(s, word) == true {
fmt.Println("this is a word ", word)
} else {
fmt.Println("this isn't a word ", word)
}
答案 0 :(得分:0)
strings.Contains()
报告字符串中是否包含子字符串。它不会检查单词边界,因此您所期望的行为是可以预期的。
您想要的是将每个单词识别为一个单词。已经有strings.Fields()
函数可以通过空格分割文本。一个简单的实现可能看起来像:
func main() {
source := `
hello
world
kingdom
foo
`
check := "gdo"
words := strings.Fields(strings.ToLower(source))
for _, w := range words {
if w == check {
fmt.Println("found", check)
break
}
}
}
我使用strings.Fields()
是因为我不知道您的words.txt
文件的内容。如果您知道分隔符始终是单个换行符或单个空格,则也可以使用strings.Split()
。
如果您要进行大量查找,这将很慢,因为它会为每个查找循环遍历words
数组。一种更快的方法是将其存储在地图中:
func main() {
source := `
hello
world
kingdom
foo
`
check := "gdo"
words := make(map[string]struct{})
for _, w := range strings.Fields(strings.ToLower(source)) {
words[w] = struct{}{}
}
_, ok := words[check]
if ok {
fmt.Println("found", check)
}
}
如果仅执行一次查找,则第一种方法会更快(因为此map方法将始终需要至少循环一次整个数组才能构建地图)。
我使用了看起来有些奇怪的空结构作为映射值,因为它不会分配任何内存(words[w] = true
会分配)。
答案 1 :(得分:0)
这是一个简单的解决方案。您可以将s转换为字符串数组。然后遍历数组以检查它是否包含单词。
var word = strings.ToLower(string(a))
// read the whole file at once
b, err := ioutil.ReadFile("words.txt")
if err != nil {
panic(err)
}
s := string(b)
// convert the string into a string array (words)
content := strings.Split(s, " ")
contains := false
for i:=0 ; i<len(content) ; i++ {
if content[i] == word {
contains = true
break
}
}
// Check whether s contains substring text
if contains {
fmt.Println("this is a word ", word)
} else {
fmt.Println("this isn't a word ", word)
}
无需复杂化。祝你有美好的一天:)
答案 2 :(得分:0)
如果不区分大小写,则可以使用opened a ticket包中的suffixArray。
b, err := ioutil.ReadFile("words.txt")
if err != nil {
panic(err)
}
word := "gdo"
suffix := suffixarray.New(b) // accepts []byte
indexList := suffix.Lookup([]byte(word), -1)
if len(indexList) == 0 {
fmt.Println("this isn't a word ", word)
return
}
s := string(b)
// loop through the word indices
for _, idx := range indexList {
fmt.Println("this is a word ", string(s[idx:idx+len(word)]))
}