We generally use cin/scanf/getchar for inputs. Let us talk about a new way of input.
getchar_unlocked() :
What is getchar_unlocked () ?
A function that gets a character from stdin. It returns the next character from stdin. If stdin is at the end of the file, the end of the file indicator is set then getchar_unlocked() returns EOF.
In short, it is another version of getcha(). It is used only for high and very large inputs as it is not threaded safe.
What do we mean when we talk about thread safety?
A thread is an execution context i.e it is all about execution of events on a computer. Suppose you are using a book and want to take a break right now, but you want to be able to come back and resume the reading from the exact point where you stopped. One way to do so is by writing down the page number, line number and book number.So your execution context for reading book is these 3 numbers. If you have a friend and he is using the same technique,he can take the book while you are no using it, and resume reading from where he stopped.The you can take it back,and resume it from you were.
Threads work the same way. A CPU gives you the illusion that it's doing multiple computation at the same time. It does that by spending a bit of time on each computation. On a technical level, an execution context(thread) consists values of the CPU's registers.
Windows does not support getchar_unlocked() function. because it's thread unsafe. So if you aren't using Linux then the only possible way to use this is on an IDE.
Here is an example using getchar_unlocked():
The following function can be used to read both +ve and -ve integers using getchar_unlocked().
#include<iostream>
#include<stdio.h>
long long int get_num(long long int &num)
{
num = 0;
char c = getchar_unlocked();
long long int flag = 0;
while(!((c>='0' & c<='9') || c == '-'))
c=getchar_unlocked();
if(c == '-')
{
flag = 1;
c=getchar_unlocked();
}
while(c>='0' && c<='9')
{
num = (num<<1)+(num<<3)+c-'0';
c=getchar_unlocked();
}
if(flag==0)
return num;
else
return -1*num;
}
int main()
{
long long int number;
number = get_num(number);
printf("%lld\n",number);
}
The working of the function goes like this:
The first while loop keeps repeating until 'c' is given a value of a digit between 0-9 or '-'(in the case of negative numbers).
If we encounter '-', we initialize flag = 1 to make a note that it is a negative number.
The second while loop keeps repeating until 'c' gets a value between 0-9 and stops when any other character is read(Usually it would be a ' '(space) or '\n').
The statement num = (num<<3)+(num<<1)+c-'0' turns character digit in c to integer digit and is added to num*10 (Left shift operators i.e num << a = num * (2^a) ).
It can also be written as:
num = num*10 + c-'0'
Finally, we return the value of num depending on the value of t flag(whether the number is -ve or +ve).
You can use the above function to read any data type. Just change the data type of the value you're passing into this function to the data type you want to scan.
Try this question to see the difference between other input methods and getchar_unlcked():
https://www.codechef.com/problems/INTEST
Why do we use different methods of inputs?
In most of the cases, the answer is related to time complexity or the time taken to take the input. The time is taken by different input methods increases in the following order:
getchar_unlocked < getchar < scanf < cin
The speed difference in scanf and cin is because iostream I/O functions maintain synchronization with the C library I/O functions. We can turn this off with a call to
std::ios::sync_with_stdio(false); ( do this if you are going to use C++ I/O only).
So until and unless speed factor is too much necessary, or you see some message like
"Warning: Large I/O data" try to avoid getchar_unlocked
getchar_unlocked() :
What is getchar_unlocked () ?
A function that gets a character from stdin. It returns the next character from stdin. If stdin is at the end of the file, the end of the file indicator is set then getchar_unlocked() returns EOF.
In short, it is another version of getcha(). It is used only for high and very large inputs as it is not threaded safe.
What do we mean when we talk about thread safety?
A thread is an execution context i.e it is all about execution of events on a computer. Suppose you are using a book and want to take a break right now, but you want to be able to come back and resume the reading from the exact point where you stopped. One way to do so is by writing down the page number, line number and book number.So your execution context for reading book is these 3 numbers. If you have a friend and he is using the same technique,he can take the book while you are no using it, and resume reading from where he stopped.The you can take it back,and resume it from you were.
Threads work the same way. A CPU gives you the illusion that it's doing multiple computation at the same time. It does that by spending a bit of time on each computation. On a technical level, an execution context(thread) consists values of the CPU's registers.
Windows does not support getchar_unlocked() function. because it's thread unsafe. So if you aren't using Linux then the only possible way to use this is on an IDE.
Here is an example using getchar_unlocked():
The following function can be used to read both +ve and -ve integers using getchar_unlocked().
#include<iostream>
#include<stdio.h>
long long int get_num(long long int &num)
{
num = 0;
char c = getchar_unlocked();
long long int flag = 0;
while(!((c>='0' & c<='9') || c == '-'))
c=getchar_unlocked();
if(c == '-')
{
flag = 1;
c=getchar_unlocked();
}
while(c>='0' && c<='9')
{
num = (num<<1)+(num<<3)+c-'0';
c=getchar_unlocked();
}
if(flag==0)
return num;
else
return -1*num;
}
int main()
{
long long int number;
number = get_num(number);
printf("%lld\n",number);
}
The working of the function goes like this:
The first while loop keeps repeating until 'c' is given a value of a digit between 0-9 or '-'(in the case of negative numbers).
If we encounter '-', we initialize flag = 1 to make a note that it is a negative number.
The second while loop keeps repeating until 'c' gets a value between 0-9 and stops when any other character is read(Usually it would be a ' '(space) or '\n').
The statement num = (num<<3)+(num<<1)+c-'0' turns character digit in c to integer digit and is added to num*10 (Left shift operators i.e num << a = num * (2^a) ).
It can also be written as:
num = num*10 + c-'0'
Finally, we return the value of num depending on the value of t flag(whether the number is -ve or +ve).
You can use the above function to read any data type. Just change the data type of the value you're passing into this function to the data type you want to scan.
Try this question to see the difference between other input methods and getchar_unlcked():
https://www.codechef.com/problems/INTEST
Why do we use different methods of inputs?
In most of the cases, the answer is related to time complexity or the time taken to take the input. The time is taken by different input methods increases in the following order:
getchar_unlocked < getchar < scanf < cin
The speed difference in scanf and cin is because iostream I/O functions maintain synchronization with the C library I/O functions. We can turn this off with a call to
std::ios::sync_with_stdio(false); ( do this if you are going to use C++ I/O only).
So until and unless speed factor is too much necessary, or you see some message like
"Warning: Large I/O data" try to avoid getchar_unlocked
No comments:
Post a Comment