github.com/searKing/golang/go@v1.2.74/exp/slices/sort_test.go (about) 1 // Copyright 2022 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package slices_test 6 7 import ( 8 "strconv" 9 "strings" 10 "testing" 11 12 math_ "github.com/searKing/golang/go/exp/math" 13 slices_ "github.com/searKing/golang/go/exp/slices" 14 "golang.org/x/exp/slices" 15 ) 16 17 func TestLinearSearch(t *testing.T) { 18 str1 := []string{"foo"} 19 str2 := []string{"ab", "ca"} 20 str3 := []string{"mo", "qo", "vo"} 21 str4 := []string{"ab", "ad", "ca", "xy"} 22 23 // slice with repeating elements 24 strRepeats := []string{"ba", "ca", "da", "da", "da", "ka", "ma", "ma", "ta"} 25 26 // slice with all element equal 27 strSame := []string{"xx", "xx", "xx"} 28 29 tests := []struct { 30 data []string 31 target string 32 wantPos int 33 wantFound bool 34 }{ 35 {[]string{}, "foo", 0, false}, 36 {[]string{}, "", 0, false}, 37 38 {str1, "foo", 0, true}, 39 {str1, "bar", 0, false}, 40 {str1, "zx", 1, false}, 41 42 {str2, "aa", 0, false}, 43 {str2, "ab", 0, true}, 44 {str2, "ad", 1, false}, 45 {str2, "ca", 1, true}, 46 {str2, "ra", 2, false}, 47 48 {str3, "bb", 0, false}, 49 {str3, "mo", 0, true}, 50 {str3, "nb", 1, false}, 51 {str3, "qo", 1, true}, 52 {str3, "tr", 2, false}, 53 {str3, "vo", 2, true}, 54 {str3, "xr", 3, false}, 55 56 {str4, "aa", 0, false}, 57 {str4, "ab", 0, true}, 58 {str4, "ac", 1, false}, 59 {str4, "ad", 1, true}, 60 {str4, "ax", 2, false}, 61 {str4, "ca", 2, true}, 62 {str4, "cc", 3, false}, 63 {str4, "dd", 3, false}, 64 {str4, "xy", 3, true}, 65 {str4, "zz", 4, false}, 66 67 {strRepeats, "da", 2, true}, 68 {strRepeats, "db", 5, false}, 69 {strRepeats, "ma", 6, true}, 70 {strRepeats, "mb", 8, false}, 71 72 {strSame, "xx", 0, true}, 73 {strSame, "ab", 0, false}, 74 {strSame, "zz", 3, false}, 75 } 76 for _, tt := range tests { 77 t.Run(tt.target, func(t *testing.T) { 78 { 79 pos, found := slices_.LinearSearch(tt.data, tt.target) 80 if pos != tt.wantPos || found != tt.wantFound { 81 t.Errorf("LinearSearch got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound) 82 } 83 wantPos, wantFound := slices.BinarySearch(tt.data, tt.target) 84 if pos != wantPos || found != wantFound { 85 t.Errorf("LinearSearch got (%v, %v), BinarySearch want (%v, %v)", pos, found, wantPos, wantFound) 86 } 87 } 88 89 { 90 pos, found := slices_.LinearSearchFunc(tt.data, tt.target, strings.Compare) 91 if pos != tt.wantPos || found != tt.wantFound { 92 t.Errorf("LinearSearchFunc got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound) 93 } 94 wantPos, wantFound := slices.BinarySearchFunc(tt.data, tt.target, strings.Compare) 95 if pos != wantPos || found != wantFound { 96 t.Errorf("LinearSearch got (%v, %v), BinarySearchFunc want (%v, %v)", pos, found, wantPos, wantFound) 97 } 98 } 99 }) 100 } 101 } 102 103 func TestLinearSearchInts(t *testing.T) { 104 tests := []struct { 105 data []int 106 target int 107 wantPos int 108 wantFound bool 109 }{ 110 {nil, 20, 0, false}, 111 {[]int{}, 20, 0, false}, 112 {[]int{20, 20, 30, 30}, 20, 0, true}, 113 {[]int{20, 20, 30, 30}, 23, 2, false}, 114 {[]int{20, 20, 30, 30}, 30, 2, true}, 115 {[]int{20, 20, 30, 30}, 43, 4, false}, 116 {[]int{20, 30, 40, 50, 60, 70, 80, 90}, 20, 0, true}, 117 {[]int{20, 30, 40, 50, 60, 70, 80, 90}, 23, 1, false}, 118 {[]int{20, 30, 40, 50, 60, 70, 80, 90}, 43, 3, false}, 119 {[]int{20, 30, 40, 50, 60, 70, 80, 90}, 80, 6, true}, 120 } 121 for _, tt := range tests { 122 t.Run(strconv.Itoa(tt.target), func(t *testing.T) { 123 { 124 pos, found := slices_.LinearSearch(tt.data, tt.target) 125 if pos != tt.wantPos || found != tt.wantFound { 126 t.Errorf("LinearSearch got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound) 127 } 128 wantPos, wantFound := slices.BinarySearch(tt.data, tt.target) 129 if pos != wantPos || found != wantFound { 130 t.Errorf("LinearSearch got (%v, %v), BinarySearch want (%v, %v)", pos, found, wantPos, wantFound) 131 } 132 } 133 134 { 135 cmp := math_.Compare[int] 136 pos, found := slices_.LinearSearchFunc(tt.data, tt.target, cmp) 137 if pos != tt.wantPos || found != tt.wantFound { 138 t.Errorf("LinearSearchFunc got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound) 139 } 140 wantPos, wantFound := slices.BinarySearchFunc(tt.data, tt.target, cmp) 141 if pos != wantPos || found != wantFound { 142 t.Errorf("LinearSearch got (%v, %v), BinarySearchFunc want (%v, %v)", pos, found, wantPos, wantFound) 143 } 144 } 145 }) 146 } 147 } 148 149 func TestPartialSortInts(t *testing.T) { 150 tests := []struct { 151 data []int 152 k int 153 }{ 154 {nil, 3}, 155 {[]int{}, 3}, 156 {[]int{20, 20, 30, 30}, 3}, 157 {[]int{20, 30}, 3}, 158 {[]int{20, 30, 40, 50, 60, 70, 80, 90}, 3}, 159 {[]int{90, 80, 70, 60, 50, 40, 30, 20}, 3}, 160 {[]int{90, 30, 70, 40, 50, 60, 80, 20}, 3}, 161 } 162 for i, tt := range tests { 163 t.Run(strconv.Itoa(i), func(t *testing.T) { 164 { 165 slices_.PartialSort(tt.data, tt.k) 166 if !slices_.IsPartialSorted(tt.data, tt.k) { 167 t.Errorf("partial sort didn't sort") 168 } 169 } 170 171 { 172 cmp := math_.Compare[int] 173 slices_.PartialSortFunc(tt.data, tt.k, func(a int, b int) int { 174 return -cmp(a, b) 175 }) 176 if !slices_.IsPartialSorted(tt.data, tt.k) { 177 t.Errorf("partial sort func didn't sort") 178 } 179 } 180 }) 181 } 182 }