C 智囊团游戏中弦乐的比较

C 智囊团游戏中弦乐的比较,c,string,compare,pattern-matching,C,String,Compare,Pattern Matching,我正在编写一个模拟游戏策划的程序,但我正在努力比较猜测模式和关键模式。 比赛条件有点变化: 图案由字母组成 如果猜测模式的元素等于键模式的元素,并且索引也等于,则打印b 若猜测模式的元素等于键模式的元素,但索引不等于,则打印w 若猜测模式的元素不等于关键模式的元素,则打印点 在关于猜测模式的反馈中,“b是第一位的,w是第二位的”,最后一位 原始密钥与猜测模式匹配代码 所需输出: 我试图再使用一个字符串,它将存储猜测的反馈,但是当有几个猜测时,我想我应该使用某种循环来打印每次新猜测时之前所有猜

我正在编写一个模拟游戏策划的程序,但我正在努力比较猜测模式和关键模式。 比赛条件有点变化:

  • 图案由字母组成
  • 如果猜测模式的元素等于键模式的元素,并且索引也等于,则打印b
  • 若猜测模式的元素等于键模式的元素,但索引不等于,则打印w
  • 若猜测模式的元素不等于关键模式的元素,则打印点
  • 在关于猜测模式的反馈中,“b是第一位的,w是第二位的”,最后一位
原始密钥与猜测模式匹配代码 所需输出:

我试图再使用一个字符串,它将存储猜测的反馈,但是当有几个猜测时,我想我应该使用某种循环来打印每次新猜测时之前所有猜测的反馈。但是我很难弄明白我应该如何用所建议的结构编写这个循环


我在代码中添加了最后一次更正,因此几乎达到了预期的输出。有人知道这里可以做什么吗?

您基本上是将
key
的所有元素与
guess
的所有元素进行匹配,这不是您想要的

