0% found this document useful (0 votes)
15 views11 pages

ADD LAB MANUAL

The document outlines two exercises focusing on algorithmic complexities and matrix multiplication. The first exercise implements recursive and non-recursive algorithms for binary search and factorial calculation, while the second exercise implements Strassen's algorithm for efficient matrix multiplication using the divide-and-conquer approach. Both programs are executed successfully, demonstrating their respective functionalities.

Uploaded by

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

ADD LAB MANUAL

The document outlines two exercises focusing on algorithmic complexities and matrix multiplication. The first exercise implements recursive and non-recursive algorithms for binary search and factorial calculation, while the second exercise implements Strassen's algorithm for efficient matrix multiplication using the divide-and-conquer approach. Both programs are executed successfully, demonstrating their respective functionalities.

Uploaded by

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

EX.

NO : 01 IMPLEMENT RECURSIVING AND NON- RECURSIVING ALGORITHMS AND


BJB4
DATE :
STUDY THE ORDER OF GROWTH FROM LOG 2N TO N!

AIM :

To illustrate and compare various algorithmic complexities, focusing on their order of growth,
from logarithmic to factorial.

ALGORITHM:

Binary Search

1. Input: Define a sorted array and a target value.

2. Set left to 0 and right to the last index of the array.

3. While left ≤ right:

o Calculate mid as (left + right) / 2.

o If arr[mid] == target, output mid (found).

o If arr[mid] < target, set left to mid + 1.

o If arr[mid] > target, set right to mid - 1.

4. If not found, output -1.

 Factorial Calculation

1. Input: Define an integer n.

2. Recursive Method:

o If n == 0 or n == 1, return 1.

o Else, return n * factorial(n - 1).

3. Non-Recursive Method:

o Set result to 1.

o For i from 2 to n:

 Multiply result by i.

