Scrabble式字母计分程序故障:字符串中b之后字母未被统计
Scrabble字母计分程序问题修复
核心问题分析
你的代码里do-while循环的终止条件写反了:
while (n > 26);
n从0开始递增,初始值0远小于26,这个条件永远为假,导致循环只执行一次就退出。也就是说,每个字符最多只和letters[0](a)、letters[1](b)对比,后面的字母根本没机会被匹配到,这就是b之后的字母无法统计的原因。
修复后的基础版本代码
先修正循环条件,同时找到匹配项后直接跳出循环避免不必要的遍历:
#include <ctype.h> #include <cs50.h> #include <stdio.h> #include <string.h> int main (void) { char letters[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10}; string word1 = "banana"; int w1p = 0; for (int i = 0; i < strlen(word1); i++) { int n = 0; printf("%c" ,word1[i]); do { if (word1[i] == letters[n]) { w1p += POINTS[n]; printf(" matched\n"); break; // 找到匹配后直接跳出内层循环 } n++; } while (n < 26); // 修正循环条件:n小于26时继续遍历字母表 } printf("\nTotal points: %i\n" ,w1p); }
更高效的优化方案
其实不需要遍历字母数组,利用ASCII码的特性可以直接计算字母对应的索引:
把字符转为小写后,减去'a'的ASCII值,就能得到0-25的索引,直接对应POINTS数组的位置,代码更简洁高效,还能兼容大写字母:
#include <ctype.h> #include <cs50.h> #include <stdio.h> #include <string.h> int main (void) { int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10}; string word1 = "banana"; int w1p = 0; for (int i = 0; i < strlen(word1); i++) { char c = tolower(word1[i]); // 统一转为小写 if (c >= 'a' && c <= 'z') { // 确保是有效字母 int index = c - 'a'; w1p += POINTS[index]; } } printf("Total points: %i\n", w1p); }
内容的提问来源于stack exchange,提问作者Gustavo Chicoski
相关产品推荐
相关产品推荐

