binary search implementation with python [duplicate] - python

This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 7 months ago.
I think I did everything correctly, but the base case return None, instead of False if the value does not exists. I cannot understand why.
def binary_search(lst, value):
if len(lst) == 1:
return lst[0] == value
mid = len(lst)/2
if lst[mid] < value:
binary_search(lst[:mid], value)
elif lst[mid] > value:
binary_search(lst[mid+1:], value)
else:
return True
print binary_search([1,2,4,5], 15)

You need to return the result of the recursive method invocation:
def binary_search(lst, value):
#base case here
if len(lst) == 1:
return lst[0] == value
mid = len(lst)/2
if lst[mid] < value:
return binary_search(lst[:mid], value)
elif lst[mid] > value:
return binary_search(lst[mid+1:], value)
else:
return True
And I think your if and elif condition are reversed. That should be:
if lst[mid] > value: # Should be `>` instead of `<`
# If value at `mid` is greater than `value`,
# then you should search before `mid`.
return binary_search(lst[:mid], value)
elif lst[mid] < value:
return binary_search(lst[mid+1:], value)

Because if return nothing!
if lst[mid] < value:
binary_search(lst[:mid], value)
# hidden return None
elif lst[mid] > value:
binary_search(lst[mid+1:], value)
# hidden return None
else:
return True

You need to return from if and elif too.
def binary_search(lst, value):
#base case here
if len(lst) == 1:
return lst[0] == value
mid = len(lst) / 2
if lst[mid] < value:
return binary_search(lst[:mid], value)
elif lst[mid] > value:
return binary_search(lst[mid+1:], value)
else:
return True
>>> print binary_search([1,2,4,5], 15)
False

Binary Search:
def Binary_search(num,desired_value,left,right):
while left <= right:
mid = (left + right)//2
if desired_value == num[mid]:
return mid
elif desired_value > num[mid]:
left = mid + 1
else:
right = mid - 1
return -1
num =[12,15,19,20,22,29,38,41,44,90,106,397,399,635]
desired_value = 41
result = Binary_search(num,desired_value,0,len(num)-1)
if result != -1:
print("Number found at " + str(result),'th index')
else:
print("number not found")

def rBinarySearch(list,element):
if len(list) == 1:
return element == list[0]
mid = len(list)/2
if list[mid] > element:
return rBinarySearch( list[ : mid] , element )
if list[mid] < element:
return rBinarySearch( list[mid : ] , element)
return True

def binary_search(lists,x):
lists.sort()
mid = (len(lists) - 1)//2
if len(lists)>=1:
if x == lists[mid]:
return True
elif x < lists[mid]:
lists = lists[0:mid]
return binary_search(lists,x)
else:
lists = lists[mid+1:]
return binary_search(lists,x)
else:
return False
a = list(map(int,input('enter list :').strip().split()))
x = int(input('enter number for binary search : '))
(binary_search(a,x))

def binary_search(arr, elm):
low, high = 0, len(arr) - 1
while low <= high:
mid = (high + low) // 2
val = arr[mid]
if val == elm:
return mid
elif val <= elm:
low = mid + 1
else:
high = mid - 1
return -1
print(binary_search([2, 3, 4, 6, 12, 19, 20, 21], 12)) # 4
print(binary_search([2, 3, 4, 6, 12, 19, 20, 21], 3333)) # -1

def Binary_search(li, e, f, l):
mid = int((f+l)/2)
if li[mid] == e:
print("Found",li[mid] )
elif f == l-1 and li[mid] != e:
print("Not Found ")
elif e < li[mid]:
Binary_search(li, e, f,mid)
elif e > li[mid]:
Binary_search(li, e, mid,l)
elements = [1,2,4,6,8,9,20,30,40,50,60,80,90,100,120,130,666]
Binary_search(elements, 120, 0, len(elements))

