[ASD] Spox, Spoj, szybkie wczytywanie int'ów w C
W tym semestrze zadania z spox'a wymagają jeszcze szybszego wczytywanie danych, niż rok temu, więc wielu osobą może przydać się informacja jak szybko wczytać inty z wejścia.
Jak wczytać z wejścia int'y najszybciej? Wczytując po znaku z wejścia cyfry i zamieniając na int'y kiedy 'inny znak niż cyfra'.
Do wczytywania najlepiej użyć getchar_unlocked [do użycia tylko w aplikacjach jednowątkowych - czyli takich jak na spox, zwykłe getchar robi to samo tylko, że przy każdym wczytaniu znaku chce synchronizować wątki [jeden wątek?] i wykonuje się 4 razy dłużej!], funkcja ta istnieje na 'spox.spoj.pl', jeśli na kompie jej nie macie to do testów możecie podmienić tą linijkę:
#define gc getchar_unlocked
na:
#define gc getchar
A to cała funkcja (TYLKO DLA DODATNICH!):
#define gc getchar_unlocked
void scan_integer( int* o )
{
register int c = gc();
int x = 0;
for( ; ((c<48 || c>57)); c = gc() );
for( ;c>47 && c<58; c = gc() ) {
x = (x << 1) + (x << 3) + c - 48;
}
*o = x;
}
Wersja dla wszystkich int (ujemnych i dodatnich):
#define gc getchar_unlocked
void scan_integer( int* o )
{
register int c = gc();
x = 0;
int neg = 0;
for( ; ((c<48 || c>57) && c != '-'); c = gc() );
if( c=='-' ) {
neg=1;
c=gc();
}
for( ;c>47 && c<58; c = gc() ) {
x = (x << 1) + (x << 3) + c - 48;
}
if( neg )
x=-x;
*o = x;
}
Przykład wczytania i wyświetlenia wszystkich int'ów z wejścia dla czystego C z podstawową biblioteką 'stdio.h':
int main()
{
int liczba;
while(!feof(stdin))
{
scan_integer(&liczba);
printf("%d ", liczba);
}
return 0;
}
Czas wykonania algorytmu na spox z wczytywaniem metoda:
cin >> x;= 0,7 secfscanf(stdin, "%d", &x);= 0,27 secscan_integer(&x);// zgetchar= 0,11 sec!scan_integer(&x);// zgetchar_unlocked= 0,03 sec!
Więcej informacje na temat: http://stackoverflow.com/a/25388170/4047081