o Return result.
PROGRAM :

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int binarySearch(const vector<int>& arr, int target) {

int left = 0;

int right = arr.size() - 1

while (left <= right) {

int mid = left + (right - left) / 2;

if (arr[mid] == target) {

return mid; // Target found

if (arr[mid] < target) {

left = mid + 1;

} else {

right = mid - 1;

return -1; // Target not found

unsigned long long recursiveFactorial(int n) {

if (n <= 1) return 1;

return n * recursiveFactorial(n - 1);

unsigned long long nonRecursiveFactorial(int n) {

unsigned long long result = 1;

for (int i = 2; i <= n; ++i) {

result *= i;
}
return result;
}
void recursivePermutations(string str, string current) {
if (str.empty()) {
cout << current << endl; // Output permutation
} else {
for (size_t i = 0; i < str.size(); ++i) {
string newStr = str;
newStr.erase(i, 1); // Remove character at i
recursivePermutations(newStr, current + str[i]);
}
}
}
int main()
vector<int> sortedArr = {1, 3, 5, 7, 9, 11, 13, 15};
int target = 7;
int index = binarySearch(sortedArr, target);
if (index != -1) {
cout << "Element " << target << " found at index " << index << endl;
} else {
cout << "Element " << target << " not found." << endl;
}
int n = 5; // Change this value for testing
cout << "Factorial of " << n << " (Recursive): " << recursiveFactorial(n) << endl;
cout << "Factorial of " << n << " (Non-Recursive): " << nonRecursiveFactorial(n) << endl;
cout << "Permutations of 'abc':" << endl;
recursivePermutations("abc", "");
return 0;

}
OUTPUT :

Element 7 found at index 3

Factorial of 5 (Recursive): 120

Factorial of 5 (Non-Recursive): 120

Permutations of 'abc':

abc

acb

bac

bca

cab

cba
RESULT :

Thus, the program for recursive and non-recursive algorithm are given above are executed
successfully.
EX.NO : 02
DIVIDE AND CONQUER – STRASSEN’S MATRIX MULTILICATION
DATE :

AIM :

To implement Strassen’s algorithm for efficient matrix multiplication using the divide-and-
conquer approach.

ALGORITHM :

Input: Two square matrices A and B of size n x n

Output: Product matrix C = A x B

Strassen's Algorithm:

1. Base Case: If n = 1, return A[0][0] * B[0][0]

2. Split Matrices:

- Divide A into four quadrants: A11, A12, A21, A22

- Divide B into four quadrants: B11, B12, B21, B22

3. Compute Seven Products:

- M1 = (A11 + A22) x (B11 + B22)

- M2 = (A21 + A22) x B11

- M3 = A11 x (B12 - B22)

- M4 = A22 x (B21 - B11)

- M5 = (A11 + A12) x B22

- M6 = (A21 - A11) x (B11 + B12)

- M7 = (A12 - A22) x (B21 + B22)

4. Combine Results:

- C11 = M1 + M4 - M5 + M7

- C12 = M3 + M5

- C21 = M2 + M4

- C22 = M1 + M3 - M2 + M6

5. Combine Quadrants: Combine C11, C12, C21, C22 to form the final product matrix C
PROGRAM :

#include <iostream>

#include <vector>

using namespace std;

vector<vector<int>> add(const vector<vector<int>>& A, const vector<vector<int>>& B) {

int n = A.size();

vector<vector<int>> C(n, vector<int>(n));

for (int i = 0; i < n; ++i)

for (int j = 0; j < n; ++j)

C[i][j] = A[i][j] + B[i][j];

return C;

vector<vector<int>> subtract(const vector<vector<int>>& A, const vector<vector<int>>& B) {

int n = A.size();

vector<vector<int>> C(n, vector<int>(n));

for (int i = 0; i < n; ++i)

for (int j = 0; j < n; ++j)

C[i][j] = A[i][j] - B[i][j];

return C;

vector<vector<int>> strassen(const vector<vector<int>>& A, const vector<vector<int>>& B) {

int n = A.size();

if (n == 1) {

return {{A[0][0] * B[0][0]}};

int k = n / 2;

vector<vector<int>> A11(k, vector<int>(k)), A12(k, vector<int>(k));

vector<vector<int>> A21(k, vector<int>(k)), A22(k, vector<int>(k));


vector<vector<int>> B11(k, vector<int>(k)), B12(k, vector<int>(k));

vector<vector<int>> B21(k, vector<int>(k)), B22(k, vector<int>(k));

for (int i = 0; i < k; ++i) {

for (int j = 0; j < k; ++j) {

A11[i][j] = A[i][j];

A12[i][j] = A[i][j + k];

A21[i][j] = A[i + k][j];

A22[i][j] = A[i + k][j + k];

B11[i][j] = B[i][j];

B12[i][j] = B[i][j + k];

B21[i][j] = B[i + k][j];

B22[i][j] = B[i + k][j + k];

auto M1 = strassen(add(A11, A22), add(B11, B22));

auto M2 = strassen(add(A21, A22), B11);

auto M3 = strassen(A11, subtract(B12, B22));

auto M4 = strassen(A22, subtract(B21, B11));

auto M5 = strassen(add(A11, A12), B22);

auto M6 = strassen(subtract(A21, A11), add(B11, B12));

auto M7 = strassen(subtract(A12, A22), add(B21, B22));

vector<vector<int>> C(n, vector<int>(n));

for (int i = 0; i < k; ++i) {

for (int j = 0; j < k; ++j) {

C[i][j] = M1[i][j] + M4[i][j] - M5[i][j] + M7[i][j];

C[i][j + k] = M3[i][j] + M5[i][j];

C[i + k][j] = M2[i][j] + M4[i][j];

C[i + k][j + k] = M1[i][j] - M2[i][j] + M3[i][j] + M6[i][j];

}
}

return C;

void printMatrix(const vector<vector<int>>& matrix) {

for (const auto& row : matrix) {

for (int val : row) {

cout << val << " ";

cout << endl;

int main() {

vector<vector<int>> A = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};

vector<vector<int>> B = {{16, 15, 14, 13}, {12, 11, 10, 9}, {8, 7, 6, 5}, {4, 3, 2, 1}};

cout << "Matrix A:\n";

printMatrix(A);

cout << "\nMatrix B:\n";

printMatrix(B)

vector<vector<int>> C = strassen(A, B);

cout << "\nResult of A * B:\n";

printMatrix(C);

return 0;

}
OUTPUT :

Matrix A:

1234

5678

9 10 11 12

13 14 15 16

Matrix B:

16 15 14 13

12 11 10 9

8765

4321

Result of A * B:

80 70 60 50

240 214 188 162

400 358 316 274

560 502 444 386


RESULT :

Thus the above program has been executed successfully and the required output is displayed.

You might also like