class binar_search:
def __init__(self,arr , element):
self.arr = arr
self.element = element
def search(self):
n = len(self.arr)
low = 0
high = n-1
while(low <= high):
mid = (low+high)//2
if self.arr[mid] == self.element:
return mid
elif self.arr[mid] < self.element:
low = mid+1
else:
high = mid -1
return 0

Related

Can't print binary heap in python

I try to make a binary heap in python but I get trouble printing it. I make sure that the logic in the program is right but when I want to try printing it I get the wrong result. This is what I want for program output:
Input:
6
1 2
1 3
1 7
2
3
2
Output:
7
3
command 1 to insert number
command 2 to display the highest number
command 3 to delete the highest number
This is my program:
class BinaryHeap:
def __init__(self):
self.items = []
def size(self):
return len(self.items)
def parent(self, i):
return (i - 1)//2
def left(self, i):
return 2*i + 1
def right(self, i):
return 2*i + 2
def get(self, i):
return self.items[i]
def get_max(self):
if self.size() == 0:
return None
return self.items[0]
def extract_max(self):
if self.size() == 0:
return None
largest = self.get_max()
self.items[0] = self.items[-1]
del self.items[-1]
self.max_heapify(0)
return largest
def max_heapify(self, i):
l = self.left(i)
r = self.right(i)
if (l <= self.size() - 1 and self.get(l) > self.get(i)):
largest = l
else:
largest = i
if (r <= self.size() - 1 and self.get(r) > self.get(largest)):
largest = r
if (largest != i):
self.swap(largest, i)
self.max_heapify(largest)
def swap(self, i, j):
self.items[i], self.items[j] = self.items[j], self.items[i]
def insert(self, key):
index = self.size()
self.items.append(key)
while (index != 0):
p = self.parent(index)
if self.get(p) < self.get(index):
self.swap(p, index)
index = p
bheap = BinaryHeap()
n = int(input())
for i in range (n):
operation= input('What would you like to do? ').split()
if operation == 1:
data = int(operation[1])
bheap.insert(data)
elif operation == 2:
print('Maximum value: {}'.format(bheap.get_max()))
elif operation == 3:
print('Maximum value removed: {}'.format(bheap.extract_max()))
elif operation == 4:
break
I need your opinion to fixed it.
operation is a list (you called split), but you compare it as an int in your if statements. Also, you should compare it against "1", "2", ... not 1, 2, ...
So:
operation = input('What would you like to do? ').split()
if operation[0] == "1":
data = int(operation[1])
bheap.insert(data)
elif operation[0] == "2":
print('Maximum value: {}'.format(bheap.get_max()))
elif operation[0] == "3":
print('Maximum value removed: {}'.format(bheap.extract_max()))
elif operation[0] == "4":
break
If you just want 7 and 3 in the output, and only after the input has been completely processed, then you should remove those verbose print statement (where you output phrases), and instead collect the output -- for instance in a list:
output = []
n = int(input())
for i in range(n):
operation = input('What would you like to do? ').split()
if operation[0] == "1":
data = int(operation[1])
bheap.insert(data)
elif operation[0] == "2":
output.append(bheap.get_max())
elif operation[0] == "3":
bheap.extract_max()
elif operation[0] == "4":
break
print("\n".join(map(str, output)))

the return value of python function [duplicate]

