在字符串中搜索特定子字符串时出现的问题

huangapple go评论73阅读模式
英文:

problems when searching for certain substrings in a string

问题

代码无法正常工作。

我需要检查给定字符串中包含的所有子字符串,并满足以下两个要求:

  • 长度至少为3个字符;
  • 开始和结束字符相同。

输出应包括这些子字符串及其出现次数。

当输入abbabbaabcacba时没有问题,但当输入eabcacf时开始出现错误。实际上,它重新读取了cac子字符串并将其计数了两次,所以我尝试通过检查该子字符串的位置(strings.Index函数)并在之后修剪字符串来解决这个问题,这样,如果需要重新读取子字符串,那肯定是由于出现次数而不是错误...至少我是这么想的。

...因为当输入eabbcabcbf时,即使在之前的修复之后,它仍然重新读取了cabc,这是因为cabc出现了两次,但不是连续的,所以previous/current的方法不起作用,必须使用previous2/previous1/current的方法来检查倒数第三个子字符串,但我认为这样做总会出现错误,并且修复将变得不可能。

也许问题是由于在代码部分中找到所有子字符串的可能错误实现,但我无法弄清楚如何修复它。

我附上了代码和输出。

希望有人能帮助我!

代码
(我添加了一些*fmt.Println()*函数来打印切片并进行调试)

package main

import (
	"fmt"
	"os"
	"strings"
)

func main() {
	string1 := os.Args[1]
	count1 := 0
	count2 := 0
	count3 := 0
	var substring1, substring2, start1, previous1, output1 string
	var slice1, slice2, slice5 []string
	var slice3, slice4 []int
	var position1, saved1 int
	var check1 bool
	dict1 := make(map[string]int)
	for index1 := 3; index1 <= len(string1); index1++ {
		for index2 := 0; index2 <= len(string1)-3; index2++ {
			for _, value3 := range string1[index2:] {
				count1++
				substring1 += fmt.Sprintf("%s", string(value3))
				if count1 == index1 {
					slice1 = append(slice1, substring1)
					count1 = 0
					substring1 = ""
				}
			}
			count1 = 0
			substring1 = ""
		}
	}
	fmt.Println(slice1)
	for _, value4 := range slice1 {
		substring2 = value4
		for index5, value5 := range substring2 {
			if index5 == 0 {
				start1 = string(value5)
			}
			if (index5 == len(substring2)-1) && (string(value5) == start1) {
				slice2 = append(slice2, substring2)
			}
		}
	}
	fmt.Println(slice2)
	for index6, value6 := range slice2 {
		if index6 == 0 {
			previous1 = value6
		}
		if (value6 == previous1) && (index6 == 0) {
			position1 = strings.Index(string1[position1:], value6)
			saved1 = position1
			slice3 = append(slice3, position1)
		} else if (value6 == previous1) && (index6 != 0) {
			position1 = strings.Index(string1[saved1+1:], value6)
			slice3 = append(slice3, position1)
		} else if value6 != previous1 {
			position1 = 0
			position1 = strings.Index(string1[position1:], value6)
			saved1 = position1
			slice3 = append(slice3, position1)
		}
		previous1 = value6
	}
	fmt.Println(slice3)
	for index7, value7 := range slice3 {
		if value7 == -1 {
			slice4 = append(slice4, index7)
		}
	}
	fmt.Println(slice4)
	if len(slice4) > 0 {
		for index8, value8 := range slice2 {
			for _, value9 := range slice4 {
				if index8 != value9 {
					check1 = false
				} else {
					check1 = true
					break
				}
			}
			if check1 == false {
				slice5 = append(slice5, value8)
			}
		}
		fmt.Println(slice5)
		for _, value10 := range slice5 {
			dict1[value10] = dict1[value10] + 1
		}
		for range dict1 {
			count2++
		}
		for key1, item1 := range dict1 {
			count3++
			if count3 != count2 {
				output1 += fmt.Sprintf("%s -> Occorrenze: %d\n", key1, item1)
			} else {
				output1 += fmt.Sprintf("%s -> Occorrenze: %d", key1, item1)
			}
		}
		fmt.Println(output1)
	} else {
		for _, value8 := range slice2 {
			dict1[value8] = dict1[value8] + 1
		}
		for range dict1 {
			count2++
		}
		for key1, quantity1 := range dict1 {
			count3++
			if count3 != count2 {
				output1 += fmt.Sprintf("%s -> Occurrences: %d\n", key1, quantity1)
			} else {
				output1 += fmt.Sprintf("%s -> Occurrences: %d", key1, quantity1)
			}
		}
		fmt.Println(output1)
	}
}

