0% found this document useful (0 votes)
2 views66 pages

DS - Lecture Week 2

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

DS - Lecture Week 2

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

Subject: Data Structure

Using C++ (CSET243)

Week 2 Lecture

Algorithms, Time Complexity, Array,


and Searching
What, Why and How?
Data Structures: Types
Algorithm

Example:
Definition
Making a Delicious Tea
Step by step
procedures to solve
a problem

Input Output
Characteristics of Algorithm

• Effectiveness: Each steps must be feasible and essential to


the requirements

• Definiteness: Each instruction must be clear, well defined


and unambiguous

• Input & Output: Zero or more input but at least one output

• Finiteness: Finite number of steps and must terminate within


a finite amount of time
Why Algorithm

Once we find an algorithm for All the knowledge required for


solving a problem, we do not need solving the problem is present in
to re-discover it the next time we the algorithm.
are faced with that problem.

Makes it easy when explaining


the process to others
How Algorithm is different from Program

Algorithm Program
• A program is a set of instructions written in Programming
• An algorithm is a well-defined
Language (computer understandable language) to
sequence of steps (written in Natural
perform a certain task.
Language) to solve a given problem
• Program is an implementation of an algorithm
• Design Time
• Knowledge of Programming Language
• Domain Knowledge
• Testing
• Analyze
• Dependent on OS and H/W
• Independent from OS and H/W
How Algorithm is different from program

Example 5, 8, 2, 32, 12, 9, 11, 3


Algorithm of linear search : Program for Linear Search :

Step 1: Start from the leftmost element of


int search(int arr[], int n, int x)
arr[] and one by one compare x with each
{
element of arr[].
int i;
Step 2: If x matches with an element, return for (i = 0; i < n; i++)
the index.
if (arr[i] == x)
Step 3: If x doesn’t match with any of return i;
elements, return -1. return -1;
}
Pseudo Code

Example 5, 8, 2, 32, 12, 9, 11, 3


• It is one of the mathematical notation to represent an algorithm for a
Pseudocode for linear search : program.
function linearsearch(list, searchterm):
• It does not have a specific syntax like any of the programming
for index from 0 -> length(list):
languages and thus cannot be executed on a computer.
if list[index] == searchterm then
• It is easier to read and understood by programmers who are familiar
return index
with different programming languages.
endif
• Pseudocode allows you to include several control structures such as
endloop
While, If-then-else, Repeat-until, for and case, which is present in
return -1 many high-level languages.

end function
Note: Pseudocode is not an actual programming language.
Role of Algorithm Designer

Algorithm
Can I do
Designer
better?
Analysis of Algorithms
• Given a particular problem of size n. The time required by any algorithm for solving, this problem
is denoted by a function such as f(n).

Time complexity defines the total amount of time an algorithm needs to


execute all its key statements and in generating the output. (running time)

Space Complexity: Amount to memory needed by the algorithm for its


completion.

Good Algorithm: Solve a problem in less amount of time or space


complexity or both.
Analysis of Algorithms
Problem Statement: Finding a number X from a given list of
numbers.

Example 5, 8, 2, 32, 12, 9, 11, 3

For n input size, we perform the three types of analysis −

• Worst-case − The maximum amount of time needed by the algorithm to complete a


task (worst data or worst input size)

• Best-case − The minimum amount of time needed by the algorithm to complete a task
(best data or best input data)

• Average case − The average amount of time needed by the algorithm to complete a
task
Write Algorithms
• Swap Two Numbers
Write an algorithm to swap the values of two variables.
• Find the Largest of Three Numbers
Write an algorithm to find the largest number among three given inputs.
• Check if a Number is Even or Odd
Write an algorithm to determine whether a given integer is even or odd.
• Sum of First N Natural Numbers
Write an algorithm to calculate the sum of the first N natural numbers.
• Check if a Number is Prime
Write an algorithm to determine if a given number is prime.
• Find the Maximum Element in an Array
Write an algorithm to find the largest number in an array of integers.
Analysis of Algorithms- How?

Problem Statement
Searching a X Student in a Class

A A
Algorithm Algorithm
11 22
Given two algorithms for the above task,
how do we find out which one is
Analysis of Algorithms – How?

