Created
September 25, 2021 15:19
-
-
Save kariyayo/1fa106711d17ddea6ab39c43e989fea3 to your computer and use it in GitHub Desktop.
lower_boundとupper_boundをGoで。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"testing" | |
) | |
// key以上の要素のうちMINである要素の添字を返す | |
func lowerBound(xs []int, key int) int { | |
if len(xs) == 0 { | |
return 0 | |
} | |
l, r := 0, len(xs)-1 | |
if xs[r] < key { | |
// key以上の要素が存在しない | |
return r + 1 | |
} | |
for r-l > 1 { | |
mid := l + (r-l)/2 | |
v := xs[mid] | |
if key <= v { | |
r = mid | |
} else { | |
l = mid | |
} | |
} | |
if xs[l] >= key { | |
return l | |
} | |
return r | |
} | |
// keyより大きな要素のうちMINである要素の添字を返す | |
func upperBound(xs []int, key int) int { | |
if len(xs) == 0 { | |
return 0 | |
} | |
l, r := 0, len(xs)-1 | |
if xs[r] <= key { | |
// keyより大きい要素が存在しない | |
return r + 1 | |
} | |
for r-l > 1 { | |
mid := l + (r-l)/2 | |
v := xs[mid] | |
if key < v { | |
r = mid | |
} else { | |
l = mid | |
} | |
} | |
if xs[l] > key { | |
return l | |
} | |
return r | |
} | |
func Test_lowerBound(t *testing.T) { | |
type args struct { | |
xs []int | |
key int | |
} | |
xs := []int{2, 3, 3, 3, 5, 5, 5, 6, 7} | |
tests := []struct { | |
note string | |
args args | |
want int | |
}{ | |
{ | |
args: args{xs: xs, key: 2}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: xs, key: 3}, | |
want: 1, | |
}, | |
{ | |
args: args{xs: xs, key: 4}, | |
want: 4, | |
}, | |
{ | |
args: args{xs: xs, key: 7}, | |
want: 8, | |
}, | |
{ | |
note: "key以上の値が存在しない", | |
args: args{xs: xs, key: 8}, | |
want: 9, | |
}, | |
{ | |
args: args{xs: []int{}, key: 2}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: []int{3}, key: 2}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: []int{3}, key: 3}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: []int{3, 3, 3}, key: 3}, | |
want: 0, | |
}, | |
} | |
for _, tt := range tests { | |
t.Run(fmt.Sprintf("%+v", tt.args), func(t *testing.T) { | |
if got := lowerBound(tt.args.xs, tt.args.key); got != tt.want { | |
t.Errorf("lowerBound() = %v, want %v", got, tt.want) | |
} | |
}) | |
} | |
} | |
func Test_upperBound(t *testing.T) { | |
type args struct { | |
xs []int | |
key int | |
} | |
xs := []int{2, 3, 3, 3, 5, 5, 5, 6, 7} | |
tests := []struct { | |
note string | |
args args | |
want int | |
}{ | |
{ | |
args: args{xs: xs, key: 1}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: xs, key: 2}, | |
want: 1, | |
}, | |
{ | |
args: args{xs: xs, key: 3}, | |
want: 4, | |
}, | |
{ | |
args: args{xs: xs, key: 4}, | |
want: 4, | |
}, | |
{ | |
args: args{xs: xs, key: 7}, | |
want: 9, | |
}, | |
{ | |
args: args{xs: []int{}, key: 2}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: []int{3}, key: 2}, | |
want: 0, | |
}, | |
{ | |
args: args{xs: []int{3}, key: 3}, | |
want: 1, | |
}, | |
{ | |
args: args{xs: []int{3, 3, 3}, key: 2}, | |
want: 0, | |
}, | |
} | |
for _, tt := range tests { | |
t.Run(fmt.Sprintf("%+v", tt.args), func(t *testing.T) { | |
if got := upperBound(tt.args.xs, tt.args.key); got != tt.want { | |
t.Errorf("upperBound() = %v, want %v", got, tt.want) | |
} | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment