Tuesday 23 July 2019

Fastest way to read input from stdin C++

Method 1 :

A noob's way :

#include <iostream>
using namespace std;
int main(){
   int nb,a;
   cin >> nb;
   for (int i=0; i < nb; ++i){
      cin >> a;
      // do some stuff
   }
   return 0;
}

Method 2 :

A classic way :

#include <iostream>
using namespace std;
int main(){
   ios::sync_with_stdio(false);
   cin.tie(nullptr);
   int nb,a;
   cin >> nb;
   for (int i=0; i < nb; ++i){
      cin >> a;
      // do some stuff
   }
   return 0;
}

Method 3 :

The C way :

#include <cstdio>
int main(){
   int nb,a;
   scanf("%d",&nb);
   for (int i=0; i < nb; ++i){
      scanf("%d",&a);
      // do something
   }
   return 0;
}

Method 4 :

The getchar way :

#include <stdio.h>
#include <stdlib.h>
int fastscan(){
   int c;
   bool negative = false;
   int a = 0;
   c = getchar();
   if (c=='-'){
      negative = true;
      c = getchar();
   }
   while(c>47 and c<58){
      a = a*10 + c - 48;
      c = getchar();
   }
   if(negative){
      a = -a;
   }
   return a;
}
int main(){
   int nb;
   scanf("%d",&nb);
   for (int i=nb; ~i; --i){
      fastscan();
      // do something
   }
   return 0;
}

Method 5 :

The optimised getchar_unlocked method :

#include <stdio.h>
#include <stdlib.h>
inline int fastscan(){
   int c;
   bool negative = false;
   int a = 0;
   c = getchar_unlocked();
   if (c=='-'){
      negative = true;
      c = getchar_unlocked();
   }
   while(c>47 and c<58){
      a = (a<<1) + (a<<3) + (c - 48);
      c = getchar_unlocked();
   }
   if(negative){
      a = -a;
   }
   return a;
}
int main(){
   int nb;
   scanf("%d",&nb);
   for (int i=nb; ~i; --i){
      fastscan();
      // do some stuff
   }
   return 0;
}

Method 6 :

The inserter's way :

#include <iostream>
#include <vector>
#include <iterator>
#pragma GCC optimize ("O3")
using namespace std;
int main(){
   setvbuf(stdin, (char*)NULL, _IOFBF, 0);
   ios::sync_with_stdio(false);
   cout.tie(nullptr);
   cin.tie(nullptr);
   int nb;
   cin >> nb;
   vector<int> v;
   copy(istream_iterator<int>(cin), istream_iterator<int>(),back_inserter(v));
   for (auto& i:v) // do some operations
   return 0;
}

Method 7 :

The bufferer's way :

#include <iostream>
#define BUFSIZE 1024*900*64
int main(){
   int n, number=0,numbers;
   scanf("%d",&n);
   char buf[BUFSIZE+1] = {0};
   while ((numbers = fread(buf, 1, BUFSIZE, stdin)) > 0){
     bool neg=false;
      for (int i=0; i < numbers; i++){
      if (buf[i] == '-') neg=true;
      else if (buf[i] != '\n'){
         number = buf[i] - '0' + 10*number;
      
      else{
         n--;
         if (neg) number = -number;
         // do something
         number = 0;
         neg = false
      }      
     }
     if (!n)  break;
   }
}

Method 8 :

The ultimate way :

#include <cstdint>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
inline char* stdin_ptr(){
    struct stat sb;
    (void)fstat( STDIN_FILENO, &sb );
    return (char*)mmap (0, sb.st_size, PROT_READ, MAP_SHARED | MAP_POPULATE, STDIN_FILENO, 0);
}
inline int atoi(char*& data){
    int val = 0;
    bool neg=false;
    if (*data == '-'){
       neg = true;
       data++;
    }
    do{
        val = val*10 + *data++ - '0';
    while(*data & (1<<4));
    if (neg) val = -val;
    ++data;
    return val;
}
int main(){
    char* ptr = stdin_ptr();
    int n = atoi(ptr);
    while (*ptr) // do something
}

If you have a better method please share !

std::next_permutation(arr.begin(),arr.end());

What is next_permutation(a.begin(),a.end()) ? Next permutation is like what its name says, finds the next permutation of a and assigns ...