I'm not able, through binary search, to count the number of times a number is repeated in a vector. Here's the code:
v = {1, 1, 2, 2, 2, 3, 4, 5}
elem = 2
n = len(v)
lef = 0
rig = n - 1
while lef <= rig:
mid = (lef rig) // 2
if v[mid] == elem:
aux= 1
break
elif elem < v[mid]:
rig = mid - 1
aux= 1
else:
lef = mid 1
aux= 1
if v[mid] == elem:
print(mid)
else:
print(-1)
print(aux)
As you can see, I put a variable named aux
serving as a counter inside the if
and elif
, but the output is not as expected. In the code I put the printing of the position to make sure that the algorithm in the part of finding the index is working.
I also thought about using another loop inside the while
, but it soon came to mind that it would make the algorithm more expensive, but would that be the only way? How could I implement this?
CodePudding user response:
Here is a simple idea: call binary search twice. That way you won't sacrifice the time complexity.
v = [1, 1, 2, 2, 2, 3, 4, 5]
elem = 2
n = len(v)
def find_lo():
lef = 0
rig = n - 1
while lef <= rig:
mid = (lef rig) // 2
if v[mid] == elem:
if not mid:
return mid
if v[mid] != v[mid-1]:
return mid
rig = mid-1
elif elem < v[mid]:
rig = mid - 1
else:
lef = mid 1
return None
def find_right():
lef = 0
rig = n - 1
while lef <= rig:
mid = (lef rig) // 2
if v[mid] == elem:
if mid >= n-1:
return mid
if v[mid] != v[mid 1]:
return mid
lef = mid 1
elif elem < v[mid]:
rig = mid - 1
else:
lef = mid 1
return None
print(find_lo()) # 2
print(find_right()) # 4
Note: the two methods can be refactored as a single function to reduce redundancy, this is just a simple demonstration.
CodePudding user response:
If you can use algorithm available in python's bisect
, it is just:
import bisect
v = [1, 1, 2, 2, 2, 3, 4, 5]
elem = 2
print(bisect.bisect_right(v, elem) - bisect.bisect_left(v, elem))
output:
3
CodePudding user response:
v = {1, 1, 2, 2, 2, 3, 4, 5} is a set, and a set cannot have duplicates
The duplicates are deleted because of the way you declared v, so you will no be able to count repetitions.
v = {1, 1, 2, 2, 2, 3, 4, 5}
print(v)
>>>{1,2,3,4,5}
You can use a list, and count the duplicates with Counter
from collections import Counter
v = [1, 1, 2, 2, 2, 3, 4, 5]
print(v)
_=[print(f"{element}: {copies} times") for element,copies in Counter(v).items()]
it outputs
[1, 1, 2, 2, 2, 3, 4, 5]
1: 2 times
2: 3 times
3: 1 times
4: 1 times
5: 1 times