Paras vastaus
On hieman epäselvää, mitä kysyt, mutta oletan, että kysymys on siitä, että taulukko annetaan , miten määrität sen pituuden.
C: llä on useita tyyppisiä taulukoita: tuntemattoman kokoiset taulukot, tunnetun vakiokokoiset taulukot ja muuttuvan pituiset taulukot.
vakiokoko, koko on osa sen tyyppiä: taulukon tyyppi, jonka tyyppi on int[10]
, on juuri 10. C: llä ei ole mekanismia sen poimimiseksi suoraan tyypistä (toisin kuin C ++ ), mutta voit tehdä sen epäsuorasti käyttämällä sizeof:
int a[] = {1,2,3,4,5,6,7,8,9,0};
size\_t sz = sizeof a / sizeof *a; // or .../sizeof a[0], same thing
printf("size = \%zu\n", sz);
Vaihtelevan pituisen taulukon koko voidaan laskea myös sizeof: lla, samalla koodilla. Siinä tapauksessa se suoritetaan ajon aikana:
scanf("\%d", &x);
int a[x];
size\_t sz = sizeof a / sizeof *a;
printf("size = \%zu\n", sz);
Lopuksi tuntemattomasti sidotuilla taulukoilla on määritelmän mukaan tuntematon koko. Sinun pitäisi saada se ohjelmalogiikan kautta
extern int a[];
size\_t sz = something\_from\_the\_module\_that\_defines\_a();
Yksi varoitus, tietysti paljaita taulukoita C: ssä ei voida siirtää funktioille, joten koot on laskettava soittajan puolelta ja siirrettävä erikseen:
void f(int *a, size\_t sz);
int a[] = {1,2,3,4,5,6,7,8,9,0};
f(a, sizeof a / sizeof *a);
jäsenryhmät voidaan tietysti siirtää funktioihin arvon mukaan:
struct a10 {int a[10];};
void f(struct a10 s) {
size\_t sz = sizeof s.a / sizeof *s.a;
}
Vastaa
Tärkeä kysymys on, etsitkö hakuja useita kertoja? Jos näin on, luo hash-taulukko tai muu hakemisto kerran löytääksesi asiat nopeasti. Hajautustaulukko voidaan luoda samalla, kun tiedot luetaan levyltä (jos se tulee siitä).
Jos tämä on kertaluonteinen asia ja tiedot ladataan levyltä, tee etsintä päällekkäin IO: n kanssa. Kahta tai useampaa puskuria voidaan käyttää.
Toinen kysymys on, haluatko vain tietää, onko jotain läsnä, vai onko siihen liittyviä tietoja, jotka haluat noutaa? Jos haluat vain tietää, onko numero läsnä, pienempää esitystä voidaan käyttää bittiryhmällä.
Tämän lisäksi on parasta käyttää nopeinta vertailua käyttävää C-rivikoodia; Käytä kaikkia kääntäjän tarjoamia optimointivaihtoehtoja. Jotkut kääntäjät saattavat luoda saman pikakoodin riippumatta siitä, käytätkö osoittimia, laskureita tai indeksointia:
int * first = ..., * last = ...;
for ( ; first <= last; ++first ) if ( *first == target ) ...
tai
int * first = ..., count = ...;
for ( ; count-- > 0; ++first ) if ( *first == target ) ...
tai
int * first = ..., count = ..., index = ...;
for ( ; index < count; ++index ) if ( first[index] == target ) ...
Saatat pitää huijaamisena pyytää kääntäjää antamaan assembler-lähde saadakseen käsityksen siitä, mitä se tekee, mutta pienemmät kääntäjät saattavat vaatia sitä, jos olet todella huolissasi suorituskyvystä - vain nähdäksesi, minkälainen C-koodi tuottaa paras tulos.
Sitten voit tehdä muita asioita, kuten käyttää useita ketjuja: Jos sinulla on 8 ydintä, voit jakaa ryhmän 8 osaan ja käynnistää ketjun kullekin osalle. Mutta ketjujen käynnistyskustannukset saattavat olla liian korkeat, jos vertailukustannukset ovat pienet.
Matriisi voi olla suuri, joten virtuaalimuistin vaihto voi hidastaa asioita. Oman muistikartoitetun tiedostotietosi käyttäminen voi antaa sinun hallita kartoitusta ja kartoituksen purkamista, jotta fyysisen muistin käyttö pysyy vähäisenä. Voit purkaa osion, jonka olet juuri päättänyt etsiä, jotta muistia voitaisiin käyttää myöhempiin osioihin.
Vain joitain ideoita. Onnea.