This question already has an answer here:
Why Python recursive function returns None [duplicate]
(1 answer)
Closed 2 years ago.
I have a recursive function, I have no idea why the result printed in main is always None.
def find_nega(A: list, start: int, right: int) -> int :
s = start
r = right
mid = (s + r) // 2
if (s >= r):
return None
if (A[mid] == 0):
return mid - 1
if (A[s] < 0 and A[r] >= 0 and s == r - 1):
print(s)
return s
if (A[mid] < 0):
s = mid
find_nega(list1, s, r)
elif (A[mid] > 0):
r=mid
find_nega(list1, s,r)
else:
return mid
if __name__ == "__main__":
list1 = [-3,-2,-1,4,5,6]
x = find_nega(list1, 0, len(list1) - 1)
print(x)
In this example, it enters the condition A[s] < 0 and A[r] >= 0 and s == r - 1 but don't know why it doesn't print 2.
It doesn't print 2 because you don't return the value when you call the recursion. Here it works
def find_nega(A: list, start: int, right: int) -> int:
print(A, start, right)
s = start
r = right
mid = (s + r) // 2
if s >= r:
return None
if A[mid] == 0:
return mid - 1
if A[s] < 0 and A[r] >= 0 and s == r - 1:
#print(s)
return s
if A[mid] < 0:
s = mid
return find_nega(list1, s, r)
elif A[mid] > 0:
r = mid
return find_nega(list1, s, r)
else:
return mid
if __name__ == "__main__":
list1 = [-3, -2, -1, 4, 5, 6]
x = find_nega(list1, 0, len(list1) - 1)
print(x)

Insertion sort using binary search in python

I need a little help with the code below, I have been tasked with changing the insertion sort to use the given binary search function.
def binarySearch(aList, start, end, value):
#Return the position where value is or should be inserted.
while start <= end:
mid = (start + end) // 2
if aList[mid] == value:
return mid
if value < aList[mid]:
end = mid - 1
else:
start = mid + 1
return start
def insertionSort(aList):
#Sort aList in ascending order.
for index in range(1, len(aList)):
key = aList[index]
pos = index
while pos > 0 and aList[pos - 1] > key:
aList[pos] = aList[pos - 1]
pos = pos - 1
aList[pos] = key
The code I am using to test the function is:
numbers = [71, 32, 22, 19, 18, 1, 15, 40]
insertionSort(numbers)
print(numbers)
Any help is appreciated as I am having a mind blank
def binary_search(arr, val, start, end):
if start == end: #折半到最后start和end可能会相等,递归退出条件之一
if arr[start] > val:
return start
else:
return start+1
if start + 1 == end: #折半到最后start和end相差1,递归退出条件之一
return start+1
mid = (start+end)//2
if arr[mid] < val:
return binary_search(arr,val,mid, end)
elif arr[mid] > val:
return binary_search(arr, val, start, mid)
else:
return mid #折半遇到mid值与val相等,递归退出条件之一
def insertion_sort(arr:list):
for i in range(1, len(arr)):
if arr[i] <= arr[0]:
index = 0
elif arr[i] >= arr[i-1]:
continue
else:
index = binary_search(arr[0:i],arr[i],0, i-1)
arr = arr[:index]+ [arr[i]] + arr[index:i] + arr[i+1:]
return arr
arr = [30,20,80,40,50,10,60,70,90]
insertion_sort(arr)

get next highest value in BST

I wrote a function to get the next highest value in a binary search tree and return 0 if the input value is the highest in the tree:
def getNext(root, x):
if x > root.d:
if root.r == None:
return 0
else:
if x > root.r.d:
getNext(root.r, x)
else:
temp = root.r
while temp.l != None:
temp = temp.l
return temp.d
else:
if root.l == None:
return root.d
elif x < root.l.d:
getNext(root.l, x)
else:
temp = Node('')
temp = root.l.r #53
if temp.d > x:
getNext(temp, x)
else:
while temp != None:
if temp.r == None:
return root.d
elif x > temp.r.d:
temp = temp.r
else:
getNext(temp.r, x)
break
but it only returns None
I have tried adding a print before the return, and the print actually outputs correctly
Add a return before every recursive call, i.e.
return getNext(root.r,x)
return getNext(root.l,x)
return getNext(temp,x)
return getNext(temp.r,x)

Calculator which parses user input

