2014-11-05 2 views
-1
#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; 
} 

Я не могу понять, почему мой код не компилируется. Предполагается, что программа запрашивает у пользователя слово, а затем записывает слово на основе точек на букву.Scrabble point counter C++

Текущая ошибка, которую я получаю: «error: запрос для длины члена» в «scrabbleLetters», который относится к классу non-class «char [26]» |

+0

Стек сниппет не предназначены для C++, FYI. –

+1

Этот пример использования действительно требует «std :: map » вместо сохранения двух параллельных массивов. – CoryKramer

+1

Вы, кажется, запутываете Java с C++. Перечитайте главу своего учебника, в которой представлены массивы. Он должен включать код, который демонстрирует, как использовать их в циклах. –

ответ

2

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 (или в целом для любого типа T с sizeof(T) == 1) используется sizeof(s). Обратите внимание, однако, что это не Работа для типов, где sizeof(T) != 1. Вы можете быть лучше не использовать встроенный в массив, а использовать std::vector<char>:

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

Ваш ответ намного лучше, чем то, что я собираюсь положить lol. +1 для вас, когда мой upvote перезаряжается. –

+0

Этот ответ будет страдать, если массив будет затухать, т. Е. Передать его функции в качестве параметра – LoPiTaL

+0

@LoPiTaL: вы имеете в виду, что первые два примера кода будут - правильно - не компилируются в этом случае, предупреждая пользователя о том, проблема? ... мотивируя далее изменить использование 'std :: vector '? –

-1

Пара больше способов решения проблемы (в дополнение к ответу Дитмар Kühl)

  1. Вычислить длину массива, в которой хранятся буквы scrabble до начала цикла.

    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; 
    } 
    
+0

Ваше первое решение пострадает, если массив затухает, т.е. передавая его функции в качестве параметра. Это решение даже хуже, чем у Dietman Kuhl, поскольку он будет бросать ошибку времени компиляции, в то время как ваш будет молча компилировать sizeof (scrabbleLetters) как sizeof (char *) – LoPiTaL

+0

@LoPiTaL, я это понимаю. Место, где оно используется, отображается полное объявление переменной. Следовательно, 'sizeof' будет оценивать количество элементов в массиве, так как его элементы имеют тип' char'. –

0

Вы можете устранить поиск и использовать прямой доступ.

  1. Преобразовать строку в нижнем регистре
  2. Вычитания «а» из письма, чтобы получить относительное смещение.
  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.  
}