You are on page 1of 13

Name: Vibhu Chandransh Bhanot

SID:19104059

Sol 1:
Using two for loops:-

int main()
{
int arr[100],i,j,N,flag=0;
cout<<"Enter the size of the array:";
cin>>N;
cout<<"\nEnter array elements:\n";
for(i=0;i<N;++i)
cin>>arr[i];
for(i=0;i<N-1;++i)
{
for(j=0;j<N;++j)
{
if(arr[i]==arr[j] && i!=j)
flag=1;
}
}
if(flag==0)
cout<<"\nIt does not have any duplicate elements!";
else
cout<<"\nIt has duplicate elements!";
return 0;
}

Improved solution:-

#include <iostream>
using namespace std;

int main()
{
int arr[100],i,j,N;
cout<<"Enter the size of the array:";
cin>>N;
cout<<"\nEnter array elements:\n";
for(i=0;i<N;++i)
cin>>arr[i];
for(i=0;i<N-1;++i)
{
for(j=i+1;j<N;++j)
{
if(arr[i]==arr[j])
break;
}
if(j!=N)
break;
}
if(i==N-1)
cout<<"\nIt does not have any duplicate elements!";
else
cout<<"\nIt has duplicate elements!";
return 0;
}

Complexity Comparision:-
The first solution has a complexity of n*n (quadratic).
There are no filters and each element in the array is being compared to every other element in the array.
In case, any match is found the flag value turns 1 and this is used as an indication after the outer loop ends.

Whereas in the improved solution only the worst case complexity is n*n i.e. when no element is duplicate.
In all the other cases the loop ends as soon as a duplicate element is encountered thus reducing the number of passes.

Also, the inner loop starts comparing from the next element of i(i.e. j=i+1) instead of starting from j=0 unlike the
first case.

Sol 2:
Complex solution:-

#include <iostream>
using namespace std;
int main()
{
int arr[100],i,j,N,k,flag=0;
int first,second;
cout<<"\nEnter the size of the array:";
cin>>N;
cout<<"\nEnter array elements:\n";
for(i=0;i<N;++i)
cin>>arr[i];
cout<<"\nEnter an element k:";
cin>>k;
for(i=0;i<N;++i)
{
for(j=0;j<N;++j)
{
if(arr[i]+arr[j]==k && i!=j)
{
first=arr[i];
second=arr[j];
flag=1;
}
}
}
if(flag==0)
cout<<"\nSum of no two elements in the array is equal to "<<k;
else
cout<<"\n"<<first<<"+"<<second<<"="<<k;
return 0;
}

Improved solution:-

#include <iostream>
using namespace std;
int main()
{
int arr[100],i,j,N,k;
int first,second;
cout<<"\nEnter the size of the array:";
cin>>N;
cout<<"\nEnter array elements:\n";
for(i=0;i<N;++i)
cin>>arr[i];
cout<<"\nEnter an element k:";
cin>>k;
for(i=0;i<N;++i)
{
for(j=i+1;j<N;++j)
{
if(arr[i]+arr[j]==k)
{
first=arr[i];
second=arr[j];
break;
}
}
if(j!=N)
break;
}
if(i==N)
cout<<"\nSum of no two elements in the array is equal to "<<k;
else
cout<<"\n"<<first<<"+"<<second<<"="<<k;
return 0;
}

Complexity Comparision:-
The first solution has a complexity of n*n (quadratic).
There are no filters and each element in the array is being compared to every other element in the array.
In case, any two elements in the array equals the given element the flag value turns 1 and this is used
as an indication only after the outer loop ends.

Whereas in the improved solution only the worst case complexity is n*n i.e. when no two elements in the array equa
l the
given element.In all the other cases the loop ends as soon as the required condition is satisfied thus reducing the
number of passes.Also, the inner loop starts comparing from the next element of i(i.e. j=i+1) instead of starting from

j=0 unlike the first case.

Sol 3:
a)Implementing stacks through array

#include <iostream>
using namespace std;
int pop(int[],int&);
int push(int[],int&,int);
void display(int[],int);
const int size=50;
int main()
{ int arr[size],item,top=-1,res;
char ch='y';
while(ch=='y'||ch=='Y')
{
cout<<"\nEnter item for insertion:";
cin>>item;
res=push(arr,top,item);
if(res==-1)
{
cout<<"OVERFLOW!!!Aborting insertion!!\n";
break;
}
cout<<"\nWant to insert more elements?(y/n)...";
cin>>ch;
}
cout<<"\nNow deletion begins..";
ch='y';
while(ch=='y'||ch=='Y')
{
res=pop(arr,top);
if(res==-1)
{
cout<<"UNDERFLOW!!Aborting!!\n";
break;
}
else
{
cout<<"\nElements deleted is:"<<res<<endl;
cout<<"\nThe stack now is:\n";
display(arr,top);
}
cout<<"\nWant to delete more elements(y/n)...";
cin>>ch;
}
return 0;
}
int pop(int arr[],int&top)
{
int ret;
if(top==-1)
return -1;
else
{
ret=arr[top];
top--;
}
return ret;
}
int push(int arr[],int& top,int ele)
{
if(top==size-1)
return -1;
else
{
top++;
arr[top]=ele;
}
return 0;
}
void display(int arr[],int top)
{
if(top==-1)
return;
cout<<arr[top]<<"<----\n";
for(int i=top-1;i>=0;i--)
cout<<arr[i]<<"\n";
}

