0% found this document useful (0 votes)
7 views75 pages

SE , CN, CD files

The document contains a series of experiments focusing on various networking protocols and algorithms, including Bit Stuffing, Byte Stuffing, CRC Code, Hamming Code, IP address classification, Sliding Window Control, Distance Vector Algorithm, Flooding Algorithm, and Dijkstra Algorithm. Each experiment includes a brief aim, code implementation, and sample input/output. The experiments illustrate fundamental concepts in data communication and networking.
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)
7 views75 pages

SE , CN, CD files

The document contains a series of experiments focusing on various networking protocols and algorithms, including Bit Stuffing, Byte Stuffing, CRC Code, Hamming Code, IP address classification, Sliding Window Control, Distance Vector Algorithm, Flooding Algorithm, and Dijkstra Algorithm. Each experiment includes a brief aim, code implementation, and sample input/output. The experiments illustrate fundamental concepts in data communication and networking.
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/ 75

EXPERIMENT-1

AIM: Implement Bit Stuffing.


CODE:

#include <stdio.h>

#include <string.h>

int main() {

char data[100], stuffedData[200];

int i, count = 0, j = 0;

printf("Enter the data: ");

scanf("%s", data); for(i = 0; i <

strlen(data); i++) {

if(data[i] == '1') {

count++;

stuffedData[j++] = data[i];

} else {

count = 0;

stuffedData[j++] = data[i];

if(count == 5) {

count = 0;

stuffedData[j++] = '0';

stuffedData[j] = '\0'; printf("Data after bit

stuffing: %s\n", stuffedData); return 0;

INPUT/OUTPUT:
Enter the data: 11011111
Data after bit stuffing: 110111110
EXPERIMENT-2
AIM: Implement Byte Stuffing.
CODE:
#include <stdio.h>

#include <string.h>

void main(){

char frame[50][50], str[50][50];

char flag[10]; strcpy(flag,

"flag"); char esc[10];

strcpy(esc, "esc");

int i, j, k = 0, n;

strcpy(frame[k++], "flag");

printf("Enter length of String : \n");

scanf("%d", &n); printf("Enter the

String: "); for (i = 0; i <= n; i++)

gets(str[i]);

printf("\nYou entered :\n"); for (i = 0; i <= n; i++)

puts(str[i]); printf("\n"); for (i = 1; i <= n; i++){

if (strcmp(str[i], flag) != 0 && strcmp(str[i], esc) != 0)

strcpy(frame[k++], str[i]);

else{

strcpy(frame[k++], "esc");

strcpy(frame[k++], str[i]);

}
strcpy(frame[k++], "flag");

printf("------------------------------\n\n");

printf("Byte stuffing at sender side:\n\n");


printf("------------------------------

\n\n"); for (i = 0; i < k; i++){

printf("%s\t", frame[i]);

INPUT/OUTPUT:

Enter length of String : 8 Enter


the String:
1
1
0
0
0
0
1
0
You entered :
1
1
0
0
0
0
1
0
------------------------------

Byte stuffing at sender side:

------------------------------

flag 1 1 0 0 0 0 1 0 flag
EXPERIMENT-3
Aim: Implement CRC Code.
CODE:
#include<stdio.h>

#include<string.h> #define

N strlen(gen_poly) char

data[28]; char

check_value[28]; char

gen_poly[10]; int

data_length,i,j; void

XOR(){

for(j = 1;j < N; j++) check_value[j] = ((

check_value[j] == gen_poly[j])?'0':'1');

void receiver(){ printf("Enter the

received data: "); scanf("%s",

data); printf("Data received: %s",

data);

crc();

for(i=0;(i<N-1) && (check_value[i]!='1');i++);

if(i<N-1) printf("\nError

detected\n\n");

else

printf("\nNo error detected\n\n");

void crc(){

for(i=0;i<N;i++)

check_value[i]=data[i];

do{
if(check_value[0]=='1')

XOR();

for(j=0;j<N-1;j++)

check_value[j]=check_value[j+1];

check_value[j]=data[i++];

}while(i<=data_length+N-1);

int main(){ printf("\nEnter data to be

transmitted: ");

scanf("%s",data);
printf("\n Enter the Generating polynomial: ");
scanf("%s",gen_poly); data_length=strlen(data);
for(i=data_length;i<data_length+N-1;i++)
data[i]='0';
printf("\n Data padded with n-1 zeros : %s",data);
crc();
printf("\nCRC or Check value is :
%s",check_value);
for(i=data_length;i<data_length+N-1;i++)
data[i]=check_value[i-data_length]; printf("\n
Final data to be sent : %s",data);
receiver();
return 0;
}
INPUT/OUTPUT:
Enter data to be transmitted: 1001101
Enter the Generating polynomial: 1011
Data padded with n-1 zeros : 1001101000
CRC or Check value is : 101
Final data to be sent : 1001101101
Enter the received data: 1001101101
Data received: 1001101101
No error detected

In case of error-
Enter the received data: 1001001101
Data received: 1001001101
Error detected
EXPERIMENT-4
AIM : Implement Hamming Code.
CODE:
#include<stdio.h>
#include <math.h>
int input[32];
int code[32];
int ham_calc(int,int); void
main(){ int n,i,p_n =
0,c_l,j,k;
printf("Please enter the length of the Data Word: ");
scanf("%d",&n);
printf("Please enter the Data Word:\n");
for(i=0;i<n;i++)
scanf("%d",&input[i]);
i=0;
while(n>(int)pow(2,i)-(i+1)){
p_n++;
i++;} c_l =
p_n + n; j=k=0;
for(i=0;i<c_l;i++){
if(i==((int)pow(2,k)-1)){
code[i]=0;
k++;}
else{
code[i]=input[j];
j++;}}
for(i=0;i<p_n;i++){
int position = (int)pow(2,i);
int value = ham_calc(position,c_l);
code[position-1]=value; }
printf("\nThe calculated Code Word is: ");
for(i=0;i<c_l;i++)
printf("%d",code[i]); printf("\n");
printf("Please enter the received Code Word:\n");
for(i=0;i<c_l;i++)
scanf("%d",&code[i]);
int error_pos = 0;
for(i=0;i<p_n;i++){
int position = (int)pow(2,i);
int value = ham_calc(position,c_l);
if(value != 0)
error_pos+=position;}
if(error_pos == 1)
printf("The received Code Word is correct.\n");
else
printf("Error at bit position: %d\n",error_pos);
}
int ham_calc(int position,int c_l){
int count=0,i,j;
i=position-1; while(i<c_l){
for(j=i;j<i+position;j++){
if(code[j] == 1)
count++;}
i=i+2*position;
}
if(count%2 ==0)
return 0;
else return 1;
}
INPUT/OUTPUT:
Please enter the length of the Data Word: 8 Please enter
the Data Word:
1
1
0
1
0
0
1
1
The calculated Code Word is: 011110100011 Please
enter the received Code Word:
0
1
1
1
1
1
1
0
0
0
1
1
Error at bit position: 6
EXPERIEMENT – 05
AIM: Write a program to classify an IP address into classes.
CODE:
#include <stdio.h>

#include <stdlib.h> #include


<string.h> void
classify_ip_address(char *ip)
{ int octet; char *token

= strtok(ip, "."); if (token


== NULL)
{ printf("Invalid IP address
format\n"); return;

}
octet = atoi(token); if (octet
>= 0 && octet <= 127)
{ printf("Class
A\n");
}

else if (octet >= 128 && octet <= 191)

{ printf("Class
B\n");
}

else if (octet >= 192 && octet <= 223)

{ printf("Class

C\n");

else if (octet >= 224 && octet <= 239)

{ printf("Class D
(Multicast)\n");
}

else if (octet >= 240 && octet <= 255)

{ printf("Class E (Reserved for experimental


use)\n");
} else { printf("Invalid IP
address\n");

int main() { char ip[16];


printf("Enter an IP address: ");
scanf("%15s", ip); int dot_count
= 0, num_count = 0; for (int i = 0;
ip[i] != '\0'; i++)
{

if (ip[i] == '.')

dot_count++;

else if (ip[i] >= '0' && ip[i] <= '9')

{
num_count++;
}

else {

printf("Invalid character detected in IP address.\n");


return 1;
}

if (dot_count != 3 || num_count == 0)
{ printf("Invalid IP address
format.\n"); return 1;
}

classify_ip_address(ip);
return 0;
}

OUTPUT :
Enter an IP address: 147.255.123.0
Class B
EXPERIEMENT- 06
AIM: Write a code to implement Sliding Wait Control.
CODE:
#include<stdio.h> int main() { int
w,i,f,frames[50]; printf("Enter window size: ");
scanf("%d",&w); printf("\nEnter number of
frames to transmit: "); scanf("%d",&f);
printf("\nEnter %d frames: ",f);
for(i=1;i<=f;i++) scanf("%d",&frames[i]);
printf("\nWith sliding window protocol the frames will be sent in the following manner
(assuming no corruption of frames)\n\n");
printf("After sending %d frames at each stage sender waits for acknowledgement sent by
the receiver\n\n",w); for(i=1;i<=f;i++)
{

if(i%w==0)

printf("%d\n",frames[i]); printf("Acknowledgement of above


frames sent is received by sender\n\n");
} else

printf("%d ",frames[i]);

if(f%w!=0) printf("\nAcknowledgement of above frames sent is received


by sender\n");

return 0;

OUTPUT:
Enter window size: 3

Enter number of frames to transmit: 5

Enter 5 frames: 12 89 5 4 6

With sliding window protocol the frames will be sent in the following manner (assuming no
corruption of frames)

After sending 3 frames at each stage sender waits for acknowledgement sent by the receiver

12 89 5

Acknowledgement of above frames sent is received by sender

46

Acknowledgement of above frames sent is received by sender


EXPERIEMENT- 07
AIM: Write a code to implement Distance Vector Algorithm.
CODE:
#include<stdio.h>

int dist[50][50],temp[50][50],n,i,j,k,x;
void dvr(); int main() { printf("\nEnter
the number of nodes : ");
scanf("%d",&n); printf("\nEnter the
distance matrix :\n"); for(i=0;i<n;i++)
{
for(j=0;j<n;j++)

scanf("%d",&dist[i][j]);
dist[i][i]=0;
temp[i][j]=j; }
printf("\n");

dvr(); printf("enter value


of i &j:"); scanf("%d",&i);

scanf("%d",&j);

printf("enter the new cost");

scanf("%d",&x); dist[i][j]=x;

printf("After update\n\n");

dvr();

return 0;

} void
dvr() {
for (i = 0;

i < n;

i++)

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

for (k = 0; k < n; k++)

if (dist[i][k] + dist[k][j] < dist[i][j])

{ dist[i][j] =

dist[i][k] + dist[k][j];

temp[i][j] = k;

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

printf("\n\nState value for router %d is \n",i+1);


for(j=0;j<n;j++) printf("\t\nnode %d via %d
Distance%d",j+1,temp[i][j]+1,dist[i][j]);
}

printf("\n\n");

OUTPUT:
Enter the number of nodes : 4

Enter the distance matrix :

12

9
16
20

18

15

32

41

24

51

State value for router 1 is

node 1 via 1 Distance0 node


2 via 2 Distance12 node 3
via 3 Distance9 node 4 via
4 Distance16

State value for router 2 is

node 1 via 1 Distance20


node 2 via 2 Distance0 node
3 via 3 Distance18 node 4
via 4 Distance4
State value for router 3 is node 1
via 1 Distance15 node 2 via 2
Distance8 node 3 via 3 Distance0
node 4 via 2 Distance12

State value for router 4 is

node 1 via 1 Distance41 node

2 via 2 Distance24 node 3


via 2 Distance42 node 4 via
4 Distance0

enter value of i &j:

1 3
enter the new cost

68
After update

State value for router 1 is

node 1 via 1 Distance0 node


2 via 2 Distance12 node 3

via 3 Distance9 node 4 via


4 Distance16

State value for router 2 is


node 1 via 1 Distance20 node 2 via 2 Distance0
node 3 via 3 Distance18 node 4 via 3
Distance30

State value for router 3 is

node 1 via 1 Distance15


node 2 via 2 Distance8 node
3 via 3 Distance0 node 4
via 2 Distance12

State value for router 4 is

node 1 via 1 Distance41 node

2 via 2 Distance24 node 3


via 2 Distance42 node 4 via
4 Distance0

--------------------------------
EXPERIEMENT- 08
AIM: Write a code to implement Flooding Algorithm.
CODE:
#include <stdio.h>

#include <stdlib.h>
#define MAX 100 int
graph[MAX][MAX];
int visited[MAX];

int nodes;

void flood(int current, int cameFrom) { visited[current] = 1;


printf("Packet reached node %d from node %d\n", current, cameFrom);
for (int i = 0; i < nodes; i++) { if (graph[current][i] && i !=
cameFrom) {

flood(i, current);

int main() { int edges;


printf("Enter number of nodes: ");
scanf("%d", &nodes);

printf("Enter number of edges: ");


scanf("%d", &edges);

printf("Enter edges (format: source destination):\n");


for (int i = 0; i < edges; i++) { int u, v;
scanf("%d %d", &u, &v);
graph[u][v] = 1; graph[v][u]

= 1;

} int source; printf("Enter source node to


start flooding: "); scanf("%d", &source);
printf("\nFlooding started:\n"); flood(source,
-1); return 0;
}

OUTPUT:
Enter number of nodes: 4

Enter number of edges: 4

Enter edges (format: source destination):

0 1

0 3

1 9

2Enter source node to start flooding: 0 Error!


Bookmark not defined.

Flooding started:

Packet reached node 0 from node -1

Packet reached node 1 from node 0

Packet reached node 3 from node 1 Packet


reached node 2 from node 0
EXPERIEMENT- 09
AIM: Write a code to implement Dijkstra Algorithm in Routing.
CODE:
#include <stdio.h>

#include <limits.h>

#define MAX 100

#define INF 99999

int graph[MAX][MAX];
int distance[MAX]; int
visited[MAX]; int
parent[MAX]; int
nodes;

void dijkstra(int start) { for


(int i = 0; i < nodes; i++) {
distance[i] = INF; visited[i]
= 0; parent[i] = -1;
}

distance[start] = 0;

for (int count = 0; count < nodes - 1; count++) {

int min = INF, u = -1;

for (int i = 0; i < nodes; i++) { if


(!visited[i] && distance[i] <= min) {
min = distance[i]; u = i;
}

visited[u] = 1;

for (int v = 0; v < nodes; v++) { if (!visited[v] && graph[u][v] &&


distance[u] + graph[u][v] < distance[v]) { distance[v] = distance[u] +
graph[u][v]; parent[v] = u;
}

void printPath(int j) {
if (parent[j] == -1)
return;
printPath(parent[j]);
printf(" -> %d", j);
}

void displayRoutes(int start) { printf("\nShortest paths from node %d:\n",


start); for (int i = 0; i < nodes; i++) { if (i != start) { printf("To
node %d: Distance = %d | Path = %d", i, distance[i], start);
printPath(i); printf("\n");
}

}
int main() { int edges;
printf("Enter number of nodes: ");
scanf("%d", &nodes);

printf("Enter number of edges: ");


scanf("%d", &edges);

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


for (int j = 0; j < nodes; j++)
graph[i][j] = 0;

printf("Enter edges and weights (format: source destination weight):\n");


for (int i = 0; i < edges; i++) { int u, v, w;

scanf("%d %d %d", &u, &v, &w);


graph[u][v] = w; graph[v][u] = w;
} int start; printf("Enter
starting node: "); scanf("%d",
&start); dijkstra(start);
displayRoutes(start);

return 0;

OUTPUT:
Enter number of nodes: 5

Enter number of edges: 6

Enter edges and weights:

012

024

121
137

243

3 4 1 Enter starting node: 0

Shortest paths from node 0:

To node 1: Distance = 2 | Path = 0 -> 1

To node 2: Distance = 3 | Path = 0 -> 1 -> 2

To node 3: Distance = 8 | Path = 0 -> 1 -> 3

To node 4: Distance = 6 | Path = 0 -> 1 -> 2 -> 4


Experiment 04:

Aim: Write program to find ε – closure of all states of any given NFA with ε
transition.
#include <bits/stdc++.h>

using namespace std;

int main(){

int n, m;

cin >> n >> m;

vector<vector<int>> e(n);

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

int u, v;

string sym;

cin >> u >> v >> sym;

if(sym == "eps")

e[u].push_back(v);

vector<set<int>> closure(n);

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

vector<bool> vis(n,false);

stack<int> st;

st.push(i);

vis[i] = true;

while(!st.empty()){

int u = st.top(); st.pop();

closure[i].insert(u);

for(int v : e[u]){
if(!vis[v]){

vis[v] = true;

st.push(v);

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

cout << "E-closure(" << i << ") = {";

bool first = true;

for(int s : closure[i]){

if(!first) cout << ",";

cout << s;

first = false;

cout << "}\n";

return 0;

INPUT-
47

0 1 eps

0 2 eps

03a

1 2 eps
13b

2 3 eps

30c

OUTPUT-
E-closure(0) = {0,1,2,3}
E-closure(1) = {1,2,3}
E-closure(2) = {2,3}
E-closure(3) = {3}
Experiment 05:

Aim: Write program to convert NFA with ε transition to NFA without ε


transition.
#include <bits/stdc++.h>

using namespace std;

int main(){

int n, m;

cin >> n >> m;

vector<vector<int>> eps(n);

vector<vector<pair<int,string>>> delta(n);

set<string> symbols;

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

int u, v; string sym;

cin >> u >> v >> sym;

if(sym == "eps") eps[u].push_back(v);

else {

delta[u].push_back({v, sym});

symbols.insert(sym);

vector<set<int>> eClos(n);

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

vector<bool> vis(n, false);

stack<int> st;

st.push(i);

vis[i] = true;
while(!st.empty()){

int u = st.top(); st.pop();

eClos[i].insert(u);

for(int v : eps[u]){

if(!vis[v]){

vis[v] = true;

st.push(v);

vector<map<string,set<int>>> newDelta(n);

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

for(auto &sym : symbols){

set<int> targets;

for(int q : eClos[i]){

for(auto &p : delta[q]){

if(p.second == sym){

for(int r : eClos[p.first])

targets.insert(r);

if(!targets.empty())

newDelta[i][sym] = move(targets);

}
}

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

for(auto &kv : newDelta[i]){

cout << "δ(" << i << "," << kv.first << ") = {";

bool first = true;

for(int s : kv.second){

if(!first) cout << ",";

cout << s;

first = false;

cout << "}\n";

return 0;

INPUT-
47

0 1 eps

0 2 eps

03a

1 2 eps

13b

2 3 eps

30c
OUTPUT-
δ(0,a) = {3}
δ(0,b) = {3}
δ(0,c) = {0,1,2,3}
δ(1,b) = {3}
δ(1,c) = {0,1,2,3}
δ(2,c) = {0,1,2,3}
δ(3,c) = {0,1,2,3}
Experiment 06:
Aim: Write program to convert NFA to DFA.

#include <bits/stdc++.h>
using namespace std;

set<int> epsilonClosure(const set<int>& states,


const vector<map<char, vector<int>>>& trans) {
stack<int> stk;
set<int> closure = states;
for (int s : states)
stk.push(s);

while (!stk.empty()) {
int u = stk.top(); stk.pop();
auto it = trans[u].find('e'); // 'e' for ε
if (it == trans[u].end()) continue;
for (int v : it->second) {
if (!closure.count(v)) {
closure.insert(v);
stk.push(v);
}
}
return closure;
}
set<int> moveStates(const set<int>& states, char a,
const vector<map<char, vector<int>>>& trans) {
set<int> result;
for (int s : states) {
auto it = trans[s].find(a);
if (it != trans[s].end()) {
result.insert(it->second.begin(), it->second.end());
}
}
return result;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<string> grid;
string line;
while (getline(cin, line)) {
if (line.empty()) break;
grid.push_back(line);
}
int N = grid.size();
vector<map<char, vector<int>>> trans(N);
set<char> alpha_set;
for (int i = 0; i < N; ++i) {
istringstream iss(grid[i]);
for (int j = 0; j < N; ++j) {
string cell;
iss >> cell;
if (cell != "-") {
char sym = cell[0];
trans[i][sym].push_back(j);
if (sym != 'e') alpha_set.insert(sym);
}
}
vector<char> alpha(alpha_set.begin(), alpha_set.end());
set<set<int>> dfaStates;
map<set<int>, set<int>> closures; // store ε-closures for printing
map<set<int>, char> name; // name DFA states A, B, ...
map<char, map<char, set<int>>> dfaTrans; // DFA transitions by set
queue<set<int>> q;
set<int> start_set = epsilonClosure({0}, trans);
dfaStates.insert(start_set);
closures[start_set] = start_set;
char nextName = 'A';
name[start_set] = nextName++;
q.push(start_set);

while (!q.empty()) {
auto T = q.front(); q.pop();
for (char a_sym : alpha) {
auto U = epsilonClosure(moveStates(T, a_sym, trans), trans);
if (U.empty()) continue;
if (!dfaStates.count(U)) {
dfaStates.insert(U);
closures[U] = U;
name[U] = nextName++;
q.push(U);
}
dfaTrans[name[T]][a_sym] = U;
}
cout << "The Epsilon Closures Are:\n";
for (int i = 0; i < N; ++i) {
set<int> single = epsilonClosure({i}, trans);
cout << "E(" << i << ")={";
for (int x : single) cout << x;
cout << "}\n";
}
cout << "\nDFA Table is:\n";
cout << "\t";
for (char a_sym : alpha) cout << a_sym << "\t";
cout << "\n";
vector<pair<char, set<int>>> order;
for (auto &p : name) order.emplace_back(p.second, p.first);
sort(order.begin(), order.end());
for (auto &pr : order) {
auto stSet = pr.second;
cout << "{";
for (int x : stSet) cout << x;
cout << "}\t";
for (char a_sym : alpha) {
if (dfaTrans[pr.first].count(a_sym)) {
auto &tgt = dfaTrans[pr.first][a_sym];
cout << "{";
for (int y : tgt) cout << y;
cout << "}";
} else {
cout << "{}";
}
cout << "\t";
}
cout << "\n";
}

return 0;
}
INPUT-
-ae-
--b-
---e
a---
OUTPUT-
The Epsilon Closures Are:
E(0)={023}
E(1)={1}
E(2)={23}
E(3)={3}
DFA Table is:
a b
{023} {0123} {}
{0123} {0123} {23}
{23} {023} {}
Experiment 07:

Aim: Write program to minimize any given DFA.


#include <bits/stdc++.h>

using namespace std;

const int MAX = 100;

int num_states, num_symbols;

vector<char> symbols;

int dfa[MAX][MAX];

bool final_states[MAX];

bool distinguishable[MAX][MAX];

void initialize_distinguishable() {

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

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

if (final_states[i] != final_states[j])

distinguishable[i][j] = true;

else

distinguishable[i][j] = false;

void mark_distinguable_pairs() {

bool changed;

do {

changed = false;

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


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

if (distinguishable[i][j]) continue;

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

int i1 = dfa[i][k];

int j1 = dfa[j][k];

if (i1 == j1) continue;

if (i1 < j1 && distinguishable[j1][i1] ||

i1 > j1 && distinguishable[i1][j1]) {

distinguishable[i][j] = true;

changed = true;

break;

} while (changed);

void print_minimised_dfa (const vector<set<int>>& classes) {

map<int,int> state_to_group;

for(int i=0;i<classes.size();i++) {

for (int state: classes[i]) {

state_to_group[state]=i;

cout<<"\nMinimised DFA transition table:\n";

cout<<"State\t";
for(char sym: symbols) cout<<sym<<"\t";

cout<<"Final\n";

for (int i=0;i<classes.size();i++) {

cout<<"G" << i<<"\t";

int rep=*classes[i].begin();

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

int next=dfa[rep][k];

cout<<"G"<<state_to_group[next]<<"\t";

bool is_final=false;

for (int s:classes[i]) {

if (final_states[s]) {

is_final=true;

break;

cout<<(is_final ? "Yes" :"No")<<endl;

void print_equivalence_classes() {

vector<set<int>> classes;

vector<bool> grouped(num_states, false);

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


if (grouped[i]) continue;

set<int> eq_class;

eq_class.insert(i);

grouped[i] = true;

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

if (i == j || grouped[j]) continue;

if (i < j && !distinguishable[j][i] ||

i > j && !distinguishable[i][j]) {

eq_class.insert(j);

grouped[j] = true;

classes.push_back(eq_class);

cout << "\nMinimized DFA State Groups:\n";

for (int i = 0; i < classes.size(); i++) {

cout << "Group " << i << ": ";

for (int state : classes[i]) {

cout << state << " ";

cout << endl;

print_minimised_dfa(classes);

}
int main() {

cout << "Enter number of states: ";

cin >> num_states;

cout << "Enter number of input symbols: ";

cin >> num_symbols;

symbols.resize(num_symbols);

cout << "Enter input symbols: ";

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

cin >> symbols[i];

cout << "Enter transition table (row: state, column: symbol index):\n";

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

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

cin >> dfa[i][j];

int num_final;

cout << "Enter number of final states: ";

cin >> num_final;

cout << "Enter final states: ";

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

int s;

cin >> s;

final_states[s] = true;
}

initialize_distinguishable();

mark_distinguable_pairs();

print_equivalence_classes();

return 0;

INPUT
4

01

01

10

23

32

23

OUTPUT
Enter number of states: Enter number of input symbols: Enter input symbols:
Enter transition table (row: state, column: symbol index):
Enter number of final states: Enter final states:
Minimized DFA State Groups:
Group 0: 0 1
Group 1: 2 3

Minimised DFA transition table:


State 0 1 Final
G0 G0 G0 No
G1 G1 G1 Yes
Experiment 08:

Aim: Develop an operator precedence parser for a given language.


#include <bits/stdc++.h>

using namespace std;

const char terminals[] = {'+', '-', '*', '/', '(', ')', 'i', '$'};

char table[8][8] = {

{'>', '>', '<', '<', '<', '>', '<', '>'}, // +

{'>', '>', '<', '<', '<', '>', '<', '>'}, // -

{'>', '>', '>', '>', '<', '>', '<', '>'}, // *

{'>', '>', '>', '>', '<', '>', '<', '>'}, // /

{'<', '<', '<', '<', '<', '=', '<', ' '}, // (

{'>', '>', '>', '>', ' ', '>', ' ', '>'}, // )

{'>', '>', '>', '>', ' ', '>', ' ', '>'}, // i

{'<', '<', '<', '<', '<', ' ', '<', '='} // $

};

int getIndex(char c) {

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

if (terminals[i] == c) return i;

return -1;

bool isOperator(char c) {

return c == '+' || c == '-' || c == '*' || c == '/';

}
string preprocess(string input) {

string res;

for (char c : input)

res += isalnum(c) ? 'i' : c;

return res;

void printStack(stack<char> s) {

vector<char> temp;

while (!s.empty()) {

temp.push_back(s.top());

s.pop();

for (auto it = temp.rbegin(); it != temp.rend(); ++it)

cout << *it;

void parse(string input) {

stack<char> st;

st.push('$');

input = preprocess(input);

input += '$';

int i = 0;

char a = input[i];

cout << "Stack\tInput\tAction\n";


while (true) {

char top;

stack<char> temp = st;

while (!temp.empty()) {

char c = temp.top(); temp.pop();

if (c != 'E') {

top = c;

break;

printStack(st);

cout << "\t" << input.substr(i) << "\t";

if (top == '$' && a == '$') {

cout << "Accept\n";

break;

int row = getIndex(top);

int col = getIndex(a);

char relation = (row != -1 && col != -1) ? table[row][col] : ' ';

if (relation == '<' || relation == '=') {

cout << "Shift " << a << "\n";


st.push(a);

i++;

a = input[i];

} else if (relation == '>') {

cout << "Reduce ";

char symbol = st.top(); st.pop();

if (symbol == 'i') {

cout << "id -> E\n";

st.push('E');

} else if (symbol == ')') {

if (st.top() == 'E') {

st.pop();

if (st.top() == '(') {

st.pop();

cout << "(E) -> E\n";

st.push('E');

} else { cout << "Error\n"; break; }

} else { cout << "Error\n"; break; }

} else if (symbol == 'E') {

if (!st.empty() && isOperator(st.top())) {

char op = st.top(); st.pop();

if (!st.empty() && st.top() == 'E') {

st.pop();

cout << "E " << op << " E -> E\n";

st.push('E');
} else { cout << "Error\n"; break; }

} else { cout << "Error\n"; break; }

} else { cout << "Error\n"; break; }

} else {

cout << "Error\n";

break;

int main() {

string input;

cin >> input;

parse(input);

return 0;

INPUT
(a+b)*c

OUTPUT
Stack Input Action
$ (i+i)*i$ Shift (
$( i+i)*i$ Shift i
$(i +i)*i$ Reduce id -> E
$(E +i)*i$ Shift +
$(E+ i)*i$ Shift i
$(E+i )*i$ Reduce id -> E
$(E+E )*i$ Reduce E + E -> E
$(E )*i$ Shift )
$(E) *i$ Reduce (E) -> E
$E *i$ Shift *
$E* i$ Shift i
$E*i $ Reduce id -> E
$E*E $ Reduce E * E -> E
$E $ Accept
Experiment 09:
Aim: Write program to find Simulate First and Follow of any given grammar.
#include <bits/stdc++.h>

using namespace std;

map<char, vector<string>> grammar;

map<char, set<char>> firstSet, followSet;

set<char> nonTerminals;

char startSymbol;

bool isNonTerminal(char c) {

return c >= 'A' && c <= 'Z';

void computeFirst(char symbol) {

if (!isNonTerminal(symbol)) {

firstSet[symbol].insert(symbol);

return;

for (const string& production : grammar[symbol]) {

if (production == "e") {

firstSet[symbol].insert('e');

continue;

}
for (char ch : production) {

computeFirst(ch);

for (char f : firstSet[ch]) {

if (f != 'e')

firstSet[symbol].insert(f);

if (firstSet[ch].find('e') == firstSet[ch].end())

break;

bool allEpsilon = true;

for (char ch : production) {

if (firstSet[ch].find('e') == firstSet[ch].end()) {

allEpsilon = false;

break;

if (allEpsilon)

firstSet[symbol].insert('e');

set<char> firstOfString(const string& str) {

set<char> result;

for (char ch : str) {


for (char f : firstSet[ch]) {

if (f != 'e')

result.insert(f);

if (firstSet[ch].find('e') == firstSet[ch].end())

return result;

result.insert('e');

return result;

void computeFollow(char symbol) {

if (symbol == startSymbol)

followSet[symbol].insert('$');

for (auto& rule : grammar) {

char lhs = rule.first;

for (const string& production : rule.second) {

for (size_t i = 0; i < production.length(); ++i) {

if (production[i] == symbol) {

if (i + 1 < production.length()) {

set<char> firstNext = firstOfString(production.substr(i + 1));

for (char f : firstNext) {

if (f != 'e')

followSet[symbol].insert(f);

}
if (firstNext.find('e') != firstNext.end()) {

if (lhs != symbol) {

computeFollow(lhs);

for (char f : followSet[lhs])

followSet[symbol].insert(f);

} else {

if (lhs != symbol) {

computeFollow(lhs);

for (char f : followSet[lhs])

followSet[symbol].insert(f);

int main() {

int n;

cout << "Enter number of productions: ";

cin >> n;

cout << "Enter productions (e.g., S->aB|b):\n";

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


string input;

cin >> input;

char lhs = input[0];

if (i == 0) startSymbol = lhs;

nonTerminals.insert(lhs);

size_t arrow = input.find("->");

string rhs = input.substr(arrow + 2);

stringstream ss(rhs);

string prod;

while (getline(ss, prod, '|')) {

grammar[lhs].push_back(prod);

for (char nt : nonTerminals) {

computeFirst(nt);

for (char nt : nonTerminals) {

computeFollow(nt);

cout << "\nFirst Sets:\n";

for (auto& p : firstSet) {

if (!isNonTerminal(p.first)) continue;

cout << "FIRST(" << p.first << ") = { ";


for (char c : p.second)

cout << c << " ";

cout << "}\n";

cout << "\nFollow Sets:\n";

for (auto& p : followSet) {

cout << "FOLLOW(" << p.first << ") = { ";

for (char c : p.second)

cout << c << " ";

cout << "}\n";

return 0;

INPUT
3

S->AB

A->a|e

B->b

OUTPUT
First Sets:
FIRST(A) = { a e }
FIRST(B) = { b }
FIRST(S) = { a b }

Follow Sets:
FOLLOW(A) = { b }
FOLLOW(B) = { $ }
FOLLOW(S) = { $ }
Experiment 10:
Aim: Construct a recursive descent parser for an expression.
#include <iostream>

#include <string>

using namespace std;

string input;

int pos = 0;

// Function declarations

bool E(), E_(), T(), T_(), F();

bool match(char expected) {

if (pos < input.size() && input[pos] == expected) {

pos++;

return true;

return false;

bool E() {

// E → T E'

if (T()) {

return E_();

return false;
}

bool E_() {

// E' → + T E' | ε

if (match('+')) {

if (T()) {

return E_();

return false;

return true; // ε

bool T() {

// T → F T'

if (F()) {

return T_();

return false;

bool T_() {

// T' → * F T' | ε

if (match('*')) {

if (F()) {

return T_();
}

return false;

return true; // ε

bool F() {

// F → (E) | i

if (match('i')) {

return true;

if (match('(')) {

if (E() && match(')')) {

return true;

return false;

return false;

int main() {

cout << "Enter expression (use 'i' for id): ";

cin >> input;

if (E() && pos == input.size()) {

cout << "Parsing successful!\n";


} else {

cout << "Syntax error.\n";

return 0;

INPUT
i+i*i

OUTPUT
Parsing successful!
Experiment 01
>>>Create a SRS document for e-banking system.
Software Requirements Specification (SRS) for E-Banking System

1. Introduction

1.1 Purpose
This document defines the software requirements for an E-Banking System, which allows customers
to perform banking transactions online securely and efficiently.

1.2 Scope
The E-Banking System will enable users to access their bank accounts, transfer funds, pay bills, check
balances, and manage personal information from a web-based or mobile platform.

1.3 Definitions, Acronyms, and Abbreviations

• E-Banking: Electronic Banking

• OTP: One-Time Password

• API: Application Programming Interface

• UI: User Interface

• DBMS: Database Management System

1.4 References

• Banking Industry Security Standards

• ISO 27001 Information Security Standard

• IEEE Standard for SRS Documentation

2. Overall Description

2.1 Product Perspective


The system integrates with the bank’s core system and provides a user-friendly interface for
customers to perform transactions securely.

2.2 Product Functions

• User Authentication and Authorization

• Account Management

• Fund Transfers

• Bill Payments

• Transaction History

• Customer Support
2.3 User Characteristics
The system will be used by customers, bank employees, and administrators. Customers may have
minimal technical knowledge, requiring an intuitive interface.

2.4 Constraints

• System must comply with banking regulations.

• High-level security measures like encryption and multi-factor authentication are mandatory.

• Should be accessible via web and mobile.

3. Specific Requirements

3.1 Functional Requirements

• User Registration and Login

• Secure Authentication (OTP, biometrics, etc.)

• Fund Transfers (Within Bank, Inter-Bank)

• Account Statement Viewing

• Transaction Confirmation Messages

• Admin Dashboard for Monitoring

3.2 Non-Functional Requirements

• High Availability (99.9% uptime)

• Performance Optimization

• Security Measures (Encryption, Secure APIs)

• Scalability for future growth

3.3 External Interface Requirements

• Web and Mobile Interface

• Integration with Core Banking System

• API for third-party applications

4. Appendices

• User Guidelines

• Security Policy

• Legal Compliance

Conclusion:
This is the SRS document for e-banking system.
Experiment 02
>>>Draw the use case diagram and specify the role of each of the actors for
ATM Machine. Also state the precondition, postcondition and function of each
use case.
Use Case Diagram for ATM Machine
An automated teller machine (ATM) or the automatic banking machine (ABM) is a banking
subsystem (subject) that provides bank customers with access to financial transactions in a
public space without the need for a cashier, clerk, or bank teller.
Customer (actor) uses bank ATM to Check Balances of his/her bank accounts, Deposit Funds,
Withdraw Cash and/or Transfer Funds (use cases). ATM Technician provides Maintenance
and Repairs. All these use cases also involve Bank actor whether it is related to customer
transactions or to the ATM servicing.
Actors:
1. Customer – Uses the ATM to perform transactions.
2. Bank System – The backend system that verifies account details and processes
transactions.
3. Technician – Maintains and repairs the ATM.

Use Cases:

1. Authenticate User – Customer inserts a card and enters a PIN for verification.

2. Withdraw Cash – Customer requests and receives cash.

3. Deposit Cash – Customer deposits money into their account.

4. Check Balance – Customer views account balance.

5. Transfer Funds – Customer transfers money between accounts.

6. Print Receipt – The ATM prints a transaction receipt.


7. Maintain ATM – The technician performs maintenance

Details for Each Use Case

1. Authenticate User

• Precondition: The ATM is powered on, and the user has an active bank card.
• Postcondition: The user is authenticated and can proceed with transactions.
• Function: Validate the card and PIN with the bank system.

2. Withdraw Cash

• Precondition: The user is authenticated, and the account has sufficient funds.
• Postcondition: Cash is dispensed, and the account balance is updated.
• Function: Deducts the amount from the account and dispenses cash.

3. Deposit Cash

• Precondition: The user is authenticated, and the ATM accepts deposits.


• Postcondition: The account balance is updated with the deposited amount.
• Function: Accepts cash or checks and credits them to the user’s account.

4. Check Balance

• Precondition: The user is authenticated.


• Postcondition: The user sees their account balance.
• Function: Retrieves and displays the account balance.

5. Transfer Funds

• Precondition: The user is authenticated and has sufficient balance.


• Postcondition: The funds are transferred to the recipient account.
• Function: Deducts money from one account and credits another.

6. Print Receipt

• Precondition: A transaction has been performed.


• Postcondition: A printed receipt is provided.
• Function: Generates and prints a receipt with transaction details.

7. Maintain ATM

• Precondition: The technician has access to the ATM.


• Postcondition: The ATM is serviced or repaired.
• Function: Allows technicians to check logs, refill cash, or fix issues.
use case diagram for Bank ATM subsystem

Bank ATM Transactions and Customer Authentication Use Cases


Bank ATM Maintenance, Repair, Diagnostics Use Cases

Conclusion:
This is the complete use case diagram for Bank ATM Machine.
Experiment 05
>>> Draw the sequence diagram for library management.
Sequence Diagram
A sequence diagram in UML (Unified Modelling Language) shows how objects interact with each
other in a particular time sequence. It’s particularly useful for understanding the flow of messages
and the order of operations in a system.

Components in the Diagram:


1. User – Initiates the book borrowing request.

2. Library System – Handles the core functionality (searching, issuing).

3. Book Copy – Represents individual book availability and lending operations.

4. Notification – Sends confirmations or updates to the user.


Sequence Flow Explained:
1. Search for Books (User → Library System)
• The user starts by searching for a book using the library system interface.

• This could include title, author, or subject queries.

2. Display Search Results (Library System → Book Copy)


• The system requests available book data from the Book Copy module.

• This involves querying the database.

3. Check Availability (Book Copy → Notification)


• Internally, the Book Copy component checks if the book is currently available for borrowing.

• Availability status is determined based on the number of available copies.

4. Book Available (Notification → Book Copy)


• The Notification module confirms the availability (may also log or trigger reminders).

5. Select Book (Library System ← User)


• Once results are shown, the user selects a specific book to borrow.

6. Borrow Book (Library System → Book Copy)


• A borrowing request is sent from the library system to the Book Copy to initiate lending.

7. Lend Book (Book Copy → Notification)


• The Book Copy system confirms the lending operation and updates the inventory.

• Notification is sent for confirmation or record-keeping.

8. Send Notification (Notification → Library System)


• A final notification is sent back to the library system to inform the user of a successful borrow
(email/SMS/in-app alert).

Sequence diagram for library management

Conclusion:
This is the sequence diagram of Library Management System.
Experiment 06
>>Draw Collaboration diagram for Library management or banking management.

For Library Management System

Definition:
A collaboration diagram, also called a communication diagram, emphasizes the interaction between
objects and the sequence of messages exchanged to complete a specific task.

Purpose in Library System:


In the library context, this diagram models how different components (such as the user, librarian,
book, and inventory system) collaborate when a user borrows a book.

Key Elements:
• Objects: User, Librarian, Book, Inventory System.

• Messages: Actions like requesting, checking availability, confirming, issuing, and updating
status.

• Flow: Sequence numbers indicate the order of interactions.

Use Case Example:


A user requests a book → librarian checks availability → inventory system confirms → book is issued
→ system updates records.

Diagram:

Conclusion:
This is the collaboration diagram for library management system.
Experiment 07
>>Draw State Chart diagram for Library management or banking management.

For Library Management System

Definition:
A state chart diagram represents the states of an object and the transitions between those states
triggered by events.

Purpose in Library System:


This diagram illustrates the lifecycle of a book as it moves through different states in the system.

Key Elements:
• States: Available, Issued, Reserved, Lost, Returned.

• Transitions: Triggered by actions such as issue(), return(), reserve(), or lost().

• Entry and Exit Points: The diagram helps in tracking book availability and managing
transitions based on user interactions or system rules.

Use Case Example:


A book is Available → Issued to a member → Returned → Available again. If lost or reserved, it
follows alternate paths.

Diagram:

Conclusion:

This is the State chart diagram for library management system.


Experiment 08
>>Draw Component diagram for Library management or banking management.
For Library Management System

Definition:
A component diagram depicts the organization and dependencies among a set of components in a
system.

Purpose in Library System:


This diagram shows how different modules or components (logical parts of the software) interact and
depend on each other to manage library functions.

Key Components:
• User Interface (UI): The front-end used by users and librarians.

• Database: Stores book data, user details, transactions.

• Book Component: Handles book-related operations.

• Member Component: Manages user registration and activity tracking.

• Admin Panel/Authentication (can be included): Manages roles and access control.

Use Case Example:


The UI interacts with both the book and member components, which in turn fetch data from the
central database.

Diagram:

Conclusion:
This is the Component diagram for library management system.
Activity diagram symbols:

You might also like