输出

正确

$ go run exercise_2.go abbabba
abbabba -> Occurrences: 1
bbabb -> Occurrences: 1
babb -> Occurrences: 1
abba -> Occurrences: 2
bbab -> Occurrences: 1
bab -> Occurrences: 1

正确

$ go run exercise_2.go abcacba
abcacba -> Occurrences: 1
bcacb -> Occurrences: 1
abca -> Occurrences: 1
acba -> Occurrences: 1
cac -> Occurrences: 1

正确,但实际上是错误的,由于错误的方法

$ go run exercise_2.go eabcacf
abca -> Occurrences: 1
cac -> Occurrences: 1

错误

$ go run exercise_2.go eabbcabcbf
bbcabcb -> Occurrences: 1
bcabcb -> Occurrences: 1
abbca -> Occurrences: 1
bbcab -> Occurrences: 1
cabc -> Occurrences: 2
bcab -> Occurrences: 1
bcb -> Occurrences: 1

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

英文:

The code doesn't work properly.

I have to check all the substrings contained in the given string and they have to meet these two requirements:

  • length at least equal to 3 characters;
  • starting and ending with the same character.

The output has to include those substrings and their occurences.

No problems when giving in input abbabba and abcacba, but when giving eabcacf errors start to pop-up. In fact it re-reads the cac substring and counts it another time, so I tried to fix this problem by checking where that substring is located (strings.Index function) and trimming the strings after, so if the substring needs to be re-read another time, it's for sure due to an occurency and not due to an error... at least this is what I thought.

...because when giving eabbcabcbf it re-reads cabc even after the previous fix, this is caused by the fact that cabc appears twice but not consecutively, so the previous/current approach doesn't work, it's necessarily needed a previous2/previous1/current approach to check also the third last substring, but I think that in this way, there will be always an error and fixing will result impossible.

Maybe the problem is caused by a possible wrong implementation of the code part that finds all the substrings at the beginning, but I can't figure it out how to fix it.

I attach the code and the outputs below.

Hope someone can help me!

code
(I put some fmt.Println() functions to print the slices and debug it)

package main
import (
&quot;fmt&quot;
&quot;os&quot;
&quot;strings&quot;
)
func main() {
string1 := os.Args[1]
count1 := 0
count2 := 0
count3 := 0
var substring1, substring2, start1, previous1, output1 string
var slice1, slice2, slice5 []string
var slice3, slice4 []int
var position1, saved1 int
var check1 bool
dict1 := make(map[string]int)
for index1 := 3; index1 &lt;= len(string1); index1++ {
for index2 := 0; index2 &lt;= len(string1)-3; index2++ {
for _, value3 := range string1[index2:] {
count1++
substring1 += fmt.Sprintf(&quot;%s&quot;, string(value3))
if count1 == index1 {
slice1 = append(slice1, substring1)
count1 = 0
substring1 = &quot;&quot;
}
}
count1 = 0
substring1 = &quot;&quot;
}
}
fmt.Println(slice1)
for _, value4 := range slice1 {
substring2 = value4
for index5, value5 := range substring2 {
if index5 == 0 {
start1 = string(value5)
}
if (index5 == len(substring2)-1) &amp;&amp; (string(value5) == start1) {
slice2 = append(slice2, substring2)
}
}
}
fmt.Println(slice2)
for index6, value6 := range slice2 {
if index6 == 0 {
previous1 = value6
}
if (value6 == previous1) &amp;&amp; (index6 == 0) {
position1 = strings.Index(string1[position1:], value6)
saved1 = position1
slice3 = append(slice3, position1)
} else if (value6 == previous1) &amp;&amp; (index6 != 0) {
position1 = strings.Index(string1[saved1+1:], value6)
slice3 = append(slice3, position1)
} else if value6 != previous1 {
position1 = 0
position1 = strings.Index(string1[position1:], value6)
saved1 = position1
slice3 = append(slice3, position1)
}
previous1 = value6
}
fmt.Println(slice3)
for index7, value7 := range slice3 {
if value7 == -1 {
slice4 = append(slice4, index7)
}
}
fmt.Println(slice4)
if len(slice4) &gt; 0 {
for index8, value8 := range slice2 {
for _, value9 := range slice4 {
if index8 != value9 {
check1 = false
} else {
check1 = true
break
}
}
if check1 == false {
slice5 = append(slice5, value8)
}
}
fmt.Println(slice5)
for _, value10 := range slice5 {
dict1[value10] = dict1[value10] + 1
}
for range dict1 {
count2++
}
for key1, item1 := range dict1 {
count3++
if count3 != count2 {
output1 += fmt.Sprintf(&quot;%s -&gt; Occorrenze: %d\n&quot;, key1, item1)
} else {
output1 += fmt.Sprintf(&quot;%s -&gt; Occorrenze: %d&quot;, key1, item1)
}
}
fmt.Println(output1)
} else {
for _, value8 := range slice2 {
dict1[value8] = dict1[value8] + 1
}
for range dict1 {
count2++
}
for key1, quantity1 := range dict1 {
count3++
if count3 != count2 {
output1 += fmt.Sprintf(&quot;%s -&gt; Occurrences: %d\n&quot;, key1, quantity1)
} else {
output1 += fmt.Sprintf(&quot;%s -&gt; Occurrences: %d&quot;, key1, quantity1)
}
}
fmt.Println(output1)
}
}