b)Implementing stacks through linked list:

#include <iostream>
#include<stdlib.h>
using namespace std;
struct node
{
int info;
node*link;
};
class Stack
{
node*top;
public:
Stack()
{
top=NULL;
}
void push();
void pop();
void display();
~Stack();
};
void Stack::push()
{
node*temp=new node;
cout<<"\nEnter the element to be pushed:";
cin>>temp->info;
temp->link=top;
top=temp;
}
void Stack::pop()
{
if(top==NULL)
cout<<"UNDERFLOW!!!";
else
{
node*ptr=top;
top=top->link;
delete ptr;
}
}
void Stack::display()
{
node*temp=top;
while(temp!=NULL)
{
cout<<temp->info<<"->";
temp=temp->link;
}
cout<<"!!!\n";
}
Stack::~Stack()
{
node*temp;
while(top!=NULL)
{
temp=top;
top=top->link;
delete temp;
}
}

int main()
{ Stack st;
int ch;
while(1)
{
cout<<"\nMenu:\n1)push\n2)pop\n3)display\n4)exit\n";
cout<<"Enter your choice:";
cin>>ch;
switch(ch)
{
case 1: st.push();
break;
case 2: st.pop();
break;
case 3: st.display();
break;
case 4: exit(0);
default: cout<<"Wrong choice entered";
}
}
return 0;
}

Sol 4:
Queue implemented with Arrays:-

#include<iostream>
#include<process.h>
using namespace std;
const int Size=50;
int Queue[Size],Front=-1,rear=-1;
int Remove(int Queue[])
{int ret;
if(Front==-1)
return -1;
else
{
ret=Queue[Front];
if(Front==rear)
Front=rear=-1;
else Front++;
}
return ret;
}
int Insert(int Queue[],int ele)
{
if(rear==Size-1)
return -1;
else if(rear==-1)
{
Front=rear=0;
Queue[rear]=ele;
}
else
{
rear++;
Queue[rear]=ele;
}
return 0;
}
void Display(int SQueue[],int Front,int rear)
{
if(Front==-1)
return;
for(int i=Front;i<rear;++i)
cout<<Queue[i]<<"<-\t";
cout<<Queue[rear]<<"\n";
}
int main()
{
int Item,res;char ch='y';
while(ch=='y'||ch=='Y')
{
cout<<"\nEnter ITEM for insertion:";
cin>>Item;
res=Insert(Queue,Item);
if(res==-1)
{cout<<"OVERFLOW...\n";exit(1);}
cout<<"\nEnter the Queue(Front to rear) is:\n";
Display(Queue,Front,rear);
cout<<"\nWant to insert more elements?(y/n):";
cin>>ch;
}
cout<<"\nNow deletion of elements begins...\n";
ch='y';
while(ch=='y'||ch=='Y')
{
res=Remove(Queue);
if(res==-1)
{cout<<"UNDERFLOW......\n";;exit(1);}
else
{
cout<<"\nElement deleted is:\n";
Display(Queue,Front,rear);
}
cout<<"Want to delet more elements?(y/n):";
cin>>ch;
}
return 0;
}

Queue implemented with Linked List:-

#include<iostream>
#include<process.h>
using namespace std;
struct node
{int Data;
node *link;
};

class Queue
{
node *rear,*Front;
public:
Queue()
{
rear=NULL;
Front=NULL;
}
void push();
void pop();
void display();
~Queue();
};

void Queue::push()
{node *temp=new node;
cout<<"\nEnter the value to be pushed:";
cin>>temp->Data;
temp->link=NULL;
if(rear==NULL)
{
rear=Front=temp;
}
else
{
rear->link=temp;
rear=temp;
}
}

void Queue::pop()
{
if(Front==NULL)cout<<"UNDERFLOW!!!";
else
{
node *ptr=Front;
cout<<Front->Data<<" deleted\n";
Front=Front->link;
delete ptr;
if(Front==NULL)
rear=NULL;
}
}
void Queue::display()
{
node *temp=Front;
while(temp!=NULL)
{
cout<<temp->Data<<"->";
temp=temp->link;
}
cout<<"!!!\n";
}
Queue::~Queue()
{
node *temp;
while(Front!=NULL)
{
temp=Front;
Front=Front->link;
delete temp;
}
}
int main()
{Queue qt;int ch;
while(1)
{cout<<"Menu:\n1)push\n2)pop\n3)display\n4)exit\n";
cout<<"Enter your choice:";
cin>>ch;
switch(ch)
{case 1:qt.push();
break;
case 2:qt.pop();
break;
case 3:qt.display();
break;
case 4:exit(1);
default:cout<<"Wrong choice entered\n";
}
}
return 0;
}

