拼字游戏点计数器 c++

Scrabble point counter c++

本文关键字:计数器 c++ 游戏      更新时间:2023-10-16
#include <iostream>
#include <string>
using namespace std;
int score(string s);
char scrabbleLetters[] = {'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 scrabblePoints[] = {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};
int main()
{
    string sWord;
    cout << "Enter the scrabble word you'd like to score.";
    cin >> sWord;
    cout << "You scored " << score(sWord)<< " points for that word!";
}
int score(string s)
{   int points = 0;
    for (int i = 0; i < s.length(); i++)
    {
        for (int j = 0; j < scrabbleLetters.length(); j++)
        {
            if (s[i] == scrabbleLetters[j])
                points += scrabblePoints[j];
        }
    }
    return points;
}

我似乎无法弄清楚为什么我的代码没有编译。该程序应该向用户询问一个单词,然后根据每个字母的分数对单词进行评分。

我当前收到的错误是:"错误:在'scrabbleLetters'中请求成员'长度',这是非类类型'char [26]'|">

C++内置数组没有length()成员函数。查找大小的一种方法是使用

for (int i = 0; i < std::distance(std::begin(s), std::end(s)); ++i) {
    ...
}

鉴于上述方法有点难看,可以将其打包成一个函数,例如:

template <typename T, std::size_t Size>
constexpr std::size_t length(T const (&)[Size]) {
    return Size;
}
...
for (std::size_t i(0); i != length(s); ++i) {
    ...
}

特别是对于char数组(或者,通常对于任何带有sizeof(T) == 1T类型(是使用sizeof(s)。但是请注意,这不适用于sizeof(T) != 1 的类型。您可能最好不要使用内置数组,而是使用std::vector<char>

std::vector<int> s{'a', 'b' /*...*/ };
for (std::size_t i(0); i != s.size(); ++i) {
    ...
}

您可以消除搜索并使用直接访问。

  1. 将字符串转换为全部小写
  2. 从字母中减去"a"以获得相对偏移量。
  3. 使用相对偏移量作为点数组的索引

下面是一些代码片段示例:

const unsigned int scrabblePoints[] =
{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};
int main()
{
    string sWord;
    cout << "Enter the scrabble word you'd like to score.";
    cin >> sWord;
    // Transform the word into all lowercase.
    std::transform(sWord.begin(), sWord.end(), sWord.begin, std::tolower);
    unsigned int points = 0;
    for (unsigned int i = 0; i < sWord.length(); ++i)
    {
       const char c = sWord[i];
       // Check if the character is a letter,
       //    it could be something like '?'.
       if (isalpha(c))
       {
         // Since the point's array starts with the letter 'a',
         // the index can be calculated by subtracting 'a' from
         // the character.
         unsigned int index = c - 'a';
         points += scrabblePoints[index];
       }
    }
    cout << "You scored "
         << points
         << " points for that word!"
         << "n";
  return 0; // Since main() returns a value.    
}

还有几种解决问题的方法(除了Dietmar Kühl的答案(

  1. 在循环开始之前计算保存拼字游戏字母的数组的长度。

    int score(string s)
    {
       int points = 0;
       int len = sizeof(scrabbleLetters);
       for (int i = 0; i < s.length(); i++)
       {
          for (int j = 0; j < len; j++)
          {
             if (s[i] == scrabbleLetters[j])
                points += scrabblePoints[j];
          }
       }
       return points;
    }
    

    警告:这种方法很脆弱。scrabbleLetters的定义必须对函数可见,才能正常工作。否则,sizeof(scrabbleLetters)最终将被sizeof(char*),这是行不通的。

  2. 一个更好的方法 - 完全避免内部循环。

    int score(string s)
    {
       int points = 0;
       for (int i = 0; i < s.length(); i++)
       {
          char ch = s[i];
          points += scrabblePoints[ch-'a'];
       }
       return points;
    }