Problem Statement
Searching a X Student in a Class A A
Algorithm Algorithm
11 22
Method-1

Implement both the algorithms (run the two


programs) on your computer for some inputs
and see which one takes less time.
Analysis of Algorithm – How?

Problem Statement
Searching a X Student in a Class

A A
Algorithm Algorithm
Problem 11 22
It might also be possible that for some
inputs, first algorithm perform better
on one machine and the second works
Machine 1 Machine 2
better on other machine.
Analysis of Algorithms – How?

Apriori and Apostiari Analysis

• Apriori analysis means analysis is performed prior to running it on a specific system.

 We determine the time and space complexity of an algorithm by just looking at the
algorithm rather than running it on a particular system with a different memory,
processor, and compiler. (Theoretical Analysis)

• Apostiari analysis of an algorithm means we perform analysis of an algorithm only


after running it on a system. It directly depends on the system and changes from system
to system. (Empirical Analysis)
Asymptotic Notation
The main idea of asymptotic analysis is to have a measure of the complexity of algorithms that don’t depend on
machine-specific constants.

It doesn’t require algorithms to be implemented and the time taken by programs to be compared.

It is used for very large value of n (data sets)

Different types of asymptotic notations are used to represent the complexity of an algorithm.

O − Big Oh (Tightly Upper Bound)

Ω − Big omega (Tightly Lower Bound)

θ − Big theta (both Lower and Upper Bound)

o − Little Oh (Strictly Upper Bound)

ω − Little omega (Strictly Lower Bound)


Example of Asymptotic Analysis
(Best suitable for very large value of n or data sets)

~ 35 Lakh
Price: 35 Lakh Price: 10,000/-

• The simplest example is a function ƒ (n) = n2 + 3n, the term 3n


becomes insignificant compared to n2 when n is very large.

• The function "ƒ (n) is said to be asymptotically equivalent to n 2 as


n → ∞", and here is written symbolically as ƒ (n) ~ n2.
O − Big Oh Notation

• Tightly Upper Bound of an Algorithm

• Given a particular problem of size n. The time required by any algorithm for solving this
problem is denoted by a function such as f(n).

Let's assume, f(n) and g(n) are two functions

f(n) = O(g(n)) if there exists a positive integer n 0

and a positive constant c, such that


f(n) ≤ c.g(n) ∀ n≥n 0
O − Big Oh Notation

Consider the following f(n) and g(n); f(n) = 3n + 2 and g(n) = n

If we want to represent f(n) as O(g(n)) then it must satisfy


f(n) <= C g(n) for all values of C > 0 and n>= n0,

f(n) <= C g(n) ⇒ 3n + 2 <= C n  3n + 2 <= 5n for all value of n >1


The above condition is always TRUE for all values of C = 5 and n 0 = 1.

By using Big - Oh notation

we can represent the time complexity as follows- f(n)= 3n + 2 = O(n)


Increase your Imagination

Example-2, Can we say 2n2 = O(n3) ?


O- Big Oh

f(n) = O(g(n)) if there exists

Assume that f(n) = 2n2, and g(n) = n3 , f(n) = O(g(n)) ? a positive integer n 0 and a

positive constant c, such


Now we have to find the existence of c and n0
that f(n)≤c.g(n) ∀
f(n) ≤ c.g(n)  2n2 ≤ c.n3  2 ≤ c.n
n≥n 0
if we take, c = 1 and n0= 2 OR c = 2 and n0= 1 then 2n2 ≤ c.n3 ,

Hence f(n) = O(g(n)), c = 1 and n0= 2


General Assessment Time
10
9
8
7
6
5
4
3
2
1

Question -1
F(n) = 1000 n2 + 5n3 + 6000n,
What is the Order of Function ?

a) f(n)= O(n2)
Which one is the
b) f(n)= O(6000n)
correct answer?
c) f(n)= O(n3)

d) I am confused
Correct Answer is c
General Assessment Time
10
9
8
7
6
5
4
3
2
1
Question -2
F(n) = n3 D(n) = n4 E(n) = n6
T(n)= F(n) + D(n) + E(n)
What is the Order of Function O(T(n))= ?

a) T(n)= O(n3)
Which one is the
b) T(n)= O(n6)
correct answer?
c) T(n)= O(n4)

