Как заставить char [] работать с std :: map - PullRequest
1 голос
/ 02 июня 2011

РЕДАКТИРОВАТЬ после ответа:

< должно быть предоставлено для std::map. Для получения дополнительной информации о рекомендациях обратитесь к ответу Джеймса Макнеллиса .

Код, включенный в этот вопрос, написан плохо. Это просто потому, что я играю с SPOJ и входные данные строго действительны. Подход std::string - это то, что я выбрал сначала, но он оказался недостаточно быстрым.

Спасибо.


Я знаю, что не могу использовать char[] напрямую с картой, например map<char[], int>. Таким образом, я положил это в классе. Но это все еще может пройти компиляцию. Как с этим бороться?


#include <stdio.h>
#include <map>

using namespace std;

class id {
public:
    char v [30];
};

int main () {
    map<id, int> m;
    id a;
    while (gets(a.v)) {
        m[a]++;
    }
    return 0;
}

/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = id]’:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_map.h:418:   instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = id, _Tp = int, _Compare = std::less<id>, _Alloc = std::allocator<std::pair<const id, int> >]’
prog.cpp:15:   instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’

Кажется, это как-то связано со сравнением, но я все еще в неведении.

Ответы [ 3 ]

6 голосов
/ 02 июня 2011

Перво-наперво: никогда, никогда не используйте gets.Его нельзя использовать безопасно, и любая программа, использующая его, имеет уязвимость безопасности.Не существует способа ограничить количество символов, которые gets может записать в буфер, который вы его предоставили, поэтому нет способа предотвратить переполнение буфера.Если вам нужно использовать библиотеку CI / O, вы должны вместо этого использовать fgets, что позволяет указать максимальное количество символов для чтения.

Причина появления этой ошибки заключается в том, чтотип ключа, который вы используете, должен быть как-то сопоставим.По умолчанию std::map использует operator<, который вы не определяете для id, следовательно, ошибка компиляции.Вам нужно либо определить operator< для сравнения двух id объектов, либо написать функтор сравнения, который можно использовать для сравнения двух объектов.Независимо от того, что вы выберете, компаратор должен обеспечить строго-слабый порядок .

Поскольку вы программируете на C ++, идеальным решением здесь является использование идиоматического C ++:

std::map<std::string, int> m;
std::string s;
while (std::cin >> s) {
    m[s]++;
}

std::string уже предоставляет operator<, который обеспечивает лексикографическое упорядочение, поэтому вам не нужно определять компаратор самостоятельно.

3 голосов
/ 02 июня 2011

Вам необходимо реализовать оператор <

class id {
public:
    char v [30];
    bool operator<(const id &rhs) const{
        return strcmp(v,rhs.v) < 0;
    }
};

РЕДАКТИРОВАТЬ: Как примечание, ваш код очень плохой способ делать вещи. См. Некоторые ответы для объяснения, почему.

0 голосов
/ 02 июня 2011

Чтобы вставить в карту, карта должна иметь возможность сравнивать идентификаторы.Вы не предоставили реализацию оператора <, которую он может использовать.У вас есть два варианта: </p>

  1. Укажите один пример, приведенный здесь другим ответом.
  2. Вместо этого используйте std :: string.

Я думаю, вам следуетиспользовать std :: string.Вы можете использовать метод .c_str () для преобразования его в массив символов, когда вам это необходимо.

...