outputs

correct

$ go run exercise_2.go abbabba
abbabba -&gt; Occurrences: 1
bbabb -&gt; Occurrences: 1
babb -&gt; Occurrences: 1
abba -&gt; Occurrences: 2
bbab -&gt; Occurrences: 1
bab -&gt; Occurrences: 1

correct

$ go run exercise_2.go abcacba
abcacba -&gt; Occurrences: 1
bcacb -&gt; Occurrences: 1
abca -&gt; Occurrences: 1
acba -&gt; Occurrences: 1
cac -&gt; Occurrences: 1

correct but actually incorrect due to bad approach

$ go run exercise_2.go eabcacf
abca -&gt; Occurrences: 1
cac -&gt; Occurrences: 1

incorrect

$ go run exercise_2.go eabbcabcbf
bbcabcb -&gt; Occurrences: 1
bcabcb -&gt; Occurrences: 1
abbca -&gt; Occurrences: 1
bbcab -&gt; Occurrences: 1
cabc -&gt; Occurrences: 2
bcab -&gt; Occurrences: 1
bcb -&gt; Occurrences: 1

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

答案1

得分: 5

检查给定字符串中包含的所有子字符串,并满足以下两个要求:

• 长度至少为3个字符;

• 以相同的字符开头和结尾。

输出应包括这些子字符串及其出现次数。

你的解决方案非常复杂。简化一下。

package main

import "fmt"

func substrings(s string) map[string]int {
    ss := make(map[string]int)
    const k = 3 - 1
    for i := 0; i < len(s)-k; i++ {
        for j := i + k; j < len(s); j++ {
            if s[i] == s[j] {
                ss[s[i:j+1]]++
            }
        }
    }
    return ss
}

func main() {
    fmt.Println(substrings("abbabba"))
    fmt.Println(substrings("abcacba"))
    fmt.Println(substrings("eabcacf"))
    fmt.Println(substrings("eabbcabcbf"))
}

点击此处查看代码运行结果。

输出结果:

map[abba:2 abbabba:1 bab:1 babb:1 bbab:1 bbabb:1]
map[abca:1 abcacba:1 acba:1 bcacb:1 cac:1]
map[abca:1 cac:1]
map[abbca:1 bbcab:1 bbcabcb:1 bcab:1 bcabcb:1 bcb:1 cabc:1]
英文:

> check all the substrings contained in the given string and they have to meet these two requirements:
>
> • length at least equal to 3 characters;
>
> • starting and ending with the same character.
>
> The output has to include those substrings and their occurences.

Your solution is very complicated. Simplify.

package main
import &quot;fmt&quot;
func substrings(s string) map[string]int {
ss := make(map[string]int)
const k = 3 - 1
for i := 0; i &lt; len(s)-k; i++ {
for j := i + k; j &lt; len(s); j++ {
if s[i] == s[j] {
ss
展开收缩
]++ } } } return ss } func main() { fmt.Println(substrings(&quot;abbabba&quot;)) fmt.Println(substrings(&quot;abcacba&quot;)) fmt.Println(substrings(&quot;eabcacf&quot;)) fmt.Println(substrings(&quot;eabbcabcbf&quot;)) }

https://go.dev/play/p/hJMvMSYuqaa