您需要迭代
guess
并区分这三种情况

  • 元素猜对了
  • 元素猜测不正确,但存在于键中
  • 元素猜测不正确且不存在于键中

    int i,k;
    bool found;
    
    for (i=0; i<patternlength; i++)
    {
        if (key[i] == guess[i])
        {
            printf("b");
        }
        else
        {
            found = false;
            for (k=0; k<patternlength && !found; k++)
            {
                if (key[k] == guess[i])
                {
                    found = true;
                    printf("w");
                }
            }
            if (!found)
            {
                printf(".");
            }
        }
    }
    
    inti,k;
    布尔发现;
    
    对于(i=0;i您基本上是将
    key
    的所有元素与
    guess
    的所有元素相匹配,这不是您想要的

    您需要迭代
    guess
    并区分这三种情况

  • 元素猜对了
  • 元素猜测不正确,但存在于键中
  • 元素猜测不正确且不存在于键中

    int i,k;
    bool found;
    
    for (i=0; i<patternlength; i++)
    {
        if (key[i] == guess[i])
        {
            printf("b");
        }
        else
        {
            found = false;
            for (k=0; k<patternlength && !found; k++)
            {
                if (key[k] == guess[i])
                {
                    found = true;
                    printf("w");
                }
            }
            if (!found)
            {
                printf(".");
            }
        }
    }
    
    inti,k;
    布尔发现;
    
    对于(i=0;i,我假设存在一个结构(为了方便复制其中包含的数组),并且输入验证确保键和猜测的长度相同,并且键和猜测只包含字母字符

    typedef struct pattern
    {
        char pattern[8];
    } pattern;
    
    size_t print_scoring(pattern key, pattern guess)
    {
        size_t n = strlen(key.pattern);
        assert(n == strlen(guess.pattern));
        size_t bcount = 0;
        for (size_t i = 0; i < n; i++)
        {
            if (key.pattern[i] == guess.pattern[i])
            {
                putchar('b');
                key.pattern[i] = guess.pattern[i] = '.';
                bcount++;
            }
        }
        if (bcount != n)
        {
            size_t wcount = 0;
            for (size_t i = 0; i < n; i++)
            {
                if (guess.pattern[i] != '.')
                {
                    for (size_t j = 0; j < n; j++)
                    {
                        if (guess.pattern[i] == key.pattern[j])
                        {
                            wcount++;
                            putchar('w');
                            guess.pattern[i] = key.pattern[j] = '.';
                            break;
                        }
                    }
                }
            }
            for (size_t i = bcount + wcount; i < n; i++)
                putchar('.');
        }
        return bcount;
    }
    
    测试输出
    从评论中 为什么我的代码不起作用?你能看一下吗? 问题是,在输入猜测模式后,我无法进入下一步。也许我在代码中没有看到一些错误

    即时响应:


    我的答案中的一个关键点是,比较代码处理的是输入数据的副本。这是一种破坏性的比较算法,在数据上写点。您试图将我的代码合并到您的程序中时,没有保留单独的函数处理数据的单独副本,这些副本是这个答案的关键部分有一个结构的se可以方便地传递数据副本(这是C为您自动复制数组的一次机会)。比较代码应该在它自己的函数中,而不是在
    main()
    中内联

    但是,我们可以让给定的代码正常工作。有一些转录错误(下面标记为BUG)和一些其他问题(也在下面识别)

    有关修订守则的工作版本 这是您的程序的工作版本,带有关键更改。非关键更改包括运算符周围的间距和使用4个空格的缩进级别

    #include <string.h>
    #include <stdio.h>
    
    static int length(void) { return 3; }    // Dummy function
    static int guessnum(void) { return 5; }  // Dummy function
    
    int main(void)
    {
        int patternlength = length();
        char key[patternlength+1];      // Buffer overflow
        char keyc[patternlength+1];     // Copy of key
        int numguess = guessnum();
        char guess[patternlength+1];    // Buffer overflow
        printf("Input the key pattern with no spaces: ");
        scanf("%s", key);
        int i,j,count = 1;
        int bcount = 0, wcount = 0;
        char guessc[patternlength+1];   // Buffer overflow
        guessc[0] = '\0';               // Initialize!
        while (strcmp(key, guess) != 0 && count <= numguess)
        {
            strcpy(keyc, key);          // Copy key too
            printf("Input a guess pattern with no spaces: ");
            scanf("%s", guess);
            strcpy(guessc, guess);
    
            wcount = 0;     // Reinitialize
            bcount = 0;     // Reinitialize
            printf("%d: ", count);
            for (i = 0; i < patternlength; i++)
            {
                if (keyc[i] == guessc[i])
                {
                    putchar('b');
                    keyc[i] = guessc[i] = '.';
                    bcount++;
                }
            }
            if (bcount != patternlength)    // Extraneous semi-colon excised! ;
            {
                for (i = 0; i < patternlength; i++)
                {
                    if (guessc[i] != '.')
                    {
                        //for (j = 0; i < patternlength; j++) BUG
                        for (j = 0; j < patternlength; j++)
                        {
                            //if (guessc[i] == keyc[i]) BUG
                            if (guessc[i] == keyc[j])
                            {
                                wcount++;
                                putchar('w');
                                //guessc[i] = keyc[i];  BUG
                                keyc[j] = guessc[i] = '.';
                                break;
                            }
                        }
                    }
                }
                for (i = bcount  +  wcount; i < patternlength; i++)
                    putchar('.');
            }
            count++;
            printf(" %s\n", guess);
        }
        if (strcmp(key, guess) != 0)
        {
            printf("You did not guess the pattern!\n");
        }
        else 
        {
            printf("You guessed the pattern!\n");
        }
        return 0;
    }
    
    如果编译器没有告诉您这一点,则说明您没有使用足够的警告(或者您需要更好的编译器)。我通常使用:

    gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
        -Wold-style-definition ss2.c -o ss2
    
    工作代码毫无怨言地通过了它

    样本输出 最终调试负载代码 这主要是为了显示我用来查看出错情况的打印级别。对诊断输出使用
    stderr
    ,意味着在建立输出行时,诊断不会干扰
    stdout
    的缓冲。这和在调试代码上使用无缩进也意味着很容易剥离de错误代码

    #include <string.h>
    #include <stdio.h>
    
    static int length(void) { return 3; }
    static int guessnum(void) { return 5; }
    
    int main(void)
    {
        int patternlength = length();
        char key[patternlength+1];      // Buffer overflow
        char keyc[patternlength+1];     // Copy of key
        int numguess = guessnum();
        char guess[patternlength+1];    // Buffer overflow
        printf("Input the key pattern with no spaces: ");
        scanf("%s", key);
        int i,j,count = 1;
        int bcount = 0, wcount = 0;
        char guessc[patternlength+1];   // Buffer overflow
        guessc[0] = '\0';               // Initialize!
        while (strcmp(key, guess) != 0 && count <= numguess)
        {
            strcpy(keyc, key);          // Copy key too
            printf("Input a guess pattern with no spaces: ");
            scanf("%s", guess);
            strcpy(guessc, guess);
    
    fprintf(stderr, "B1: (%s) vs (%s)\n", key, guess);
    fprintf(stderr, "B2: (%s) vs (%s)\n", keyc, guessc);
            wcount = 0;     // Reinitialize
            bcount = 0;     // Reinitialize
            printf("%d: ", count);
            for (i = 0; i < patternlength; i++)
            {
    fprintf(stderr, "L1a: %d\n", i);
                if (keyc[i] == guessc[i])
                {
    fprintf(stderr, "L1b: B (%c = %c)\n", keyc[i], guessc[i]);
                    putchar('b');
                    keyc[i] = guessc[i] = '.';
                    bcount++;
                }
            }
    fprintf(stderr, "M1: (%s) vs (%s)\n", keyc, guessc);
            if (bcount != patternlength)    // Extraneous semi-colon excised! ;
            {
    fprintf(stderr, "L2a: b = %d (%s) vs (%s)\n", bcount, keyc, guessc);
                for (i = 0; i < patternlength; i++)
                {
    fprintf(stderr, "L2b: %d (%c)\n", i, guessc[i]);
                    if (guessc[i] != '.')
                    {
    fprintf(stderr, "L2c: %d (%c)\n", i, guessc[i]);
                        //for (j = 0; i < patternlength; j++) BUG
                        for (j = 0; j < patternlength; j++)
                        {
    fprintf(stderr, "L2d: %d (%c) vs %d (%c)\n", i, guessc[i], j, keyc[j]);
                            //if (guessc[i] == keyc[i]) BUG
                            if (guessc[i] == keyc[j])
                            {
    fprintf(stderr, "L2e: W %d (%c) vs %d (%c)\n", i, guessc[i], j, keyc[j]);
                                wcount++;
                                putchar('w');
                                keyc[j] = guessc[i] = '.';
                                //guessc[i] = keyc[i];  BUG
                                break;
                            }
                        }
                    }
                }
    fprintf(stderr, "L3a: %d + %d vs %d\n", bcount, wcount, patternlength);
                for (i = bcount  +  wcount; i < patternlength; i++)
    fprintf(stderr, "L3b: D %d\n", i),
                    putchar('.');
            }
            count++;
            printf(" %s\n", guess);
        }
        if (strcmp(key, guess) != 0)
        {
            printf("You did not guess the pattern!\n");
        }
        else 
        {
            printf("You guessed the pattern!\n");
        }
        return 0;
    }
    
    引入了函数
    prompt\u int()
    prompt\u str()
    来获取数据。
    prompt\u str()
    函数对溢出具有相当的弹性。有一个错误报告函数。虚拟函数被替换。下面是一些示例输出。从这里开始,您就可以依靠自己了

    Length of key: 4
    Number of guesses: 8
    Input the key pattern with no spaces: abcd
    Input a guess pattern with no spaces: aaaa
    Guess: 0 [aaaa] marks [b...]
    Input a guess pattern with no spaces: dcba
    Guess: 0 [aaaa] marks [b...]
    Guess: 1 [dcba] marks [wwww]
    Input a guess pattern with no spaces: cdba
    Guess: 0 [aaaa] marks [b...]
    Guess: 1 [dcba] marks [wwww]
    Guess: 2 [cdba] marks [wwww]
    Input a guess pattern with no spaces: abcd
    You guessed the pattern!
    

    我假设存在一个结构(为了方便复制其中包含的数组),并且输入验证确保键和猜测的长度相同,并且键和猜测只包含字母字符

    typedef struct pattern
    {
        char pattern[8];
    } pattern;
    
    size_t print_scoring(pattern key, pattern guess)
    {
        size_t n = strlen(key.pattern);
        assert(n == strlen(guess.pattern));
        size_t bcount = 0;
        for (size_t i = 0; i < n; i++)
        {
            if (key.pattern[i] == guess.pattern[i])
            {
                putchar('b');
                key.pattern[i] = guess.pattern[i] = '.';
                bcount++;
            }
        }
        if (bcount != n)
        {
            size_t wcount = 0;
            for (size_t i = 0; i < n; i++)
            {
                if (guess.pattern[i] != '.')
                {
                    for (size_t j = 0; j < n; j++)
                    {
                        if (guess.pattern[i] == key.pattern[j])
                        {
                            wcount++;
                            putchar('w');
                            guess.pattern[i] = key.pattern[j] = '.';
                            break;
                        }
                    }
                }
            }
            for (size_t i = bcount + wcount; i < n; i++)
                putchar('.');
        }
        return bcount;
    }
    
    测试输出
    从评论中 为什么我的代码不起作用?你能看一下吗? 问题是,在输入猜测模式后,我无法进入下一步。也许我在代码中没有看到一些错误

    即时响应:


    我的答案中的一个关键点是,比较代码处理的是输入数据的副本。这是一种破坏性的比较算法,在数据上写点。您试图将我的代码合并到您的程序中时,没有保留单独的函数处理数据的单独副本,这些副本是这个答案的关键部分有一个结构的se可以方便地传递数据副本(这是C为您自动复制数组的一次机会)。比较代码应该在它自己的函数中,而不是在
    main()
    中内联

    但是,我们可以让给定的代码正常工作。有一些转录错误(下面标记为BUG)和一些其他问题(也在下面识别)

    有关修订守则的工作版本 这是您的程序的工作版本,带有关键更改。非关键更改包括运算符周围的间距和使用4个空格的缩进级别

    #include <string.h>
    #include <stdio.h>
    
    static int length(void) { return 3; }    // Dummy function
    static int guessnum(void) { return 5; }  // Dummy function
    
    int main(void)
    {
        int patternlength = length();
        char key[patternlength+1];      // Buffer overflow
        char keyc[patternlength+1];     // Copy of key
        int numguess = guessnum();
        char guess[patternlength+1];    // Buffer overflow
        printf("Input the key pattern with no spaces: ");
        scanf("%s", key);
        int i,j,count = 1;
        int bcount = 0, wcount = 0;
        char guessc[patternlength+1];   // Buffer overflow
        guessc[0] = '\0';               // Initialize!
        while (strcmp(key, guess) != 0 && count <= numguess)
        {
            strcpy(keyc, key);          // Copy key too
            printf("Input a guess pattern with no spaces: ");
            scanf("%s", guess);
            strcpy(guessc, guess);
    
            wcount = 0;     // Reinitialize
            bcount = 0;     // Reinitialize
            printf("%d: ", count);
            for (i = 0; i < patternlength; i++)
            {
                if (keyc[i] == guessc[i])
                {
                    putchar('b');
                    keyc[i] = guessc[i] = '.';
                    bcount++;
                }
            }
            if (bcount != patternlength)    // Extraneous semi-colon excised! ;
            {
                for (i = 0; i < patternlength; i++)
                {
                    if (guessc[i] != '.')
                    {
                        //for (j = 0; i < patternlength; j++) BUG
                        for (j = 0; j < patternlength; j++)
                        {
                            //if (guessc[i] == keyc[i]) BUG
                            if (guessc[i] == keyc[j])
                            {
                                wcount++;
                                putchar('w');
                                //guessc[i] = keyc[i];  BUG
                                keyc[j] = guessc[i] = '.';
                                break;
                            }
                        }
                    }
                }
                for (i = bcount  +  wcount; i < patternlength; i++)
                    putchar('.');
            }
            count++;
            printf(" %s\n", guess);
        }
        if (strcmp(key, guess) != 0)
        {
            printf("You did not guess the pattern!\n");
        }
        else 
        {
            printf("You guessed the pattern!\n");
        }
        return 0;
    }
    
    如果你的编译器没有告诉你这一点,你就不是u
    ss2.c: In function ‘main’:
    ss2.c:36:37: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
    
    gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
        -Wold-style-definition ss2.c -o ss2
    
    Input the key pattern with no spaces: abc
    Input a guess pattern with no spaces: aaa
    1: b.. aaa
    Input a guess pattern with no spaces: bbb
    2: b.. bbb
    Input a guess pattern with no spaces: ccc
    3: b.. ccc
    Input a guess pattern with no spaces: cab
    4: www cab
    Input a guess pattern with no spaces: abc
    5: bbb abc
    You guessed the pattern!
    
    #include <string.h>
    #include <stdio.h>
    
    static int length(void) { return 3; }
    static int guessnum(void) { return 5; }
    
    int main(void)
    {
        int patternlength = length();
        char key[patternlength+1];      // Buffer overflow
        char keyc[patternlength+1];     // Copy of key
        int numguess = guessnum();
        char guess[patternlength+1];    // Buffer overflow
        printf("Input the key pattern with no spaces: ");
        scanf("%s", key);
        int i,j,count = 1;
        int bcount = 0, wcount = 0;
        char guessc[patternlength+1];   // Buffer overflow
        guessc[0] = '\0';               // Initialize!
        while (strcmp(key, guess) != 0 && count <= numguess)
        {
            strcpy(keyc, key);          // Copy key too
            printf("Input a guess pattern with no spaces: ");
            scanf("%s", guess);
            strcpy(guessc, guess);
    
    fprintf(stderr, "B1: (%s) vs (%s)\n", key, guess);
    fprintf(stderr, "B2: (%s) vs (%s)\n", keyc, guessc);
            wcount = 0;     // Reinitialize
            bcount = 0;     // Reinitialize
            printf("%d: ", count);
            for (i = 0; i < patternlength; i++)
            {
    fprintf(stderr, "L1a: %d\n", i);
                if (keyc[i] == guessc[i])
                {
    fprintf(stderr, "L1b: B (%c = %c)\n", keyc[i], guessc[i]);
                    putchar('b');
                    keyc[i] = guessc[i] = '.';
                    bcount++;
                }
            }
    fprintf(stderr, "M1: (%s) vs (%s)\n", keyc, guessc);
            if (bcount != patternlength)    // Extraneous semi-colon excised! ;
            {
    fprintf(stderr, "L2a: b = %d (%s) vs (%s)\n", bcount, keyc, guessc);
                for (i = 0; i < patternlength; i++)
                {
    fprintf(stderr, "L2b: %d (%c)\n", i, guessc[i]);
                    if (guessc[i] != '.')
                    {
    fprintf(stderr, "L2c: %d (%c)\n", i, guessc[i]);
                        //for (j = 0; i < patternlength; j++) BUG
                        for (j = 0; j < patternlength; j++)
                        {
    fprintf(stderr, "L2d: %d (%c) vs %d (%c)\n", i, guessc[i], j, keyc[j]);
                            //if (guessc[i] == keyc[i]) BUG
                            if (guessc[i] == keyc[j])
                            {
    fprintf(stderr, "L2e: W %d (%c) vs %d (%c)\n", i, guessc[i], j, keyc[j]);
                                wcount++;
                                putchar('w');
                                keyc[j] = guessc[i] = '.';
                                //guessc[i] = keyc[i];  BUG
                                break;
                            }
                        }
                    }
                }
    fprintf(stderr, "L3a: %d + %d vs %d\n", bcount, wcount, patternlength);
                for (i = bcount  +  wcount; i < patternlength; i++)
    fprintf(stderr, "L3b: D %d\n", i),
                    putchar('.');
            }
            count++;
            printf(" %s\n", guess);
        }
        if (strcmp(key, guess) != 0)
        {
            printf("You did not guess the pattern!\n");
        }
        else 
        {
            printf("You guessed the pattern!\n");
        }
        return 0;
    }
    
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    static void err_exit(const char *msg, ...);
    static void prompt_str(const char *prompt, int bufsiz, char *buffer);
    static int  prompt_int(const char *prompt);
    
    int main(void)
    {
        int  patternlength = prompt_int("Length of key");
        int  numguess = prompt_int("Number of guesses");
        char key[patternlength+1];
        char guesses[numguess][patternlength+1];
        char marks[numguess][patternlength+1];
        int  count = 0;
    
        prompt_str("Input the key pattern with no spaces", patternlength, key);
    
        while (count < numguess)
        {
            char guess[patternlength+1];
            char keyc[patternlength+1];
            char mark[patternlength+1];
            char *marker = mark;
            int wcount = 0;
            int bcount = 0;
    
            strcpy(keyc, key);
            prompt_str("Input a guess pattern with no spaces", patternlength, guess);
            strcpy(guesses[count], guess);
    
            for (int i = 0; i < patternlength; i++)
            {
                if (keyc[i] == guess[i])
                {
                    *marker++ = 'b';
                    keyc[i] = guess[i] = '.';
                    bcount++;
                }
            }
            if (bcount == patternlength)
                break;
            for (int i = 0; i < patternlength; i++)
            {
                if (guess[i] == '.')
                    continue;
                for (int j = 0; j < patternlength; j++)
                {
                    if (guess[i] == keyc[j])
                    {
                        wcount++;
                        *marker++ = 'w';
                        keyc[j] = guess[i] = '.';
                        break;
                    }
                }
            }
            for (int i = bcount  +  wcount; i < patternlength; i++)
                *marker++ = '.';
            *marker = '\0';
            strcpy(marks[count], mark);
            count++;
            for (int i = 0; i < count; i++)
                printf("Guess: %d [%s] marks [%s]\n", i, guesses[i], marks[i]);
        }
        if (count >= numguess)
            printf("You did not guess the pattern (which was [%s])!\n", key);
        else 
            printf("You guessed the pattern!\n");
        return 0;
    }
    
    static void prompt_str(const char *prompt, int bufsiz, char *buffer)
    {
        char fmt[8];
        int  c;
    
        sprintf(fmt, "%%%ds", bufsiz);
        printf("%s: ", prompt);
        if (scanf(fmt, buffer) != 1)
            err_exit("Unexpected input failure\n");
        while ((c = getchar()) != EOF && c != '\n')
            ;
    }
    
    static int prompt_int(const char *prompt)
    {
        int number;
        printf("%s: ", prompt);
        if (scanf("%d", &number) != 1)
            err_exit("Unexpected input failure\n");
        if (number <= 0 || number > 9)
            err_exit("Number should be in the range 1..9 (not %d)\n", number);
        return(number);
    }
    
    static void err_exit(const char *fmt, ...)
    {
        va_list args;
        va_start(args, fmt);
        vfprintf(stderr, fmt, args);
        va_end(args);
        exit(1);
    }
    
    Length of key: 4
    Number of guesses: 8
    Input the key pattern with no spaces: abcd
    Input a guess pattern with no spaces: aaaa
    Guess: 0 [aaaa] marks [b...]
    Input a guess pattern with no spaces: dcba
    Guess: 0 [aaaa] marks [b...]
    Guess: 1 [dcba] marks [wwww]
    Input a guess pattern with no spaces: cdba
    Guess: 0 [aaaa] marks [b...]
    Guess: 1 [dcba] marks [wwww]
    Guess: 2 [cdba] marks [wwww]
    Input a guess pattern with no spaces: abcd
    You guessed the pattern!