Lecture 4
Lecture 4
Lecture -4
DISCOVER . LEARN . EMPOWER
File Handling and Recursion 1
Chapter Course Objectives
This subject aims to focuses on Advanced concept of C++ and advanced data structure to
1.
students. It focuses on advanced level analysis of algorithm and computational mathematics.
3
What if a FILE?
4
NEED FOR DATA FILES
Many real life problems requires handling of large amount of data.
Earlier we used arrays to store bulk data.
The problem with the arrays is that arrays are stored in RAM.
The data stored in arrays is retained as long as the program is running.
Once the program is over the data stored in the arrays is also lost.
To store the data permanently we need files.
Files are required to save our data (on a secondary storage device)
for future use, as RAM is not able to hold our data permanently.
5
Difference Between Arrays And Files
Difference between Files and Arrays( graduating to files ):
ARRAYS FILES
Arrays are stored in RAM Files are stored on Hard Disk
6
Input/Output In C++ Streams
The input/output system of C++ handles
file I/O operations in the same way it Input Stream
Read Extract from
handles console I/O operations. data input stream
It uses file stream as an interface between
programs and files. Disk C++
File Program
A stream is defined as the flow of data.
Different kinds of stream are used to Write
Insert into
output stream
represent different kinds of data flow. data
Output Stream
Output stream: The stream which
controls the flow of data from the
program to file is called output
stream.
Input stream: The stream which
controls the flow of data from the 7
Input/Output In C++ Classes
Each stream is associated with a particular IOS
class which contains definitions and methods
for dealing with that particular kind of data ISTREAM OSTREAM
These include fstream, ifstream and ofstream. get () put ()
getline() write()
These classes are defined in the header file read() <<
fstream.h. Therefore it is necessary to include >>
8
Input/Output In C++ Classes Contd..
The ifstream class contains open() function with default
input mode and inherits the functions get(), getline(),
read(), seekg() and tellg().
The ofstream class contains open() function with default
output mode and inherits functions put(), write(), seekp()
and tellp() from ostream.
The fstream class contains open() function with default
input/output mode and inherits all I/O functions from
iostream.h.
9
Types Of Data Files
There are two types of data files in C++: Text files and
Binary files
Portability Portable: one can easily transfer text file from Non portable: Binary files are
one computer to the other dependent. If the new computer uses
a different internal representation for
values they cannot be transferred.
Storage of In text files when we store numbers they are In a binary file 42.9876 is stored in 4
numbers stored as characters eg if we store a decimal bytes
no 42.9876 in a text file it occupies 7 bytes
11
Difference Between Text Files And Binary Files
Contd..
Text Files Binary Files
Readability Are readable and thus can Not readable
be easily edited using any
word editor.
Storage Occupy more space due to Occupy less space.
character conversions
Accuracy While reading/writing of Highly accurate for
numbers, some numbers because it stores
conversion errors may the exact internal
occur. representation of values.
12
Opening Files
Opening of files can be achieved in two ways:
Using Constructor function: This method is useful when we open only one file in a
stream. To open a file using a constructor fuction we create an object of desired
stream and initialize that object ith the desired file name. For eg. The statement
ofstream fout(“ABC.TXT”);
will create an object fout of class ofstream, opens the file ABC.TXT and attaches
it to the output stream for writing. Similarly the statement
ifstream fin(“ABC.TXT);
will create an object fin of class ifstream, opens the file “ABC.TXT” and attaches it to
the input stream for reading.
Using open() function: This method is useful when we want to open multiple files
using a single stream. For eg.
ifstream fin; //creates input stream
fin.open(“ABC.TXT”); // associates ABC.TXT to
this stream
fin.close(); // closes the file 13
Closing Files
The connections with a file are automatically closed when the
input and output stream objects expires ie when they go out of
scope.
However we can close the file explicitly by using the close()
method: fin.close();
Closing a file flushes the buffer which means the data remaining
in the buffer of input/output stream is moved to its appropriate
place. For example, when an input files connection is closed, the
data is moved from the input bufferto the program and when an
output file connection is closed the data is moved from the
output buffer to the disk file.
14
File Modes
File modes describes the way in which a file is to be used. The most common file modes are :
File Modes Explanation
ios::in Opens file for reading. File pointer is at the beginning of the
file
ios::out Opens file for writing. If the file is already created and opened
in this
mode all the previous content gets erased from the file.
ios::app Opens file for adding new records. File pointer is at the end of
the
file. New records can be added only at the end of the file.
ios::ate Opens the file for both reading and writing. File pointer is at
the end
of the file when file is opened in his mode but can be moved
to any
location in the file using file pointer methods.
ios::binary Opens file in binary mode. By default the file is opened n text
mode.
15
Two or more modes can be combined using the bitwise operator |
Text File Functions
Reading/writing a single character from/to file :
get() – read a single character from text file and store in a buffer.
e.g file.get(ch);
put() - writing a single character in text file.
e.g. file.put(ch);
Reading/writing a line from/to file:
getline() - read a line of text from text file stored in a buffer.
e.g file.getline(s,80,”\n”);
<<(insertion operator) – write a line to a file.
fin<<s;
Reading/writing a word from/to file:
char ch[20];
fin.getline(ch,20, ‘ ‘)
fin.getline(ch,20, ‘ ‘);
We canuse file>>ch
for reading and
file<<ch writing a
word in text file. The 16
A Program To Create A Text File
#include<fstream.h>
void main()
{
ofstream fout(“abc.txt”);
fout<<“ i am creating a new text file\n”;
fout<<“this text file contains alphabets and
numbers\n”;
fout.close();
}
17
File Pointers
All i/o streams objects have, at least, one internal stream pointer.
ifstream, like istream, has a pointer known as the get pointer that points to
the element to be read in the next input operation.
ofstream, like ostream, has a pointer known as the put pointer that
points to the location where the next element has to be written.
Finally, fstream, inherits both, the get and the put pointers, from
iostream.
The default writing pointer is set at the end of the file when the file is
opened in app mode.
18
File Pointers Contd..
There are two types of file pointers. These are:
get pointer – specifies the location in a file where the next
read operation will occur.
put pointer – specifies the location in a file where the
next write operation will occur.
In other words, these pointers indicate the current positions
for read and write operations, respectively. Each time an
input or an output operation takes place, the pointers
automatically advance sequentially.
It is also possible to read from and write to an arbitrary
locations in the file by moving the file pointer. 19
FUNCTIONS ASSOCIATED WITH FILE POINTERS
get pointer: The functions associated with get pointer are
seekg()
tellg()
put pointer: The functions associated with put pointer are
seekp()
tellp()
The seekg() or the seekp() functions are used to move the get and put
pointers respectively either to an absolute address within the file or to
certain number of bytes from a particular position.
The tellg() and tellp() functions can be used to find out the current
position of the get and put file pointers respectively in a file.
20
seekg()/seekp() Functions
The seekg() member function takes two arguments:
Number of bytes to move. (also called offset)
Reference in the file from which the pointer has to be repositioned.
There are three reference points defined in the ios class:
• ios:beg – the beginning of the file.
• ios:cur – the current position of the file pointer.
• ios:end – the end of the file.
For eg.
ifstream fin(“ABC.TXT”);
fin.seekg(10, ios::beg); // here 10 is the offset and ios::beg is the reference position
If the reference point is not specified, ios::beg reference point is assumed. For eg.
fin.seekg(50); // here the file pointer is moves ahead 50 bytes from the current position
21
seekg()/seekp() Function contd…
Command Explanation
fin.seekg(0,ios::beg); Moves the file pointer to the beginning of the file
fin.seekg(10,ios::beg); Moves the file pointer to 10 bytes from the
beginning of the file
fin.seekg(10,ios::cur); Moves the file pointer to 10 bytes ahead from the current
position of
the file
fin.seekg(-10,ios::cur); Moves the file pointer to 10 bytes backward from the current
position
of the file
Fin.seekg(0,ios::cur); The file pointer remains at the same position
fin.seekg(- Moves the file pointer to 10 bytes backward from the end of
10,ios::end); the file
fin.seekg(0,ios::end); Moves the file pointer to the end of the file
22
tellg()/tellp() FUNCTIONS
The tellg() function does not have any arguments. It returns the current
byte position of the get pointer relative to the beginning of the file.
For example:
Ifstream fin(“ABC.TXT”);
long pos = fin.tellg();
The above command will assign the current position of the get
pointer to the variable pos.
23
Recursion
24
What is recursion?
• Sometimes, the best way to solve a problem is by solving a smaller
version of the exact same problem first
• Recursion is a technique that solves a problem by solving a smaller
problem of the same type
25
When you turn this into a program, you end up with
functions that call themselves (recursive functions)
int f(int x)
{
int y;
if(x==0)
return 1;
else {
y = 2 * f(x-1);
return y+1;
}
} 26
Problems defined recursively
• There are many problems whose solution can be defined
recursively
Example: n factorial
1 if n = 0
n!= (recursive solution)
(n-1)!*n if n > 0
1 if n = 0
n!= (closed form solution)
1*2*3*…*(n-1)*n if n > 0
27
Coding the factorial function
• Recursive implementation
int Factorial(int n)
{
if (n==0) // base case
return 1;
else
return n * Factorial(n-1);
}
28
29
Coding the factorial function (cont.)
• Iterative implementation
int Factorial(int n)
{
int fact = 1;
for(int count = 2; count <= n; count++)
fact = fact * count;
return fact;
}
30
Another example: n choose k (combinations)
• Given n things, how many different sets of size k can be
chosen?
n n-1 n-1
= + + , 1<k<n (recursive solution)
k k k-1
n n!
= , 1<k<n (closed-form solution)
k k!(n-k)!
with base cases:
n n
= n (k = 1), = 1 (k = n)
1 n
31
n choose k (combinations)
32
33
Recursion vs. iteration
• Iteration can be used in place of recursion
• An iterative algorithm uses a looping construct
• A recursive algorithm uses a branching structure
• Recursive solutions are often less efficient, in terms of both
time and space, than iterative solutions
• Recursion can simplify the solution of a problem, often
resulting in shorter, more easily understood source code
34
How do I write a recursive function?
• Determine the size factor
• Determine the base case(s)
(the one for which you know the answer)
• Determine the general case(s)
(the one where the problem is expressed as a smaller
version of itself)
• Verify the algorithm
(use the "Three-Question-Method")
35
Three-Question Verification Method
The Base-Case Question:
Is there a nonrecursive way out of the function,
and does the routine work correctly for this
"base" case?
The Smaller-Caller Question:
Does each recursive call to the function involve a
smaller case of the original problem, leading
inescapably to the base case?
The General-Case Question:
Assuming that the recursive call(s) work
correctly, does the whole function work
correctly?
36
Recursive binary search
• Non-recursive implementation
template<class ItemType>
void SortedType<ItemType>::RetrieveItem(ItemType& item, bool& found)
{
int midPoint;
int first = 0;
int last = length - 1;
found = false;
while( (first <= last) && !found) {
midPoint = (first + last) / 2;
if (item < info[midPoint])
last = midPoint - 1;
else if(item > info[midPoint])
first = midPoint + 1;
else {
found = true;
item = info[midPoint]; } }}
37
Recursive binary search (cont’d)
• What is the size factor?
The number of elements in (info[first] ... info[last])
38
Recursive binary search (cont’d)
template<class ItemType>
bool BinarySearch(ItemType info[], ItemType& item, int first, int last)
{
int midPoint;
if(first > last) // base case 1
return false;
else {
midPoint = (first + last)/2;
if(item < info[midPoint])
return BinarySearch(info, item, first, midPoint-1);
else if (item == info[midPoint]) { // base case 2
item = info[midPoint];
return true;
}
else
return BinarySearch(info, item, midPoint+1, last);
}
} 39
Recursive binary search (cont’d)
template<class ItemType>
void SortedType<ItemType>::RetrieveItem (ItemType& item, bool& found)
{
found = BinarySearch(info, item, 0, length-1);
}
40
How is recursion implemented?
• What happens when a function gets called?
int a(int w)
{
return w+w;
}
int b(int x)
{
int z,y;
……………… // other statements
z = a(x) + y;
return z;
}
41
What happens when a function is called? (cont.)
An activation record is stored into a stack (run-time stack)
1) The computer has to stop executing function b and starts executing
function a
2) Since it needs to come back to function b later, it needs to store
everything about function b that is going to need (x, y, z, and the
place to start executing upon return)
3) Then, x from a is bounded to w from b
4) Control is transferred to function a
42
What happens when a function is called?
(cont.)
• After function a is executed, the activation record is popped
out of the run-time stack
• All the old values of the parameters and variables in function
b are restored and the return value of function a replaces
a(x) in the assignment statement
43
What happens when a recursive function is
called?
• Except the fact that the calling and called functions have the same name, there is
really no difference between recursive and nonrecursive calls
int f(int x)
{
int y;
if(x==0)
return 1;
else {
y = 2 * f(x-1);
return y+1;
}
}
44
2*f(2)
2*f(1)
2*f(1)
=f(0)
=f(1)
=f(2)
=f(3)
45
Bit Manipulation
46
Introduction
47
Bit Representation
An n-bit integer is internally stored as a binary number with n bits
in programming.
e.x. C++ int type is of 32 bit
int n=43 can be represented as
The bits in the representation are indexed from right to left. To
convert a bit representation bk ···b2b1b0 into a number, we can use
the formula:
bk2k +...+ b222 + b121 + b02 0 .
Bit representation number either signed or unsigned. Usually a
signed representation is used, which means that both negative and
positive numbers can be represented. Range is (-2n-1 to 2n-1 -1).
48
Bit Representation contd..
The first bit in a signed representation is the sign of the number
(0 for nonnegative numbers and 1 for negative numbers), and
the remaining n−1 bits contain the magnitude of the number
Two’s complement is used, which means that the opposite
number of a number is calculated by first inverting all the bits in
the number, and then increasing the number by one.
Ex. -43 can be represented as
11111111111111111111111111010101.
In an unsigned representation, only nonnegative numbers can
be used, but the upper bound for the values is larger. An
unsigned variable of n bits can contain any integer between 0
and 2n −1 . 49
Bit Representation contd..
A signed number is connected with unsigned number by following
formula: 2n-x
e.x
int x = -43;
unsigned int y = x;
cout << x << "\n"; // -43
cout << y << "\n"; // 4294967253
If a number is larger than the upper bound of the bit representation, the
number will overflow. In a signed representation, the next number after
2n−1 −1 is −2n−1 , and in an unsigned representation, the next number after 2n
−1
is 0.
e.x. int x = 2147483647
cout << x << "\n"; // 2147483647
x++;
cout << x << "\n"; // -2147483648 50
Bit Operations
AND Operation:
e.x.
10110 (22)
& 11010 (26)
= 10010 (18)
Or Operation:
e.x.
10110 (22)
| 11010 (26)
= 11110 (18)
Xor Operation:
NOT :
Bit Shifts: 51
Bit Operations Contd..
Xor Operation:
e.x.
10110 (22)
^ 11010 (26)
= 01100 (18)
NOT Operation:
e.x.
x = 29 00000000000000000000000000011101
~x = −30 11111111111111111111111111100010
Bit Shifts:
The left bit shift x << k appends k zero bits to the number, and the right bit
shift x >> k removes the k last bits from the number. For example, 14 << 2 =
56, because 14 and 56 correspond to 1110 and 111000. Similarly, 49 >> 3 = 6,
because 49 and 6 correspond to 110001 and 110. Note that x << k corresponds
to multiplying x by 2k , and x >> k corresponds to dividing x by 2k rounded 52
Bit Operations Contd..
__builtin_clz(x): the number of zeros at the beginning of the
number
__builtin_ctz(x): the number of zeros at the end of the number
__builtin_popcount(x): the number of ones in the number .
__builtin_parity(x): the parity (even or odd) of the number of
ones.
Hamming distances:
The Hamming distance hamming(a,b) between two strings a and b
of equal length is the number of positions where the strings differ.
For example, hamming(01101,11001) = 2.
54
Bit Optimizations Example
Given a list of n bit strings, each of Solution 1:
length k, calculate the minimum int hamming(string a, string b)
Hamming distance between two {
strings in the list. int d = 0; for (int i = 0; i < k; i++)
For example, the answer for {
[00111,01101,11110] is 2, if (a[i] != b[i]) d++;
because: }
• hamming(00111,01101) = 2, return d;
• hamming(00111,11110) = 3, and }
• hamming(01101,11110) = 3. O(n2 K)
55
Bit Optimizations Example contd..
Solution 2: Using the first approach, the
int hamming(int a, int b) search took 13.5 seconds, and
{ after the bit optimization, it only
return __builtin_popcount(a^b); took 0.5 seconds. Thus, the bit
} optimized code was almost 30
In the above function, the xor times faster than the original code.
operation constructs a bit string
that has one bits in positions
where a and b differ. Then, the
number of bits is calculated using
the __builtin_popcount function.
56
Conclusion
We are now able to understand the recursion and file handling process.
57
References
Images link-
[1] https://simplesnippets.tech/inheritance-in-java-types-of-inheritance/
Online Video Link-
• https://nptel.ac.in/courses/106/104/106104128/
Research Paper:
• http://onlinepubs.trb.org/Onlinepubs/trr/1993/1408/1408-012.pdf
• https://www.researchgate.net/publication/327633163_ADVANCE-RABIN_KARP_ALGORITHM_FOR_STRING_MATCHING
• https://glossary.informs.org/notes/spanningtree.pdf
58
THANK YOU
For queries
Email: [email protected]
59