Correct Answer is b d) None of the Above


Type and Comparison of Order of Function of Classes
(Valid for larger values of n)

O(1)< O(logn)< O(√n)< O(n)


< O(nlogn)< O(n2<
) O(n3)< O(2n<
) O(10n)< O(nn)

Log2n n n 2
n 3
2 n
n
n

n=1 0 1 1 1 2 1
n=2 1 2 4 8 4 4
n=4 2 4 16 64 16 256
n=8 3 8 64 512 256 1,67,77,216

n=10 3.2 10 100 1000 1024 10 10


Type and Comparison of Order of Function of Classes
(Valid for larger values of n)
Analyzing Time Complexity

Time Complexity: Time complexity defi nes the total amount of


time an algorithm needs to execute all its key statements and
in generating the output. (running time)

Algorithm of Swapping Two Numbers

Algorithm Swap
(a, b)
{ 1 unit of
temp=a; time
1 unit of
a=b; time
1 unit of
b=temp; time
} Total= 3 unit of time = O(1) = constant
*Assume that every statement take one unit of time for
Analyzing Time Complexity
Time Complexity: Time complexity defi nes the total amount of time an algorithm
needs to execute all its key statements and in generating the output. (running
time)
n=
Algorithm of Sum of n number Algorithm Sum (A, n) 5 4
A 6 3 8 1
{
= 0 1 2 3 4
S=0; 1
Sum instructions will be executed
for ( i=0; i<n; i++) n+ i=0
i=0 -> 1 i=1 Sum instructions will be executed
{ i++ -> n 1 Sum instructions will be executed
i<n -> n+1 i=2
S= S + A[i]; n Sum instructions will be executed
i=3
} Sum instructions will be executed
i=4
return S; 1 i<n Sum instructions will not execute
i=5
} condition checked 6
f(n) = timesi has changed 5
i++,
times
*Assume that every statement take one unit of time for execution 2n+3
Understanding Space
Complexity
Algorithm of Swapping Two Numbers

Algorithm Swap (a, Total


b) Variable 1 word
{
temp=a; a 1 word

a=b; b 1 word

b=temp; temp
} Total= 3 words
Space Complexity= s(n)= constant =
*Assume that every variable takes one word space for storage
Understanding Space
Complexity
Sum of n
number
Algorithm Sum (A, n) Space Complexity
{
S=0; A ----->n
for ( i=0; i<n; i++) n------>1
{ S------>1
S= S + A[i];
i------>1
}
return S; S(n) = n+3 =
} O(n)
General Assessment Time
10
9
8
7
6
5
4
3
2
1

What is the Time Complexity of


this algorithm?
A) O(1)
Algorithm print(n)
{ B) O(100)
for ( i=0; i<n; i++)
{ C) O(n)
printf(“This is number:
%d”, i); D) None of the Above
}
}
Correct Answer: C
General Assessment Time
10
9
8
7
6
5
4
3
2
1

What is the Space Complexity


of this algorithm?
A) O(1)
Algorithm print(n)
{ B) O(100)
for ( i=0; i<n; i++)
{ C) O(n)
printf(“This is number:
%d”, i); D) None of the Above
}
}
Correct Answer: A
What is Array Data
Structure ??
DS- Array
• An array is a Linear type data structure used to
store a collection of data of same type.

• All arrays consist of contiguous memory


locations.

Syntax type arrayName [arraySize];

• Element − Each item stored in an array is called an element.

• Index − Each location of an element in an array has a numerical


index, which is used to identify the element.
Uses of Array DS
• Arrays allow us to store multiple values of the same data type using a single variable.

• Arrays support fast, direct access to elements using an index.

• Arrays can be easily looped through, which is useful for processing data.

• Arrays are stored in contiguous memory locations, which improves memory access
speed and performance, especially in lower-level languages like C/C++.

• Arrays can represent complex structures like matrices, images, and tables.
Array Initialization

double balance[10];

Type Array size


name elements

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};


Array Visualization in Memory

int arr[5];

base address

Meaning of contiguous memory allocations


Array Program
Storing the arrays values Printing the arrays value
#include <iostream>
using namespace std; for (i = 0; i < 5; i++)

