0% found this document useful (0 votes)
44 views17 pages

Exercise 1

The program contains 5 exercises related to graph algorithms and data structures: 1. It contains functions to find the Greatest Common Divisor (GCD) of two numbers using the Euclid's algorithm and consecutive integer checking algorithm. 2. It implements the Rabin-Karp algorithm to perform string matching between a pattern and text. 3. It analyzes the time complexity of Merge Sort which uses the divide and conquer technique with worst, best and average cases taking O(n log n) time. 4. It analyzes the time complexity of Quicksort which also uses divide and conquer. The best and average cases take O(n log n) time while the worst case takes O

Uploaded by

Trevor Erickson
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views17 pages

Exercise 1

The program contains 5 exercises related to graph algorithms and data structures: 1. It contains functions to find the Greatest Common Divisor (GCD) of two numbers using the Euclid's algorithm and consecutive integer checking algorithm. 2. It implements the Rabin-Karp algorithm to perform string matching between a pattern and text. 3. It analyzes the time complexity of Merge Sort which uses the divide and conquer technique with worst, best and average cases taking O(n log n) time. 4. It analyzes the time complexity of Quicksort which also uses divide and conquer. The best and average cases take O(n log n) time while the worst case takes O

Uploaded by

Trevor Erickson
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 17

EXERCISE 1

1. Write a program to find GCD of two numbers using different

algorithms Euclid’s Algorithm and Consecutive Integer Checking

Algorithm

def gcde(m,n):
if m< n:
(m,n) =
(n,m) while n!
=0:
r=m % n
m=n
n=r
return m

def gcdc(m,n):
t=min(m, n)
while t > 0:
if m % t == 0 and n % t == 0:
return t
t =t - 1

print("Program to find the GCD of 2 numbers using:")


print("1: Euclid's Algorithm")
m = int(input("enter first number: "))
n = int(input("enter second number: "))
print(gcde(m,n))
print("2: Consecutive Integer Checking Algorithm")
m = int(input("enter first number: "))
n = int(input("enter second number: "))
print(gcdc(m,n))

Explanation:

The program takes two numbers and prints the GCD of two numbers.
def : It is used to define the function in python , which can take the arguments.
input(): Function is used to take input from the user
int(input) :To take integer input in Python. The Python’s built-in input () function always returns a
str(string) class object. So for taking integer input we have to type cast those inputs into integers by
using Python built-in int () function.

Euclid Algorithm :
1. Take two numbers from the user.
2. Pass the two numbers as arguments to a recursive
function. If m < n ,interchange as we do m % n
3. When the second number becomes 0, return the first number.
4. Else recursively call the function with the arguments as the second number and
the remainder when the first number is divided by the second number.
5. Return the first number which is the GCD of the two numbers.
6. Print the GCD.
7. Exit.

Consecutive Integer Checking


Step 1. Assign the value of min{m,n} to t
Step 2. Divide m by t. If the remainder of this division is 0, go to
Step 3; otherwise go to Step 4.
Step 3. Divide n by t. If the remainder of this division is 0, return the value of t as the answer
and step, otherwise, proceed to Step 4.
Step 4. Decrease the value of t by 1. Go to Step 2.

Output:
Program to find the GCD of 2 numbers using:
1: Euclid's Algorithm

enter first number: 5

enter second number: 10


5
2: Consecutive Integer Checking Algorithm

enter first number: 5

enter second number: 10


5
1.b) Write a program to Implement Sieve of Eratosthenes to generate Prime Numbers Between Given
Range

def SieveOfEratosthenes(n):

prime = [True for i in range(n + 1)]


p=2
while (p * p <= n):

if (prime[p] == True):

for i in range(p * 2, n + 1, p):


prime[i] = False
p += 1
prime[0]= False
prime[1]= False
for p in range(n + 1):
if prime[p]:
print p,

if name ==' main ':


n = 30
print "Following are the prime numbers "
SieveOfEratosthenes(n)

Explanation:

