Wyświetlanie mapy w losowym porządku

0

Witajcie!

W celu poznania kontenerów, tworzę prosty projekt (aplikację konsolową do nauki słówek po ang metodą qwerty).

Mam taki dylemat. Gdy użytkownik będzie chciał się pouczyć słówek, wciśnie literę a, wywoła się metoda z klasy learn.

void learn::LearnVocabularyAngPol(map<string,string>temp)
for (auto it = temp.begin(); it != temp.end(); ++it)
	{
		string temp_pol, temp_ang;
		cout << it->first << " - ";
		cin >> temp_pol;
		transform(temp_pol.begin(), temp_pol.end(), temp_pol.begin(), ::tolower);
		temp_ang = it->second;
		transform(temp_ang.begin(), temp_ang.end(), temp_ang.begin(), ::tolower);
		if (temp_pol == temp_ang)
		{
			cout << "Prawidlowa odpowiedz." << endl;
		}
		else
		{
			cout << "Prawidlowa odpowiedz to: " << it->second<< endl;
		}
	}

Za każdym razem użytkownik będzie pytany o słówka w dokładnie tej samej kolejności co poprzednio. To trochę bez sensu.

Czy jest jakiś sposób by losowo przechodzić przez mapę bez powtórzeń?

Myślałem nad takim rozwiązaniem - osobna metoda, która stworzy mapę <int,map<string,string>::iterator> i dla wartości klucza będzie losowo dobierać iterator. Ale jak? :/ Siedzę i myślę i nic nie wymyśle... Macie jakieś pomysły?

3

Trzymaj dane w wektorze i użyj random_shuffle

0
spartanPAGE napisał(a):

Trzymaj dane w wektorze i użyj random_shuffle

Tzn? W wektorze ciężko trzymać dwa odpowiadające sobie słówka, w mapie dużo wygodniej. Tutaj mam problem :/

3
  1. Kopiujesz kluczy do wektora
  2. Random_shuffle
  3. Wyświetlasz wg porządku wektora.
0
insectoman napisał(a):
spartanPAGE napisał(a):

Trzymaj dane w wektorze i użyj random_shuffle

Tzn? W wektorze ciężko trzymać dwa odpowiadające sobie słówka, w mapie dużo wygodniej. Tutaj mam problem :/

Serio?

 vector<pair<string, string>>
0

Działa, zrobiłem to w ten sposób:

void learn::LearnVocabularyAngPol(map<string,string>temp)
{
	vector <string> temp_vector;
	int i = 0;
	for (auto it = temp.begin(); it != temp.end(); ++it)
	{
		temp_vector.push_back(it->first);
	}

	random_shuffle(temp_vector.begin(), temp_vector.end());

	for (int i = 0; i < temp_vector.size(); ++i)
	{
		string temp_pol, temp_ang;
		auto it=temp.find(temp_vector[i]);
		cout << it->first << " - ";
		cin >> temp_pol;
		transform(temp_pol.begin(), temp_pol.end(), temp_pol.begin(), ::tolower);
		temp_ang = it->second;
		transform(temp_ang.begin(), temp_ang.end(), temp_ang.begin(), ::tolower);
		if (temp_pol == temp_ang)
		{
			cout << "Prawidlowa odpowiedz." << endl;
		}
		else
		{
			cout << "Prawidlowa odpowiedz to: " << it->second << endl;
		}
	}
}

Jak możecie to zerknijcie i powiedzcie co zrobiłem źle, co mogłem lepiej.

0

Na pewno przekazanie mapy przez kopię to beznadziejny pomysł.

0

Przez referencję będzie szybciej czy chodzi o jakieś inne aspekty?

Zmieniłem na:

void learn::LearnVocabularyAngPol(const map<string,string>&temp) 
0

Przez wartość - tworzysz kopię całej mapy.

0

Chwila, czy dobrze rozumiem? Nie przez referencję a przez wskaźnik tak?

3
insectoman napisał(a):

Chwila, czy dobrze rozumiem? Nie przez referencję a przez wskaźnik tak?

W pierszym kodzie przekazywałeś mapę przez wartość, co skutkowało skopiowaniem jej zawarosci do zmiennej temp. Nie jest to potrzebne, można użyć referencji do oryginalnej mapy. Jakbyś miał milion słów, to kopiowałbyś milion słów w pamięci do innego - w dodatku tymczasowego - kontenera, tylko dlatego, że nie wstawiłeś tam &.

PS.
Zmiast

for (auto it = temp.begin(); it != temp.end(); ++it)
{
    temp_vector.push_back(it->first);
}

możesz zrobić tak:

for (auto &words_pair : temp)
{
    temp_vector.push_back(words_pair.first);
}
0
nalik napisał(a):
insectoman napisał(a):

Chwila, czy dobrze rozumiem? Nie przez referencję a przez wskaźnik tak?

W pierszym kodzie przekazywałeś mapę przez wartość, co skutkowało skopiowaniem jej zawazrosci do zmiennej temp. Nie jest to zupelnie potrzebne, można użyć referencji do oryginalnej mapy.

No to tak zrobiłem, dzięki :)

for (auto &words_pair : temp)
{
    temp_vector.push_back(words_pair.first);
}

Co oznacza words_pair : temp ? To jakiś nowy zapis pętli for?

Tutaj odpowiedź na moje pytanie jeśli by ktoś szukał: http://kacperkolodziej.pl/artykuly/programowanie/262-cpp-11-nowa-skladnia-petli-for.html

2

zamiast std::random_shuffle powinno się używać std::shuffle
http://en.cppreference.com/w/cpp/algorithm/random_shuffle

Co oznacza words_pair : temp ? To jakiś nowy zapis pętli for?

http://en.cppreference.com/w/cpp/language/range-for

1 użytkowników online, w tym zalogowanych: 0, gości: 1