int main() { cout<<var[i];


{
}
int var[5], i;
for (i = 0; i < 5; i++)
{ return 0;

cin>>var[i]; }
}
General Assessment Time
10
9
8
7
6
5
4
3
2
1
#include <iostream>
using namespace std; Which one is the
int main() correct answer?
{
a) 25
int a[] = {1,2,3,4};
b) 52
int b[4] = {5,6,7,8};
c) 36
Correct Answer is c cout<< a[2] << b[1];
d) 63
return 0;
}
Operations on Array

• Traverse − print all the array elements one by one.

• Insertion − Adds an element at the given index.

• Deletion − Deletes an element at the given index.

• Update − Updates an element at the given index.

• Search − Searches an element using the given index or by the value.

• Sorting – Arrange the elements in ascending or descending order


Traversing (printing) Array Elements

#include <iostream>
using namespace std;
int main(){
int num[] = {2,8,7,6,0};
int n = sizeof (num) / sizeof(num[0]);
for (int i = 0; i < n; i++)
Time Complexity
{
cout<< num[i]; Time Complexity for Traversal – O(n)
(in all cases)
}
return 0;
}
Insertion − Adding an element

Add an Element 9 #include <iostream>


using namespace std;
int main(){
int num[] = {2,8,7,6,0};
int n = sizeof (num) / sizeof(num[0]);
No Space in the Existing Array, for (int i = 0; i < n; i++)

We can not add any new element. {


cout<< num[i];
}
return 0;
}
Insertion − Adding an element

Create New Space before adding an element


int new_element=9;
int num[] = {2,8,7,6,0};
int n = sizeof (num) / sizeof(num[0]);
2 8 7 6 0
N=n+1;
New Element can be added

1. At the end of the array

2. At the beginning or at any index


Insertion − Adding an element

Case 1 : Add the new element at the end of the array


#include <iostream>
using namespace std;
int main() {
int new_element = 9;
int num[] = {2, 8, 7, 6, 0};
int old_size = sizeof(num) / sizeof(num[0]); 2 8 7 6 0 9
int new_size = old_size + 1;
int updated[new_size];
for (int i = 0; i < old_size; i++) { Time Complexity
updated[i] = num[i]; }
Copying existing elements: O(n)
updated[new_size - 1] = new_element;
Time Complexity of Insertion at the
for (int i = 0; i < new_size; i++) { end of array – O(1)
cout << updated[i] << " "; } return 0;} Total Time Complexity: O(n)
Insertion − Adding an element

Case 2 : Add the new element at the beginning of the array

int new_element = 9 2 8 7 6 0
int num[]={2,8,7,6,0};
int n = sizeof (num) / sizeof(num[0]);

n=n+1; Beginning of the array


Insertion − Adding an element

Case 2 : Add the new element at the beginning of the array

Shifting element to the next available space

2 8 7 6 0

Beginning of the array


Insertion − Adding an element

Case 2 : Add the new element at the beginning of the array

2 8 7 6 0
Shifting last element to
the next available space
Beginning of the array
Insertion − Adding an element

Case 2 : Add the new element at the beginning of the array

int num[] = {2, 8, 7, 6, 0};


int old_size = sizeof(num) / sizeof(num[0]);
int new_size = old_size + 1; 2 8 7 6 0
int updated[new_size]; // New array with
0 1 2 3 4 5
space for new element num[0] num[1] num[2] num[3] num[4] num[5]
// Step 1: Insert new element at beginning
updated[0] = new_element;
// Step 2: Shift old elements to the right
for (int i = 0; i < old_size; i++) {
9 2 8 7 6 0
updated[i + 1] = num[i];
}
Insertion − Adding an element
Case 2 : Add the new element at the
beginning of the array
int num[]={2,8,7,6,0};
int n = sizeof (num) / sizeof(num[0]);
2 8 7 6 0
num[0] num[1] num[2] num[3] num[4] num[5]

n=n+1;
int num[new_size]; for (i = n-1; i <=1; i--) Time Complexity
num[5]=num[4];
{ Time Complexity– O(n)
num[4]=num[3];
num[3]=num[2]; num[i] = num[i-1];
num[2]=num[1]; }
num[1]=num[0];
num[i]=new_element;
num[0]=new_element;
Insertion − Adding an element

