github.com/tunabay/go-bitarray@v1.3.1/bitarray_search.go (about) 1 // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be found in 3 // the LICENSE file. 4 5 package bitarray 6 7 import ( 8 "bytes" 9 ) 10 11 // HasPrefix reports whether the bit array starts with prefix. 12 func (ba *BitArray) HasPrefix(prefix BitArrayer) bool { 13 var baPrefix *BitArray 14 if prefix != nil { 15 baPrefix = prefix.BitArray() 16 } 17 switch { 18 case baPrefix.IsZero(): 19 return true 20 case ba.IsZero(), ba.nBits < baPrefix.nBits: 21 return false 22 case ba.b == nil: 23 return baPrefix.b == nil || allBytesZero(baPrefix.b) 24 } 25 if baPrefix.nBits < ba.nBits { 26 ba = ba.Slice(0, baPrefix.nBits) 27 } 28 switch { 29 case baPrefix.b == nil: 30 return ba.b == nil || allBytesZero(ba.b) 31 case ba.b == nil: 32 return allBytesZero(baPrefix.b) 33 } 34 35 return bytes.Equal(ba.b, baPrefix.b) 36 } 37 38 // HasSuffix reports whether the bit array ends with suffix. 39 func (ba *BitArray) HasSuffix(suffix BitArrayer) bool { 40 var baSuffix *BitArray 41 if suffix != nil { 42 baSuffix = suffix.BitArray() 43 } 44 switch { 45 case baSuffix.IsZero(): 46 return true 47 case ba.IsZero(), ba.nBits < baSuffix.nBits: 48 return false 49 case ba.b == nil: 50 return baSuffix.b == nil || allBytesZero(baSuffix.b) 51 } 52 if baSuffix.nBits < ba.nBits { 53 ba = ba.Slice(ba.nBits-baSuffix.nBits, ba.nBits) 54 } 55 switch { 56 case baSuffix.b == nil: 57 return ba.b == nil || allBytesZero(ba.b) 58 case ba.b == nil: 59 return allBytesZero(baSuffix.b) 60 } 61 62 return bytes.Equal(ba.b, baSuffix.b) 63 } 64 65 // Index returns the index of the first instance of x in the bit array ba, or -1 66 // if x is not present in ba. 67 func (ba *BitArray) Index(x BitArrayer) int { 68 var bax *BitArray 69 if x != nil { 70 bax = x.BitArray() 71 } 72 switch { 73 case ba.Len() < bax.Len(): 74 return -1 75 case bax.IsZero(): 76 return 0 77 case ba.b == nil && bax.b == nil: 78 return 0 79 } 80 ba8 := ba.bits8() 81 bax8 := bax.bits8() 82 83 return bytes.Index(ba8, bax8) 84 } 85 86 // LastIndex returns the index of the last instance of x in the bit array ba, or 87 // -1 if x is not present in ba. 88 func (ba *BitArray) LastIndex(x BitArrayer) int { 89 var bax *BitArray 90 if x != nil { 91 bax = x.BitArray() 92 } 93 switch { 94 case ba.Len() < bax.Len(): 95 return -1 96 case bax.IsZero(): 97 return ba.Len() 98 case ba.b == nil && bax.b == nil: 99 return ba.nBits - bax.nBits 100 } 101 ba8 := ba.bits8() 102 bax8 := bax.bits8() 103 104 return bytes.LastIndex(ba8, bax8) 105 } 106 107 // AllIndex returns the indexes of the all instance of x in the bit array ba, or 108 // empty slice if x is not present in ba. 109 func (ba *BitArray) AllIndex(x BitArrayer) []int { 110 var bax *BitArray 111 if x != nil { 112 bax = x.BitArray() 113 } 114 switch { 115 case ba.Len() < bax.Len(): 116 return []int{} 117 case bax.IsZero(): 118 idxs := make([]int, ba.Len()+1) 119 for i := range idxs { 120 idxs[i] = i 121 } 122 return idxs 123 case ba.b == nil && bax.b == nil: 124 idxs := make([]int, ba.nBits-bax.nBits+1) 125 for i := range idxs { 126 idxs[i] = i 127 } 128 return idxs 129 } 130 ba8 := ba.bits8() 131 bax8 := bax.bits8() 132 var idxs []int 133 i := 0 134 for i < ba.nBits-bax.nBits+1 { 135 idx := bytes.Index(ba8[i:], bax8) 136 if idx < 0 { 137 break 138 } 139 idx += i 140 idxs = append(idxs, idx) 141 i = idx + 1 142 } 143 return idxs 144 }