Prime = [True for i in range(n+1) : Print True for all till n value
It is one of the simple, ancient algorithm for finding all prime numbers up to any given limit.
The Steps in simple form
Mark the table with all true values initially and later follow the given steps
8. Generate numbers from 2 to n (2 is the smallest prime).
9. Traverse from smallest prime number which is num = 2.
10. Eliminate or mark all the multiples of num (as 0 or -1) which are lesser than or equal to n. It
will help remove non-prime numbers and will help to reduce our number of comparisons to
check for each number.
11. Update the value of num to the immediate next prime number. The next prime is the
next (non 0 or -1) number in the list which is greater than the current number (num).
12. Repeat step three until num<=√n.
Traverse the whole list and number print. All the numbers (>=0) will be our required prime
numbers lesser than n (given number).
Example for prime number using Sieve of Eratosthenes

Output:
enter the value of n10
Following are the prime numbers
[True, True, True, True, True, True, True, True, True, True,
True] 4 False
6 False
8 False
10 False
6 False
9 False
2 True
3 True
5 True
7 True
EXERCISE 2
2. Develop a program to perform string matching using the Rabin-Karp algorithm
# Rabin-Karp algorithm in python
d = 10
def search(pattern, text, q):
m = len(pattern)
n = len(text)
p=0
t=0
h=1
i=0
j=0

for i in range(m-1):
h = (h*d) % q

# Calculate hash value for pattern and text


for i in range(m):
p = (d*p + ord(pattern[i])) % q
t = (d*t + ord(text[i])) % q

# Find the match


for i in range(n-m+1):
if p == t:
for j in range(m):
if text[i+j] != pattern[j]:
break

j += 1
if j == m:
print("Pattern is found at position: " + str(i+1))

if i < n-m:
t = (d*(t-ord(text[i])*h) + ord(text[i+m])) % q

if t < 0:
t = t+q

text = "ABCCDDAEFG"
pattern = "CDD"
q = 13
search(pattern, text, q)

OUTPUT :

Pattern is found at position: 4

Explanation :

Step-by-step approach:
 Initially calculate the hash value of the pattern.
 Start iterating from the starting of the string:
 Calculate the hash value of the current substring having length m.
 If the hash value of the current substring and the pattern are same check if the substring
is same as the pattern.
If they are same, store the starting index as a valid answer. Otherwise, continue for the

next substrings.
 Return the starting indices as the required answer.
Time Complexity:
 The average and best-case running time of the Rabin-Karp algorithm is O(n+m), but its worst-case
time is O(nm).
 The worst case of the Rabin-Karp algorithm occurs when all characters of pattern and text are the
same as the hash values of all the substrings of T[] match with the hash value of P[].

Algorithm:

n = t.length
m = p.length
h = dm-1 mod q
p=0
t0 = 0
for i = 1 to m
p = (dp + p[i]) mod q
t0 = (dt0 + t[i]) mod q
for s = 0 to n - m
if p = ts
if p[1.....m] = t[s + 1..... s + m]
print "pattern found at position" s
If s < n-m
ts + 1 = (d (ts - t[s + 1]h) + t[s + m + 1]) mod q
EXERCISE 3

3. Examine the time complexity of Merge Sort through the application of the divide and conquer technique

def merge_sort(alist, start, end):


'''Sorts the list from indexes start to end - 1 inclusive.'''
if end - start > 1:
mid = (start + end)//2
merge_sort(alist, start, mid)
merge_sort(alist, mid, end)
merge_list(alist, start, mid, end)

def merge_list(alist, start, mid, end):


left = alist[start:mid]
right = alist[mid:end]
k = start
i=0
j=0
while (start + i < mid and mid + j < end):
if (left[i] <= right[j]):
alist[k] = left[i]
i=i+1
else:
alist[k] = right[j]
j=j+1
k=k+1
if start + i < mid:
while k < end:
alist[k] = left[i]
i=i+1
k=k+1
else:
while k < end:
alist[k] = right[j]
j=j+1
k=k+1

alist = input('Enter the list of numbers:


').split() print(alist)
alist = [int(x) for x in alist]
merge_sort(alist, 0, len(alist))
print('Sorted list: ', end='')
print(alist)

Explanation :

Step 1 − if it is only one element in the list it is already sorted, return.


Step 2 − divide the list recursively into two halves until it can no more be divided.
Step 3 − merge the smaller lists into new list in sorted order.

The split() method splits a string into a list.


print('Sorted list: ', end='') : ends the output with a space

Time Complexity : Worst,Best, Avg case : O(n log n)


OUTPUT:
Enter the list of numbers: 10 3 4 5 76
['10', '3', '4', '5', '76']
Sorted list: [3, 4, 5, 10, 76]
EXERCISE 4
4. Examine the time complexity of Quick Sort employing the divide and conquer technique

def quicksort(alist, start, end):

'''Sorts the list from indexes start to end - 1 inclusive.'''

if end - start > 1:

p = partition(alist, start, end)

quicksort(alist, start, p)

quicksort(alist, p + 1, end)

def partition(alist, start, end):

pivot = alist[start]

i = start + 1

j = end - 1

while True:

while (i <= j and alist[i] <= pivot):

i=i+1

while (i <= j and alist[j] >= pivot):

j=j-1

if i <= j:

alist[i], alist[j] = alist[j], alist[i]

else:

alist[start], alist[j] = alist[j], alist[start]

return j

alist = input('Enter the list of numbers:

').split() alist = [int(x) for x in alist]

quicksort(alist, 0, len(alist))

print('Sorted list: ', end='')

print(alist)
Explanation : Refer the link https://www.geeksforgeeks.org/quick-sort/
Time Complexity : Best and Avg case : O(n log n),Worst Case :O(n2)

OUTPUT:

Enter the list of numbers: 20 3 1 56 43


Sorted list: [1, 3, 20, 43, 56]
EXERCISE 5

a) Create a program for executing Breadth-First Search (BFS) on a specified graph


b) Develop a program to execute Depth-First Search (DFS) on a provided graph.

a) BFS