Case 3 : Add the new element at some index of an array


int num[] = {2, 8, 7, 6, 0};
int new_element = 12;
int index = 2;
2 8 7 6 0
int old_size = sizeof(num) / sizeof(num[0]);
num[0] num[1] num[2] num[3] num[4] num[5]
int new_size = old_size + 1;

int updated[new_size];

// Copy elements before index


for (int i = 0; i < index; i++) {
updated[i] = num[i];
} At this index of the array
// Insert new element
updated[index] = new_element;
Time Complexity
// Copy remaining elements
for (int i = index; i < old_size; i++) { Time Complexity– O(n)
updated[i + 1] = num[i];
}
Deletion of an element in Array

Element can be deleted

1. At the end of the array

2. At the beginning or at any index


You cannot actually remove an element from a static array in C++. Arrays are fixed in size. But you
can simulate deletion by:
•Reducing the logical size of the array
•Ignoring the last element in future operations
Deletion of an element in Array

Case 1 : Element can be deleted at the end of the array

Last element of the array int num[] = {2, 8, 7, 6, 0};


int size = sizeof(num) / sizeof(num[0]);
Just reduce the one size of the array
size = size - 1; // Reduce logical size

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


Time Complexity cout << num[i] << " ";
}
Time Complexity of Deletion– O(1)
Deletion of an element in Array

Case 2 : Element can be deleted at the any Index of the array

8 7 6 0
num[0] num[1] num[2] num[3] num[4]
Element at Index 0 of the array

You cannot actually remove an element from a static array because its size is fixed. But
you can simulate deletion by shifting elements to the left and reducing the logical size.

nt num[] = {2, 8, 7, 6, 0};


int size = sizeof(num) / sizeof(num[0]);
int index = 0; // Delete element at index 0

if (index >= 0 && index < size) {


8 7 6 0
for (int i = index; i < size - 1; i++) {
num[i] = num[i + 1]; // Shift elements left
}
size--; // Logical deletion Time Complexity of Deletion– O(n)
Basic Array Operations Using std::vector in C++
In C++, a vector is a dynamic array provided by the Standard Template Library
(STL) that can grow or shrink in size automatically.

Initial Vector: vector<int> num = {2, 8, 7, 6, 0};


Insertion at End: num.push_back(12);
Insertion at Beginning: num.insert(num.begin(), 5);
Insertion at Index 2: num.insert(num.begin() + 2, 99);
Deletion from End: num.pop_back();
Deletion from Beginning: num.erase(num.begin());
Deletion from Index 2: num.erase(num.begin() + 2);
Time Complexity
Insert at End: O(1) (amortized)
Insert at Beginning/Index: O(n)
Delete from End: O(1)
Delete from Beginning/Index: O(n)
Dynamic Array in C++ using std::vector
#include <iostream>
#include <vector>
/ Insert at index 2
using namespace std;
int index_to_insert = 2;
num.insert(num.begin() + index_to_insert, 99);
void printVector(const vector<int>& vec) {
cout << "After inserting 99 at index 2: ";
for (int val : vec) {
printVector(num);
cout << val << " ";
}
// Delete from end
cout << endl;
num.pop_back();
}
cout << "After deleting element from end: ";
int main() { printVector(num);
// Initial vector
vector<int> num = {2, 8, 7, 6, 0}; // Delete from beginning
cout << "Initial vector: "; num.erase(num.begin());
printVector(num); cout << "After deleting element from beginning: ";
printVector(num);
// Insert at end
num.push_back(12); // Delete from index 2
cout << "After inserting 12 at end: "; int index_to_delete = 2;
printVector(num); if (index_to_delete < num.size()) {
num.erase(num.begin() + index_to_delete);
// Insert at beginning cout << "After deleting element at index 2: ";
num.insert(num.begin(), 5); printVector(num);
cout << "After inserting 5 at beginning: "; } else {
printVector(num); cout << "Index out of bounds for deletion." << endl;
}
General Assessment Time
10
9
8
7
6
5
4
3
2
1

Array in C++ indicates?

A) A group of elements of same data type.

B) An array contains more than one element

