2009-03-30 1 views
6

У меня есть массив строк, заполненный словами из предложения.Мне нужно иметь ключ с несколькими значениями. Какую структуру данных вы бы порекомендовали?

слова [0] = "на"
слова [1] = "собака"
слова [2] = "прыгнули"
слова [3] = "над"
слова [4] = " «
слов [5] =« стена ».
слова [6] = "на"
слова [7] = "кошки"
слова [8] = "упал"
слова [9] = "выключено"
слов [10] = "The"
слов [10] = "дом."
и т.д. (Глупый пример, но он работает для этого)

Каждого слово будет ключевым с этим следующим словом, как это значение. поэтому "over" => "the". Некоторые клавиши могут иметь несколько значений. Например, «the» => «собака» || "стена" || "кошка" || "дом". Значение выбирается случайным образом из значений для этого ключа.

Когда программа запускается, она выбирает слово наугад и делает предложение. Так может быть что-то вроде: «кот упал с собаки».

Я попытался реализовать карту (map myMap;), но это позволяет использовать только одно значение для ключа (я думаю).

Надеюсь, я объяснил это право.

ответ

4

вы можете использовать Multimap из STL и использовать вызов

pair<iterator, iterator> equal_range(const key_type& k) 

, чтобы получить диапазон итераторов, которые соответствуют вашим ключевым

лично я нахожу это немного неуклюжим из-за необходимости иметь дело с итератора а не просто возвращает объект обратно, который представляет все значения для этого ключа. чтобы обойти это, вы также можете сохранить вектор на обычной карте и добавить свои строки в вектор.

24

std::multimap

Ссылка обеспечивает отличный пример. Цитируется ниже:

int main() 
{ 
    multimap<const char*, int, ltstr> m; 

    m.insert(pair<const char* const, int>("a", 1)); 
    m.insert(pair<const char* const, int>("c", 2)); 
    m.insert(pair<const char* const, int>("b", 3)); 
    m.insert(pair<const char* const, int>("b", 4)); 
    m.insert(pair<const char* const, int>("a", 5)); 
    m.insert(pair<const char* const, int>("b", 6)); 

    cout << "Number of elements with key a: " << m.count("a") << endl; 
    cout << "Number of elements with key b: " << m.count("b") << endl; 
    cout << "Number of elements with key c: " << m.count("c") << endl; 

    cout << "Elements in m: " << endl; 
    for (multimap<const char*, int, ltstr>::iterator it = m.begin(); 
     it != m.end(); 
     ++it) 
    cout << " [" << (*it).first << ", " << (*it).second << "]" << endl; 
} 
+0

Благодарим за быстрый ответ. При использовании карты я могу получить доступ к значениям с помощью map [key]. Как получить значения с помощью мультимапа? –

+1

@Haawk: у multimap есть метод с именем equal_range(), который вернет пару итераторов, указывающих диапазон элементов, равный заданному ключу. –

0

Как указывали другие, std :: multimap может быть вашим решением.

Также рассмотрите std::tr1::unordered_multimap. Он доступен в VS 2008, похоже, имеет его, GCC имеет его по крайней мере с версии 4.3.

4

Если вы используете C++, то просто создать класс для представления ваших пар ключ-значение:

Class foo { 
    key : String 
    values : list of values 
} 

Затем создать карту, которая отображает каждый ключ объект, содержащий его значения.

Это прост, расширяемый и может быть выполнен на любом языке OO.

Извините, мой C++ ржавый, поэтому синтаксис неправильный, но основная идея проста.

0

Вы также можете использовать unordered_map>, который имеет некоторое преимущество над структурой карты. Вы можете сделать такую ​​вставку, если ваш словарь как «с»: «кошка», «с»: «автомобиль», «а»: яблоко, «а»: «Ангус»:

unordered_map<char, vector<string>> char_to_strings_map; 
//loop to traverse the dictionary : key:c, value:s 
    char_to_strings_map[c].emplace_back(s); 
//loop ends 
0

Там может быть альтернативный подход к достижению двух значений для каждого ключа, особенно для случаев, когда большинство элементов карты имеют два значения на ключ. При сопряжении двух значений ключа, как указано в этом link:

std::map<std::string, std::pair<std::int, int> > myMap2 

использовать его в функции как:

#include<iostream> 
#include<map> 
#include<iterator> 
using namespace std; 
int main(){ 
map<string,pair<int,int>>mp; 
mp.insert(pair<string,pair<int,int>>("ab",make_pair(50,7))); 
mp.insert(pair<string,pair<int,int>>("cd",make_pair(51,8))); 
map<string,pair<int,int>>::iterator it; 
for(it=mp.begin();it!=mp.end();it++) 
    cout<<it->first<<" "<<it->second.first<<" "<<it->second.second<<" "; 
return 0; 
} 
0

Я обнаружил, что структура может хорошо работать для этой ситуации. Этот подход (в основном похожий на класс) позволяет более чистый доступ к вашим параметрам, названным так, как вы сочтете нужным.

struct car_parts { 

    string wheelType; 
    string engine; 
    int number_of_cylinders; 

    car_parts(string _wheelType, string _engine, int _number_of_cylinders) 
    { 
     wheelType = _wheelType; 
     engine = _engine; 
     number_of_cylinders = _number_of_cylinders; 
    } 
}; 

int main() 
{ 
    // Populate the dictionary 
    map<char, car_parts> vehicles = 
    { 
     { 'I', car_parts("All terrain", "X2", 6) }, 
     { 'C', car_parts("Summer only", "BB", 8) }, 
     { 'U', car_parts("All terrain", "X3", 4) } 
    }; 

    map<char, car_parts>::iterator it; 

    it = vehicles.find('I'); 

    if (it != vehicles.end()) 
    { 
     cout << "The vehicle with key of I has " << it->second.number_of_cylinders << " cylinders\n"; 
    } 
} 
Смежные вопросы