graph = {
'5' : ['3','7'],
'3' : ['2', '4'],
'7' : ['8'],
'2' : [],
'4' : ['8'],
'8' : []
}
visited = [] #
List for
visited
nodes. queue
= []

def bfs(visited, graph,


node): #function for
BFS
visited.append(node)
queue.append(node)

while queue: # Creating


loop to visit each node m =
queue.pop(0)
print (m, end = " ")

for neighbour in graph[m]:


if neighbour not in visited:
visited.append(neighbour)
queue.append(neighbour)

# Driver Code
print("Following is the
Breadth-First Search")
bfs(visited, graph, '5')

E
x
p
l
a
n
a
t
i
o
n

:
c
r
e
a
t
e

q
u
e
u
e

Q
mark v as
visited and
put v into Q
while Q is
non-empty
remove the head u of Q
mark and enqueue all (unvisited) neighbors of u
Time Complexity : O(V+E)

OUTPUT:
Following is the
Breadth-First
Search 5 3 7 2 4
8

b) DFS
graph = {
'5' : ['3','7'],
'3' : ['2', '4'],
'7' : ['8'],
'2' : [],
'4' : ['8'],
'8' : []
}
visited = set() # Set to keep
track of visited nodes of
graph.

def dfs(visited, graph,


node): #function for
dfs if node not in
visited:
p
r
i
n
t

(
n
o
d
e
)

v
i
s
i
t
e
d
.
a
d
d
(
n
o
d
e
)
for
neighb
our in
graph[n
ode]:
dfs(visi
ted,
graph,
neighb
our)

# Driver Code
print("Following is
the Depth-First
Search") dfs(visited,
graph, '5')
Explanation :

DFS(G, u)
u.visited = true
for
e
a
c
h
v

G
.
A
d
j[
u
]
if
v.
v
is
it
e
d
=
=
f
al
s
e
DFS(G,v)
init() {
Fo
r

e
a
c
h

u
.
v
i
s
i
t
e
d

f
a
l
s
e
F
o
r

e
a
c
h

D
F
S
(
G
,

u
)
}

Time Complexity : O(V+E)

OUTPUT :
Following is
the Depth-
First Search 5
3
2
4
8
7

You might also like