⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 anagram.c

📁 一个很有名的硬件模拟器。可以模拟CPU
💻 C
📖 第 1 页 / 共 2 页
字号:
    cchPhraseLength = 0;    while ((ch = *pchPhrase++) != '\0') {        if (isalpha(ch)) {            ch = tolower(ch);            lPhrase(ch).uFrequency++;            cchPhraseLength++;        }    }    /* Build  masks */    iq = 0;                             /* which quad being used */    cbtUsed = 0;                        /* bits used so far */    for (i = 0; i < ALPHABET; i++) {        if (alPhrase[i].uFrequency == 0) {            auGlobalFrequency[i] = ~0;  /* to make it sort last */        } else {            auGlobalFrequency[i] = 0;            for (cbtNeed = 1, qNeed = 1;                 alPhrase[i].uFrequency >= qNeed;                 cbtNeed++, qNeed <<= 1);            if (cbtUsed + cbtNeed > MASK_BITS) {                if (++iq >= MAX_QUADS)		    Fatal("MAX_QUADS not large enough\n", 0);                cbtUsed = 0;            }            alPhrase[i].uBits = qNeed-1;            if (cbtUsed)		qNeed <<= cbtUsed;            aqMainSign[iq] |= qNeed;            aqMainMask[iq] |= (Quad)alPhrase[i].uFrequency << cbtUsed;            alPhrase[i].uShift = cbtUsed;            alPhrase[i].iq = iq;            cbtUsed += cbtNeed;        }    }}PWordNewWord(void) {    PWord pw;    pw = (Word *)malloc(sizeof(Word));    if (pw == NULL)        Fatal("Out of memory after %d candidates\n", cpwCand);    return pw;}/* wprint -- print a word, followed by a space * * We would normally just use printf, but the string being printed is * is a huge pointer (on an IBM PC), so special care must be taken. */void wprint(char * pch) {    printf("%s ", pch);}PWord NextWord(void);/* NextWord -- get another candidate entry, creating if necessary */PWord NextWord(void) {    PWord pw;    if (cpwCand >= MAXCAND)	Fatal("Too many candidates\n", 0);    pw = apwCand[cpwCand++];    if (pw != NULL)	return pw;    apwCand[cpwCand-1] = NewWord();    return apwCand[cpwCand-1];}/* BuildWord -- build a Word structure from an ASCII word * If the word does not fit, then do nothing. */void BuildWord(char * pchWord) {    unsigned char cchFrequency[ALPHABET];    int i;    char * pch = pchWord;    PWord pw;    int cchLength = 0;    bzero(cchFrequency, sizeof(unsigned char)*ALPHABET);    /* Zero(cchFrequency); */    /* Build frequency table */    while ((i = *pch++) != '\0') {        if (!isalpha(i)) continue;        i = ch2i(tolower(i));        if (++cchFrequency[i] > alPhrase[i].uFrequency)	    return;        ++cchLength;    }    Debug(wprint(pchWord);)    /* Update global count */    for (i = 0; i < ALPHABET; i++)        auGlobalFrequency[i] += cchFrequency[i];    /* Create a Word structure and fill it in, including building the     * bitfield of frequencies.     */    pw = NextWord();    bzero(pw->aqMask, sizeof(Quad)*MAX_QUADS);    /* Zero(pw->aqMask); */    pw->pchWord = pchWord;    pw->cchLength = cchLength;    for (i = 0; i < ALPHABET; i++) {        pw->aqMask[alPhrase[i].iq] |=            (Quad)cchFrequency[i] << alPhrase[i].uShift;    }}/* AddWords -- build the list of candidates */voidAddWords(void) {    char * pch = pchDictionary;     /* walk through the dictionary */    cpwCand = 0;    while (*pch) {        if ((pch[1] >= cchMinLength && pch[1]+cchMinLength <= cchPhraseLength)            || pch[1] == cchPhraseLength)	    BuildWord(pch+2);        pch += *pch;    }    fprintf(stdout, "%d candidates\n", cpwCand);}void DumpCandidates(void) {    unsigned u;    for (u = 0; u < cpwCand; u++)        printf(StringFormat, apwCand[u]->pchWord, (u % 4 == 3) ? '\n' : ' ');    printf("\n");}PWord apwSol[MAXSOL];                   /* the answers */int cpwLast;Debug(void DumpWord(Quad * pq) {    int i;    Quad q;    for (i = 0; i < ALPHABET; i++) {        if (alPhrase[i].uFrequency == 0) continue;        q = pq[alPhrase[i].iq];        if (alPhrase[i].uShift) q >>= alPhrase[i].uShift;        q &= alPhrase[i].uBits;        while (q--) putchar('a'+i);    }    putchar(' ');})                                       /* End of debug code */void DumpWords(void) {    int i;    for (i = 0; i < cpwLast; i++) wprint(apwSol[i]->pchWord);    printf("\n");}Stat(unsigned long ulHighCount; unsigned long ulLowCount;)jmp_buf jbAnagram;#define OneStep(i) \    if ((aqNext[i] = pqMask[i] - pw->aqMask[i]) & aqMainSign[i]) { \        ppwStart++; \        continue; \    }voidFindAnagram(Quad * pqMask, PPWord ppwStart, int iLetter){    Quad aqNext[MAX_QUADS];    register PWord pw;    Quad qMask;    unsigned iq;    PPWord ppwEnd = &apwCand[0];    ppwEnd += cpwCand;    ;    if (HaltProcessing()) longjmp(jbAnagram, 1);    Debug(printf("Trying :"); DumpWord(pqMask); printf(":\n");)    for (;;) {        iq = alPhrase[achByFrequency[iLetter]].iq;        qMask = alPhrase[achByFrequency[iLetter]].uBits <<                alPhrase[achByFrequency[iLetter]].uShift;        if (pqMask[iq] & qMask) break;        iLetter++;    }    Debug(printf("Pivoting on %c\n", i2ch(achByFrequency[iLetter]));)    while (ppwStart < ppwEnd) {          /* Half of the program execution */        pw = *ppwStart;                  /* time is spent in these three */        Stat(if (++ulLowCount == 0) ++ulHighCount;)#if MAX_QUADS > 0        OneStep(0);                     /* lines of code. */#endif#if MAX_QUADS > 1        OneStep(1);#endif#if MAX_QUADS > 2        OneStep(2);#endif#if MAX_QUADS > 3        OneStep(3);#endif#if MAX_QUADS > 4            @@"Add more unrolling steps here, please."@@#endif        /* If the pivot letter isn't present, defer this word until later */        if ((pw->aqMask[iq] & qMask) == 0) {            *ppwStart = *--ppwEnd;            *ppwEnd = pw;            continue;        }        /* If we get here, this means the word fits. */        apwSol[cpwLast++] = pw;        if (cchPhraseLength -= pw->cchLength) { /* recurse */            Debug(DumpWords();)            /* The recursive call scrambles the tail, so we have to be             * pessimistic.             */	    ppwEnd = &apwCand[0];	    ppwEnd += cpwCand;            FindAnagram(&aqNext[0],			ppwStart, iLetter);        } else DumpWords();             /* found one */        cchPhraseLength += pw->cchLength;        --cpwLast;        ppwStart++;        continue;    }    ;}int Cdecl CompareFrequency(char *pch1, char *pch2) {    return auGlobalFrequency[*pch1] < auGlobalFrequency[*pch2]        ?  -1 :           auGlobalFrequency[*pch1] == auGlobalFrequency[*pch2]        ?   0 : 1;}void SortCandidates(void) {    int i;    /* Sort the letters by frequency */    for (i = 0; i < ALPHABET; i++) achByFrequency[i] = i;    qsort(achByFrequency, ALPHABET, sizeof(char),          (int (*)(const void *, const void *))CompareFrequency);    fprintf(stdout, "Order of search will be ");    for (i = 0; i < ALPHABET; i++)	fputc(i2ch(achByFrequency[i]), stdout);    fputc('\n', stdout);}int fInteractive;char * GetPhrase(char * pch) {    if (fInteractive) printf(">");    fflush(stdout);    if (gets(pch) == NULL) {#ifdef PLUS_STATS	PrintDerefStats(stdout);        PrintHeapSize(stdout);#endif /* PLUS_STATS */	exit(0);    }    return(pch);}char achPhrase[255];int Cdecl main(int cpchArgc, char **ppchArgv) {    if (cpchArgc != 2 && cpchArgc != 3)        Fatal("Usage: anagram dictionary [length]\n", 0);    if (cpchArgc == 3)	cchMinLength = atoi(ppchArgv[2]);    fInteractive = isatty(1);    ReadDict(ppchArgv[1]);    while (GetPhrase(&achPhrase[0]) != NULL) {        if (isdigit(achPhrase[0])) {            cchMinLength = atoi(achPhrase);            printf("New length: %d\n", cchMinLength);        } else if (achPhrase[0] == '?') {            DumpCandidates();        } else {            BuildMask(&achPhrase[0]);            AddWords();            if (cpwCand == 0 || cchPhraseLength == 0) continue;            Stat(ulHighCount = ulLowCount = 0;)            cpwLast = 0;            SortCandidates();            if (setjmp(jbAnagram) == 0)                FindAnagram(&aqMainMask[0], &apwCand[0], 0);            Stat(printf("%lu:%lu probes\n", ulHighCount, ulLowCount);)        }    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -