forked from jasder/antlr
Revert "[Go] Interval"
This commit is contained in:
parent
24c149603d
commit
38aaf88097
|
@ -14,9 +14,10 @@ type Interval struct {
|
|||
Stop int
|
||||
}
|
||||
|
||||
/* Inclusive interval*/
|
||||
/* stop is not included! */
|
||||
func NewInterval(start, stop int) *Interval {
|
||||
i := new(Interval)
|
||||
|
||||
i.Start = start
|
||||
i.Stop = stop
|
||||
return i
|
||||
|
@ -26,78 +27,16 @@ func (i *Interval) Contains(item int) bool {
|
|||
return item >= i.Start && item < i.Stop
|
||||
}
|
||||
|
||||
// Does this start completely before other? Disjoint
|
||||
func (i *Interval) StartsBeforeDisjoint(other *Interval) bool{
|
||||
return i.Start < other.Start && i.Stop < other.Start
|
||||
}
|
||||
|
||||
// Does this start at or before other? Nondisjoint
|
||||
func (i *Interval) StartsBeforeNonDisjoint(other *Interval) bool{
|
||||
return i.Start <= other.Start && i.Stop >= other.Start
|
||||
}
|
||||
|
||||
// Does this.a start after other.b? May or may not be disjoint
|
||||
func (i *Interval) StartsAfter(other *Interval) bool{
|
||||
return i.Start > other.Start
|
||||
}
|
||||
|
||||
// Does this start completely after other? Disjoint
|
||||
func (i *Interval) StartsAfterDisjoint(other *Interval) bool{
|
||||
return i.Start > other.Stop
|
||||
}
|
||||
|
||||
// Does this start after other? NonDisjoint
|
||||
func (i *Interval) StartsAfterNonDisjoint(other *Interval) bool{
|
||||
return i.Start>other.Start && i.Start <= other.Stop // i.Stop>=other.Stop implied
|
||||
}
|
||||
|
||||
// Are both ranges disjoint? I.e., no overlap?
|
||||
func (i *Interval) Disjoint(other *Interval) bool{
|
||||
return i.StartsBeforeDisjoint(other) || i.StartsAfterDisjoint(other)
|
||||
}
|
||||
|
||||
// Are two intervals adjacent such as 0..41 and 42..42?
|
||||
func (i *Interval) Adjacent(other *Interval) bool{
|
||||
return i.Start == other.Stop+1 || i.Stop == other.Start-1;
|
||||
}
|
||||
|
||||
func (i *Interval) ProperlyContains(other *Interval) bool{
|
||||
return other.Start >= i.Start && other.Stop <= i.Stop
|
||||
}
|
||||
|
||||
// Return the interval computed from combining this and other
|
||||
func (i *Interval) Union(other *Interval) *Interval{
|
||||
return NewInterval(intMin(i.Start, other.Start), intMax(i.Stop, other.Stop))
|
||||
}
|
||||
|
||||
// Return the interval in common between this and other
|
||||
func (i *Interval) Intersection(other *Interval) *Interval{
|
||||
return NewInterval(intMax(i.Start, other.Start), intMin(i.Stop, other.Stop))
|
||||
}
|
||||
// Return the interval with elements from this not in other;
|
||||
// other must not be totally enclosed (properly contained)
|
||||
// within this, which would result in two disjoint intervals
|
||||
// instead of the single one returned by this method.
|
||||
func (i *Interval) DifferenceNotProperlyContained(other *Interval) *Interval{
|
||||
var diff *Interval = nil
|
||||
if other.StartsBeforeDisjoint(i){
|
||||
diff = NewInterval(intMax(i.Start, other.Stop +1), i.Stop)
|
||||
}else if other.StartsAfterNonDisjoint(i){
|
||||
diff = NewInterval(i.Start, other.Start -1)
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
func (i *Interval) String() string {
|
||||
if i.Start == i.Stop {
|
||||
if i.Start == i.Stop-1 {
|
||||
return strconv.Itoa(i.Start)
|
||||
}
|
||||
|
||||
return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop)
|
||||
return strconv.Itoa(i.Start) + ".." + strconv.Itoa(i.Stop-1)
|
||||
}
|
||||
|
||||
func (i *Interval) length() int {
|
||||
return intMax(i.Stop - i.Start + 1,0)
|
||||
return i.Stop - i.Start
|
||||
}
|
||||
|
||||
type IntervalSet struct {
|
||||
|
@ -124,11 +63,11 @@ func (i *IntervalSet) first() int {
|
|||
}
|
||||
|
||||
func (i *IntervalSet) addOne(v int) {
|
||||
i.addInterval(NewInterval(v, v))
|
||||
i.addInterval(NewInterval(v, v+1))
|
||||
}
|
||||
|
||||
func (i *IntervalSet) addRange(l, h int) {
|
||||
i.addInterval(NewInterval(l, h))
|
||||
i.addInterval(NewInterval(l, h+1))
|
||||
}
|
||||
|
||||
func (i *IntervalSet) addInterval(v *Interval) {
|
||||
|
@ -210,30 +149,31 @@ func (i *IntervalSet) length() int {
|
|||
}
|
||||
|
||||
func (i *IntervalSet) removeRange(v *Interval) {
|
||||
if v.Start == v.Stop {
|
||||
if v.Start == v.Stop-1 {
|
||||
i.removeOne(v.Start)
|
||||
} else if i.intervals != nil {
|
||||
for k := 0; k < len(i.intervals); k++ {
|
||||
k := 0
|
||||
for n := 0; n < len(i.intervals); n++ {
|
||||
ni := i.intervals[k]
|
||||
// intervals are ordered
|
||||
if v.Stop <= ni.Start {
|
||||
return
|
||||
} else if v.Start > ni.Start && v.Stop < ni.Stop {
|
||||
i.intervals[k] = NewInterval(ni.Start, v.Start-1)
|
||||
x := NewInterval(v.Stop+1, ni.Stop)
|
||||
i.intervals[k] = NewInterval(ni.Start, v.Start)
|
||||
x := NewInterval(v.Stop, ni.Stop)
|
||||
// i.intervals.splice(k, 0, x)
|
||||
i.intervals = append(i.intervals[0:k+1], append([]*Interval{x}, i.intervals[k+1:]...)...)
|
||||
i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...)
|
||||
return
|
||||
} else if v.Start <= ni.Start && v.Stop >= ni.Stop {
|
||||
// i.intervals.splice(k, 1)
|
||||
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
|
||||
k = k - 1
|
||||
continue
|
||||
k = k - 1 // need another pass
|
||||
} else if v.Start < ni.Stop {
|
||||
i.intervals[k] = NewInterval(ni.Start, v.Start-1)
|
||||
i.intervals[k] = NewInterval(ni.Start, v.Start)
|
||||
} else if v.Stop < ni.Stop {
|
||||
i.intervals[k] = NewInterval(v.Stop+1, ni.Stop)
|
||||
i.intervals[k] = NewInterval(v.Stop, ni.Stop)
|
||||
}
|
||||
k++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,18 +185,18 @@ func (i *IntervalSet) removeOne(v int) {
|
|||
// intervals i ordered
|
||||
if v < ki.Start {
|
||||
return
|
||||
} else if v == ki.Start && v == ki.Stop {
|
||||
} else if v == ki.Start && v == ki.Stop-1 {
|
||||
// i.intervals.splice(k, 1)
|
||||
i.intervals = append(i.intervals[0:k], i.intervals[k+1:]...)
|
||||
return
|
||||
} else if v == ki.Start {
|
||||
i.intervals[k] = NewInterval(ki.Start+1, ki.Stop)
|
||||
return
|
||||
} else if v == ki.Stop {
|
||||
} else if v == ki.Stop-1 {
|
||||
i.intervals[k] = NewInterval(ki.Start, ki.Stop-1)
|
||||
return
|
||||
} else if v < ki.Stop {
|
||||
x := NewInterval(ki.Start, v-1)
|
||||
} else if v < ki.Stop-1 {
|
||||
x := NewInterval(ki.Start, v)
|
||||
ki.Start = v + 1
|
||||
// i.intervals.splice(k, 0, x)
|
||||
i.intervals = append(i.intervals[0:k], append([]*Interval{x}, i.intervals[k:]...)...)
|
||||
|
@ -295,14 +235,9 @@ func (i *IntervalSet) toCharString() string {
|
|||
names = append(names, ("'" + string(v.Start) + "'"))
|
||||
}
|
||||
} else {
|
||||
names = append(names, "'"+string(v.Start)+"'..'"+string(v.Stop)+"'")
|
||||
names = append(names, "'"+string(v.Start)+"'..'"+string(v.Stop-1)+"'")
|
||||
}
|
||||
}
|
||||
|
||||
if len(names) == 0{
|
||||
return "{}"
|
||||
}
|
||||
|
||||
if len(names) > 1 {
|
||||
return "{" + strings.Join(names, ", ") + "}"
|
||||
}
|
||||
|
@ -322,14 +257,9 @@ func (i *IntervalSet) toIndexString() string {
|
|||
names = append(names, strconv.Itoa(v.Start))
|
||||
}
|
||||
} else {
|
||||
names = append(names, strconv.Itoa(v.Start)+".."+strconv.Itoa(v.Stop))
|
||||
names = append(names, strconv.Itoa(v.Start)+".."+strconv.Itoa(v.Stop-1))
|
||||
}
|
||||
}
|
||||
|
||||
if len(names) == 0{
|
||||
return "{}"
|
||||
}
|
||||
|
||||
if len(names) > 1 {
|
||||
return "{" + strings.Join(names, ", ") + "}"
|
||||
}
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
package antlr
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func assertInterval(t *testing.T, i *Interval, l int){
|
||||
if i.length() != l{
|
||||
t.Errorf("For interval [%s] [%d] length is expected, [%d] is actual", i.String(), l, i.length())
|
||||
}
|
||||
}
|
||||
|
||||
func assertString(t *testing.T, expected string, result string){
|
||||
if result != expected{
|
||||
t.Errorf("expected: %s, result:%s", result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultIntervalLength(t *testing.T){
|
||||
assertInterval(t, NewInterval(0,0), 1)
|
||||
assertInterval(t, NewInterval(100, 100), 1)
|
||||
assertInterval(t, NewInterval(200,100),0)
|
||||
}
|
||||
|
||||
func TestIntervalSetAbsorb(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,20)
|
||||
s.addRange(11,19)
|
||||
assertString(t, "10..20", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetOverlap(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10, 20)
|
||||
s.addRange(15, 25)
|
||||
assertString(t, "10..25", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetIndependent(t *testing.T) {
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10, 20)
|
||||
s.addRange(30, 40)
|
||||
assertString(t, "{10..20, 30..40}", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetAdjoint(t *testing.T) {
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,20)
|
||||
s.addRange(20, 30)
|
||||
assertString(t, "10..30", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetBridge(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,20)
|
||||
s.addRange(30,40)
|
||||
s.addRange(20,30)
|
||||
assertString(t, "10..40", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetBreak(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,40)
|
||||
s.removeOne(25)
|
||||
assertString(t, "{10..24, 26..40}", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetRemoveStart(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,40)
|
||||
s.removeOne(10)
|
||||
assertString(t, "11..40", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetRemoveEnd(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,40)
|
||||
s.removeOne(40)
|
||||
assertString(t, "10..39", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetRemoveSinglePoint(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addOne(10)
|
||||
s.addRange(100,200)
|
||||
s.removeOne(10)
|
||||
assertString(t, "100..200", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetRemoveRangeMid(t *testing.T) {
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,30)
|
||||
s.removeRange(NewInterval(15,20))
|
||||
assertString(t, "{10..14, 21..30}", s.toIndexString())
|
||||
}
|
||||
|
||||
func TestIntervalSetRemoveEverything(t *testing.T){
|
||||
s := NewIntervalSet()
|
||||
s.addRange(10,20)
|
||||
s.addRange(30,40)
|
||||
s.removeRange(NewInterval(5, 50))
|
||||
assertString(t, "{}", s.toIndexString())
|
||||
}
|
Loading…
Reference in New Issue