Sol 5:
Algorithm:-

Required-array should have all the 1's first followed by all the 0's
/*Initialise segment variables*/
1. Set lb=0, ub=N-1 //where N is the size of the array
2. REPEAT steps 3 through 17
3. mid=INT((lb+ub)/2)
4. check if arr[mid]==1
5. if TRUE then proceed,else go to step 12
6. check if arr[mid+1]==0
7. if TRUE then proceed,else go to step 10
8. div=mid+1
9. break // get out of the loop (Step 18)
10.lb=mid+1
11.Go to step 17
12.check if arr[mid-1]==1
13.if TRUE then proceed,else go to step 16
14.div=mid
15.break // get out of the loop (Step 18)
16.ub=mid-1
17.Go to step 3
18.print div //the position of the first 0
19.END

Example Program:-

#include <iostream>
using namespace std;
void zerostart(int arr[],int N)
{
int lb,ub,mid,div;
lb=0;
ub=N-1;
while(1)
{
mid=(lb+ub)/2;
if(arr[mid]==1)
{
if(arr[mid+1]==0)
{
div=mid+1;
break;
}
else
lb=mid+1;
}
else
{
if(arr[mid-1]==1)
{
div=mid;
break;
}
else
ub=mid-1;
}
}
cout<<"\n"<<div<<" is the position of the first 0";
return;
}
int main()
{
int arr[10000];
int i,n,one,zero;
cout<<"\nEnter the no. of 1's:";
cin>>one;
cout<<"\nEnter the no. of 0's:";
cin>>zero;
n=one+zero;
for(i=0;i<one;++i)
arr[i]=1;
for(i=one;i<n;++i)
arr[i]=0;
zerostart(arr,n);
return 0;
}

Complexity:-
The algorithm is similar to that of a binary search. So, the complexity is logarithmic.
Explanation:
At Iteration 1,
Length of array = n
At Iteration 2,
Length of array = n⁄
At Iteration 3,
Length of array = (n⁄ )⁄ = n⁄
Therefore, after Iteration k,
Length of array = n⁄ k
Also, we know that after
After k divisions, the length of array becomes 1
Therefore
Length of array = n⁄ k = 1
=> n = 2k
Applying log function on both sides:
=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)
Therefore,
=> k = log2 (n)

Sol 6:
Algorithm:-
Required-array should have distinct ascending order of elements followed by descending
/*Initialise segment variables*/
1. Set lb=0, ub=N-1 //where N is the size of the array
2. REPEAT steps 3 through _
3. mid=INT((lb+ub)/2)
4. check if arr[mid]>arr[mid-1] and arr[mid+1]<arr[mid]
5. if TRUE then proceed,else go to step 8
6. k=mid
7. break //get out of the loop (Step 16)
8. check if arr[mid]>arr[mid-1] and arr[mid+1]>arr[mid]
9. if TRUE then proceed,else go to step 12
10.lb=mid+1
11.Go to step 15
12.check if arr[mid]<arr[mid-1] and arr[mid+1]>arr[mid]
13.if TRUE then proceed,else go to step 15
14.ub=mid-1
15.Go to step 3
16.print k //the index of the largest element
17.END

Example program:-

#include <iostream>
using namespace std;
void kfinder(int[],int);
int main()
{ int arr[100],n,i;
cout<<"\nEnter the size of the array:";
cin>>n;
cout<<"\nEnter the elements of the array:\n";
for(i=0;i<n;++i)
cin>>arr[i];
kfinder(arr,n);
return 0;
}
void kfinder(int arr[],int N)
{
int k,lb,ub,mid;
lb=0;
ub=N-1;
while(1)
{
mid=(lb+ub)/2;
if(mid==0||mid==N-1||(arr[mid]>arr[mid-1]&&arr[mid]>arr[mid+1]))
{
k=mid;
break;
}
else if(arr[mid]>arr[mid-1]&&arr[mid]<arr[mid+1])
lb=mid+1;
else if(arr[mid]<arr[mid-1]&&arr[mid]>arr[mid+1])
ub=mid-1;
}
cout<<"\n"<<k<<" "<<arr[k];
return;
}

Complexity:-
The algorithm is similar to that of a binary search. So, the complexity is logarithmic.
Explanation:
At Iteration 1,
Length of array = n
At Iteration 2,
Length of array = n⁄
At Iteration 3,
Length of array = (n⁄ )⁄ = n⁄
Therefore, after Iteration k,
Length of array = n⁄ k
Also, we know that after
After k divisions, the length of array becomes 1
Therefore
Length of array = n⁄ k = 1
=> n = 2k
Applying log function on both sides:
=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)
Therefore,
=> k = log2 (n)

*********************************************************************************************
*****

You might also like