import string
# Strength of operations:
# -> [] (brackets)
# 6 -> ~ (negative)
# 5 -> #, $, & (average, maximum, minimum)
# 4 -> %, ! (modulo, factorial)
# 3 -> ^ (power)
# 2 -> *, / (multiplication, division)
# 1 -> +, - (addition, subtraction)
def BinaryOperation(exp, idx):
""" Gets an expression and an index of an operator and returns a tuple with (first_value, operator, second_value). """
first_value = 0
second_value = 0
#Get first value
idx2 = idx -1
if idx2 == 0:
first_value = exp[idx2:idx]
else:
while (idx2 > 0) and (exp[idx2] in string.digits):
idx2 -=1
if (exp[idx2] in ("-")) or (exp[idx2] in string.digits):#-5*3
first_value = exp[idx2:idx]
else:#%5*3
first_value = exp[idx2+1:idx]
#Get second value
idx2 = idx +1
if exp[idx+1] not in string.digits: #If there is something like 1*+5, second_sign will be +.
idx2 += 1 #idx2 will begin from the char after the sign.
while (idx2 < len(exp)) and (exp[idx2] in string.digits):
idx2 += 1
second_value = exp[idx+1:idx2]
return (first_value, exp[idx], second_value)
def UnaryOperation(exp, idx):
""" Gets an expression and an index of an operator and returns a tuple with (operator, value). """
#Get value
idx2 = idx+1
if exp[idx+1] not in string.digits: #If there is something like ~-5, second_sign will be -.
idx2 += 1 #idx2 will begin from the char after the sign.
while (idx2 < len(exp)) and (exp[idx2] in string.digits):
idx2 +=1
return (exp[idx], exp[idx+1:idx2])
def Brackets(exp):
idx = 0
while idx < len(exp):
if exp[idx] == "[":
#Brackets
close_bracket = exp.find("]")
if close_bracket == -1:
raise Exception("Missing closing bracket.")
exp_brackets = exp[idx+1:close_bracket]
value = str(solve(exp_brackets))
exp = exp.replace("[" + exp_brackets + "]", value)
idx = 0 #The len has been changed, scan again.
idx += 1
return Level6(exp)
def Level6(exp):
idx = 0
while idx < len(exp):
if exp[idx] in ("~"):
#Negative
sub_exp = UnaryOperation(exp, idx)
value = ~int(sub_exp[1])
value = str(value)
exp = exp.replace(''.join(sub_exp), value)
idx = 0 #The len has been changed, scan again.
idx += 1
return Level5(exp)
def Level5(exp):
idx = 0
while idx < len(exp):
if exp[idx] in ("#", "$", "&"):
#Average, Maximum and Minimum
sub_exp = BinaryOperation(exp, idx)
first_value = int(sub_exp[0])
second_value = int(sub_exp[2])
if sub_exp[1] == "#":
value = (first_value + second_value)/2
if sub_exp[1] == "$":
value = first_value if first_value > second_value else second_value
if sub_exp[1] == "&":
value = first_value if first_value < second_value else second_value
value = str(value)
exp = exp.replace(''.join(sub_exp), value)
idx = 0 #The len has been changed, scan again.
idx += 1
return Level4(exp)
def Level4(exp):
idx = 0
while idx < len(exp):
if exp[idx] in ("%","!"):
#Modulo and Factorial
if exp[idx] == "%":
sub_exp = BinaryOperation(exp, idx)
value = int(sub_exp[0]) % int(sub_exp[2])
if exp[idx] == "!":
sub_exp = UnaryOperation(exp, idx)
value = reduce(lambda x,y:x*y, range(1, int(sub_exp[1])+1))
value = str(value)
exp = exp.replace(''.join(sub_exp), value)
idx = 0 #The len has been changed, scan again.
idx += 1
return Level3(exp)
def Level3(exp):
idx = 0
while idx < len(exp):
if exp[idx] in ("^"):
#Power
sub_exp = BinaryOperation(exp, idx)
value = int(sub_exp[0]) ** int(sub_exp[2])
value = str(value)
exp = exp.replace(''.join(sub_exp), value)
idx = 0 #The len has been changed, scan again.
idx += 1
return Level2(exp)
def Level2(exp):
idx = 0
while idx < len(exp):
if exp[idx] in ("*", "/"):
#Multiplication and Division
sub_exp = BinaryOperation(exp, idx)
if sub_exp[1] == "*":
value = int(sub_exp[0]) * int(sub_exp[2])
if sub_exp[1] == "/":
value = int(sub_exp[0]) / int(sub_exp[2])
value = str(value)
exp = exp.replace(''.join(sub_exp), value)
idx = 0 #The len has been changed, scan again.
idx += 1
return Level1(exp)
def Level1(exp):
idx = 0
while idx < len(exp):
if (exp[idx] in ("+", "-")) and (idx != 0):
#Addition and Subtraction
sub_exp = BinaryOperation(exp, idx)
if sub_exp[1] == "+":
value = int(sub_exp[0]) + int(sub_exp[2])
if sub_exp[1] == "-":
value = int(sub_exp[0]) - int(sub_exp[2])
value = str(value)
exp = exp.replace(''.join(sub_exp), value)
idx = 0 #The len has been changed, scan again.
idx += 1
return exp
def solve(exp):
exp = Brackets(exp)
return float(exp) if "." in exp else int(exp)
def remove_whitespace(exp):
""" Gets a string and removes all whitespaces and tabs """
exp = exp.replace(" ", "")
exp = exp.replace("\t", "")
return exp
while True:
exp = raw_input("")
exp = remove_whitespace(exp)
print solve(exp)
I have written this program after a lot of effort, and I was wondering about the efficiency of that solution and if it's neat.
So my question is, how plain is this program and is there any better way to rewrite it?
just for the point.
>>> eval(raw_input("input calculation: "))
input calculation: 1+1
2
>>> eval(raw_input("input calculation: "))
input calculation: (6*4^2)
26
>>> eval(raw_input("input calculation: "))
input calculation: (3/2.3)*4
5.2173913043478262
for an innocent program, you can use eval
but you really shouldn't use it ever. its only real use is confusing people, and being a fun novelty if you write programs fro yourself and decide you want a calculator.
there are many ways to write a calculator function.
try some of these other answers:
Python creating a calculator
Basic calculator program in python
python calculator program
If you want to check out some custom class-based evaluation engines in Python, these might help you:
Expression Evaluator (version 1 with source)
Math Evaluator (version 2 with source)
again = True
answer = ""
while again is True:
try:
expression = raw_input("Enter your expression: ")
found = False
oper = -1
operator1 = 0
operator2 = 0
while found==False:
if (expression.find("+")>0 and expression.find("+")<len(expression)-1):
found = True
oper = expression.find("+")
operator1 = float(expression[:oper])
operator2 = float(expression[oper+1:])
print "{} + {} = {}".format(operator1,operator2,operator1+operator2)
elif(expression.find("-")>0 and expression.find("-")<len(expression)-1):
found = True
oper = expression.find("-")
operator1 = float(expression[:oper])
operator2 = float(expression[oper+1:])
print "{} - {} = {}".format(operator1,operator2,operator1-operator2)
elif(expression.find("*")>0 and expression.find("*")<len(expression)-1):
found = True
oper = expression.find("*")
operator1 = float(expression[:oper])
operator2 = float(expression[oper+1:])
print "{} * {} = {}".format(operator1,operator2,operator1*operator2)
elif(expression.find("/")>0 and expression.find("/")<len(expression)-1):
found = True
oper = expression.find("/")
operator1 = float(expression[:oper])
operator2 = float(expression[oper+1:])
print "{} / {} = {}".format(operator1,operator2,operator1/operator2)
else:
oper = -1
found = False
print "Incorrect expression, please try again"
break
again = False
answer = raw_input("Try again?: ")
if(answer == "y" or answer=="yes" or answer =="Y" or answer == "YES"):
again = True
else:
again = False
print "Thank you for playing! See you next time."
break
except:
print "Failed, check your expression and try again"

Categories