map[abba:2 abbabba:1 bab:1 babb:1 bbab:1 bbabb:1]
map[abca:1 abcacba:1 acba:1 bcacb:1 cac:1]
map[abca:1 cac:1]
map[abbca:1 bbcab:1 bbcabcb:1 bcab:1 bcabcb:1 bcb:1 cabc:1]

答案2

得分: -1

感谢@rocka2q的帮助!这是代码的调整和最终版本。


正确的代码,完整版本(我需要它能正常工作)

package main

import (
	"fmt"
	"os"
)

func main() {
	string1 := os.Args[1]
	map2 := substrings(string1)
	count1 := 0
	count2 := 0
	var output1 string
	for range map2 {
		count1++
	}
	for key1, quantity1 := range map2 {
		count2++
		if count2 != count1 {
			output1 += fmt.Sprintf("%s -> Occurrences: %d\n", key1, quantity1)
		} else {
			output1 += fmt.Sprintf("%s -> Occurrences: %d", key1, quantity1)
		}
	}
	if len(map2) != 0 {
		fmt.Println(output1)
	}
}

func substrings(string1 string) map[string]int {
	map1 := make(map[string]int)
	for index1 := 0; index1 < len(string1)-2; index1++ {
		for index2 := index1 + 2; index2 < len(string1); index2++ {
			if string1[index1] == string1[index2] {
				map1[string1[index1:index2+1]]++
			}
		}
	}
	return map1
}

输出,全部正确

$ go run exercise_2.go abbabba
abbabba -> Occurrences: 1
bbabb -> Occurrences: 1
babb -> Occurrences: 1
abba -> Occurrences: 2
bbab -> Occurrences: 1
bab -> Occurrences: 1
$ go run exercise_2.go abcacba
abcacba -> Occurrences: 1
bcacb -> Occurrences: 1
abca -> Occurrences: 1
acba -> Occurrences: 1
cac -> Occurrences: 1
$ go run exercise_2.go eabcacf
abca -> Occurrences: 1
cac -> Occurrences: 1
$ go run exercise_2.go eabbcabcbf
bbcabcb -> Occurrences: 1
bcabcb -> Occurrences: 1
abbca -> Occurrences: 1
bbcab -> Occurrences: 1
cabc -> Occurrences: 1
bcab -> Occurrences: 1
bcb -> Occurrences: 1
英文:

Thanks to @rocka2q for helping me! This is the adjusted and final version of the code.


correct code, complete version (as I need it to work)

package main
import (
&quot;fmt&quot;
&quot;os&quot;
)
func main() {
string1 := os.Args[1]
map2 := substrings(string1)
count1 := 0
count2 := 0
var output1 string
for range map2 {
count1++
}
for key1, quantity1 := range map2 {
count2++
if count2 != count1 {
output1 += fmt.Sprintf(&quot;%s -&gt; Occurrences: %d\n&quot;, key1, quantity1)
} else {
output1 += fmt.Sprintf(&quot;%s -&gt; Occurrences: %d&quot;, key1, quantity1)
}
}
if len(map2) != 0 {
fmt.Println(output1)
}
}
func substrings(string1 string) map[string]int {
map1 := make(map[string]int)
for index1 := 0; index1 &lt; len(string1)-2; index1++ {
for index2 := index1 + 2; index2 &lt; len(string1); index2++ {
if string1[index1] == string1[index2] {
map1[string1[index1:index2+1]]++
}
}
}
return map1
}

outputs, all correct

$ go run exercise_2.go abbabba
abbabba -&gt; Occurrences: 1
bbabb -&gt; Occurrences: 1
babb -&gt; Occurrences: 1
abba -&gt; Occurrences: 2
bbab -&gt; Occurrences: 1
bab -&gt; Occurrences: 1
$ go run exercise_2.go abcacba
abcacba -&gt; Occurrences: 1
bcacb -&gt; Occurrences: 1
abca -&gt; Occurrences: 1
acba -&gt; Occurrences: 1
cac -&gt; Occurrences: 1
$ go run exercise_2.go eabcacf
abca -&gt; Occurrences: 1
cac -&gt; Occurrences: 1
$ go run exercise_2.go eabbcabcbf
bbcabcb -&gt; Occurrences: 1
bcabcb -&gt; Occurrences: 1
abbca -&gt; Occurrences: 1
bbcab -&gt; Occurrences: 1
cabc -&gt; Occurrences: 1
bcab -&gt; Occurrences: 1
bcb -&gt; Occurrences: 1

huangapple
  • 本文由 发表于 2023年5月20日 04:40:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76292304.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定