C) Array elements are stored in memory in continuous or


contiguous locations.

Answer: D D) All the above.


General Assessment Time
10
9
8
7
6
5
4
3
2
1

Choose a correct statement about arrays ?

A) An array size can not change once it is created.

B) Array element value can be changed any number of times

C) To access Nth element of an array students, use students[n-1]


as the starting index is 0.

D) All the above


Answer: D
Updating an element in Array

2 8 5 6 0
num[0] num[1] num[2] num[3] num[4]

int num []= {2,8,7,6,0};


num[2]=5;
Update Value
for (int i = 0; i < 5; i++)
with 5
{
cout<<num[i];
Time Complexity }

Time Complexity for updation– O(1)


Multi-Dimensional Arrays
A multi-dimensional array is an array of arrays. string letters[2][2][2] = {
string letters[2][4]; {
{ "A", "B" },
string letters[2][4] = {
{ "C", "D" }
{ "A", "B", "C", "D" },
},
{ "E", "F", "G", "H" }
{
};
{ "E", "F" },
{ "G", "H" }
}
};
Initializing 2-D Arrays

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


{
for (int j=0; j<n; j++)
{
a[i][j] = 0;
}
}
Accessing Element of an Array

1D Array

Address of element A[i] = base address + size * ( i - first index)

Suppose an array, A[ ] having Base address (BA) = 999 and size of an element = 2 bytes, find the
location of A[1].

Address of (A[-1]) = 999 + 2 x [(1) - (0)]


= 999 + 2 =1001
Accessing Element of in 2D Array

2D Array
Note: 2-D arrays exists only from the user point of view and created to
implement a relational database table look alike data structure. In
computer memory, the storage technique for 2D array is similar to that of
an one dimensional array.
Visualization/Representation of 2-D arrays in Memory

• Row Major ordering

• Column Major Ordering


Accessing Element of in 2D Array

Visualization/Representation of 2-D arrays in Memory

• Row Major ordering

• All the rows of the 2D array are stored into the memory contiguously.

• First, the 1st row of the array is stored into the memory completely, then
the 2nd row of the array is stored into the memory completely and so on
till the last row.

a11 a12 a13 a21 a22 a23 a31 a32 a33


Accessing Element in 2D Array

Visualization/Representation of 2-D arrays in Memory

• Row Major ordering

If array is declared by a[m][n] where m is the number of rows while n


is the number of columns, then address of an element a[i][j] of the
array stored in row major order is calculated as,

Address(a[i][j]) = B. A. + (i * n + j) * size
or
Address(a[i][j]) = B. A. + ((i -lr)* n + (j-lc)) * size
lr - Lower limit of row or start limit of the row or assume 0 if it is not given
lc- lower limit of column o start limit of column or assume 0 if it is not given.
Accessing Element of in 2D Array
Address(a[i][j]) = B. A. + ((i-lr) * n + (j-lc)) * size

Example-
Given an array, arr[1………10][1………15] with base value 100 and the size of each element
is 1 Byte in memory. Find the address of arr[8][6] with the help of row-major order.

Row Subset of an element whose address to be found i = 8


Column Subset of an element whose address to be found j = 6
Address of A[8][6] = 100 + 1 * ((8 – 1) * 15 + (6 – 1))
Lower Limit of row/start row index of matrix lr = 1
= 100 + 1 * ((7) * 15 + (5))
Lower Limit of column/start column index of matrix lc = 1
= 100 + 1 * (110)
Number of column given in the matrix (n)
Address of a[i][j] = 210
n = Upper Bound – Lower Bound + 1
= 15 – 1 + 1
= 15
Accessing Element in 2D Array

Visualization/Representation of 2-D arrays in Memory

• Column Major ordering

If array is declared by a[m][n] where m is the number of rows


while n is the number of columns, then address of an element
a[i][j] of the array stored in column major order is calculated
as,
Address(a[i][j]) = B. A. + (i + j*m) * size
or
Address(a[i][j]) = B. A. + ((i -lr)+ (j-lc)*m) * size

lr - Lower limit of row or start limit of the row or assume 0 if it is not given
lc- lower limit of column o start limit of column or assume 0 if it is not given.
Any Queries?

You might also like