feat(Go-Tool):新增Horspool字符串查找算法及其单测、新增计数排序及其单测
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2020/8/21 9:28
|
||||||
|
* @Description:计数排序,时间复杂度:Ο (n+k)、空间复杂度是 O(k)
|
||||||
|
* 限制:1.当数列最大最小值差距过大时,并不适用计数排序。2.当数列元素不是整数,并不适用计数排序。
|
||||||
|
* 参考地址:https://blog.csdn.net/csdnnews/article/details/83005778
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sort
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
func CountingSort(list []int) []int {
|
||||||
|
min, max := findMinAndMax(list)
|
||||||
|
countArray := make([]int, max-min+1)
|
||||||
|
for index := range list {
|
||||||
|
countArray[list[index]-min]++ //根据偏移量对数组某个下标的元素进行增一,如果这个位置元素存在
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建结果数组,这边其实可以直接输出或者使用原来的数组
|
||||||
|
result := make([]int, len(list))
|
||||||
|
pos := 0
|
||||||
|
for index := range countArray {
|
||||||
|
for countArray[index] != 0 {
|
||||||
|
result[pos] = index + min
|
||||||
|
pos++
|
||||||
|
countArray[index]--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func findMinAndMax(list []int) (int, int) {
|
||||||
|
min := math.MaxInt64
|
||||||
|
max := math.MinInt64
|
||||||
|
//找到数组中的最大值和最小值
|
||||||
|
for _, num := range list {
|
||||||
|
if num > max {
|
||||||
|
max = num
|
||||||
|
}
|
||||||
|
if num < min {
|
||||||
|
min = num
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min, max
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2020/8/21 9:28
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sort
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCountingSort(t *testing.T) {
|
||||||
|
list1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
|
CountingSort(list1)
|
||||||
|
for _, r := range list1 {
|
||||||
|
fmt.Print(r, " ")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
list2 := []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
|
||||||
|
result2 := CountingSort(list2)
|
||||||
|
for _, r := range result2 {
|
||||||
|
fmt.Print(r, " ")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
list3 := []int{1, 432, 12, 67, 341, 874, 56332, 43, 6564, 234, 980, 4234, 6589932, 80, 42, 4234, 55}
|
||||||
|
result3 := CountingSort(list3)
|
||||||
|
for _, r := range result3 {
|
||||||
|
fmt.Print(r, " ")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
list4 := []int{4523325, 21, 43, 1, 265, 7657, 8754, 234, 543, 536, 2, 6543, 772, 432, 5, 6, 7214, 6754}
|
||||||
|
result4 := CountingSort(list4)
|
||||||
|
for _, r := range result4 {
|
||||||
|
fmt.Print(r, " ")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2020/8/21 16:06
|
||||||
|
* @Description:参考地址:http://www.ifcoding.com/archives/247.html
|
||||||
|
* 该算法相当于先构造出对应的字符的移动位置,这边假设只匹配字母,则构造26个字母的移动表
|
||||||
|
* 从匹配的字符串的最后一位开始跟被匹配字符串进行匹配,直到没有匹配的字段或者匹配完整之后结束
|
||||||
|
* 得到当前匹配不正确的那个位置的字母,以此来找到该字母对应的移动位置,然后把匹配的字符串向后移动对应的位置,使得该字母和后面的字母对上,然后再进行一次匹配,直到找到对应的字符串位置为止,或者没有匹配的字符串返回-1
|
||||||
|
* 举例 abcdefg 和 bcd进行匹配
|
||||||
|
* 第一次: abcdefg
|
||||||
|
* d
|
||||||
|
* 发现不匹配并且不匹配的字母是c,所以按照c的移动规则,向后移动一位
|
||||||
|
* 第二次: abcdefg
|
||||||
|
* cd
|
||||||
|
*
|
||||||
|
* abcdefg
|
||||||
|
* bcd
|
||||||
|
* 关于另一种更有效的模式匹配算法 Boyer-Moore这边不给出算法实现(比较复杂),可参考:https://www.cnblogs.com/en-heng/p/5095542.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
func Horspool(allString string, match string) int {
|
||||||
|
//生成对应的移动表数据
|
||||||
|
move := shiTable(match)
|
||||||
|
i := len(match) - 1
|
||||||
|
for i < len(allString) {
|
||||||
|
k := 0
|
||||||
|
for k < len(match) && match[len(match)-1-k] == allString[i-k] {
|
||||||
|
k++
|
||||||
|
}
|
||||||
|
if k == len(match) {
|
||||||
|
return i - len(match) + 1
|
||||||
|
} else {
|
||||||
|
i = i + move[allString[i]-'a']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成对应的移动表数据
|
||||||
|
func shiTable(s string) []int {
|
||||||
|
table := make([]int, 27) //这边只考虑26个字母和一个空字符串的情况
|
||||||
|
//所有格子都初始化移动步数为被查找字符串长度.
|
||||||
|
for i := 0; i < 27; i++ {
|
||||||
|
table[i] = len(s)
|
||||||
|
}
|
||||||
|
//构造对应的被查找字符串中的字符的移动步数
|
||||||
|
for i := 0; i < len(s)-1; i++ {
|
||||||
|
table[s[i]-'a'] = len(s) - 1 - i
|
||||||
|
}
|
||||||
|
return table
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2020/8/21 16:07
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHorspool(t *testing.T) {
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "abcd")) //输出0
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "bcd")) //输出1
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "fgh")) //输出6
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "hijk")) //输出8
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "jk")) //输出10
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "k")) //输出11
|
||||||
|
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "kbz")) //输出-1
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "kdasdsad")) //输出-1
|
||||||
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "dsadsa")) //输出-1
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user