Count Real Numbers
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;
int main()
{
string lineOfNumbers;
getline(cin, lineOfNumbers);
istringstream numbersStream(lineOfNumbers);
vector<double> numbersVector(stod(lineOfNumbers));
sort(numbersVector.begin(), numbersVector.end(), greater<double>());
for(int i = 0; i < numbersVector.size(); ++i)
cout << numbersVector.at(i) << " -> ";
return 0;
}
Нещо ми се бърка от задачата. А пък и вектора ми занулява числата. Пробрах с pair от string and double, но ми гърми на getline да не би вместо да трябва да се сортират да трябва да се закрагляват с ceil? Несхващам описанието на задачата.
Гледах пак лекцията, макар че доста неща с map и pair ме объркват. Промених си подхода И се опитвам да съединя прочетеното число с брояч. За да намеря колко пъти го има в потока. Чете ми ги числата, но брояча не работи.
Привет!
Eто това е един работещ вариант:
Първо проверяваш дали елемента го няма, т.е. ако итератора ти върне numbersMap.end(), това означава, че вече си един елемент след този, който имаш последно записан в map, т.е. обходил си елемент по елемент map и нищо не е намерило, като ти връща numbersMap.end(). След което го добавяш със стойност 1, тъй като за сега само един път си го срещал. Ако след това пак имаш същата стойност, то итератора няма да ти върне numbersMap.end(), а ще ти върне итератор към съществуващата стойност.
if (numbersMap.find(numberToRead) == numbersMap.end()) {
numbersMap.insert(pair<double, int>(numberToRead, 1));
} else {
numbersMap[numberToRead]++;
}
- чрез този оператор [...] като използваш ключа numberToRead(в случая double), достъпваш до стойността (в случая int), но трябва да се внимава, понеже независимо дали има или няма записана стойност под този ключ, чрез този оператор директно се създава стойност(дефолтна за типа данни) и ключ(зададения).
- тъй като в случая се иска именно да се добави в map стойност, ако тя липсва е много удобно:
++numbersMap[numberToRead]; - така създаваш стойност ако липсва и увеличаваш дефолтната и стойност от 0 на 1 чрез ++[...].
Може да зададеш и някаква желана стойност(по прицип, в случая не ти трябва):
numbersMap[numberToRead] = 5;
Поздрави!
Няма нужда да смесваш map и pair. Решението на задачата наистина е в слайда от лекцията за достъпването на map. Идеята е следната - когато се опиташ да достъпиш нещо от map което не се съдържа в него, то първо се създава след което връща неговата default стойност според типа зададен при създаване на map-a. Иначе казано ако имаш std::map<int, int> и ти потърсиш в него числото 1, но то не се съдъжра, то 1-цата ще влезе като ключ, а за value ще имаш default стойност 0 (защото сме създали map от интиджъри). Та този път си сравнително на прав път. Това което трябва да направиш е да махнеш pair-a. Усложнява ти излишно логиката. Махни и тези IF-ове. В while цикъла където подаваш входния поток към числата, които ще търсиш директно се опитвай да ги достъпваш в map-а. По този начин освен, че ще създадеш ключа в мap-а, както казахме по-горе, се възползваш и от другото много удобно за случая свойство на map - не може да създадеш един ключ два пъти, но пък ако вече го има само ще промениш неговото value. Накрая ти остава само да принтираш съдържанието на map-а.
Hint - още при първото създаване на ключа сетни value-то му на 1. В противен случай ако имаш елемента само веднъж накрая ще ти принтира 0.
Ето моето решение:
#include <iostream>
#include <string>
#include <map>
#include <sstream>
void countRealNumbers(std::string input) {
double numbers = 0.0;
std::istringstream iss (input);
std::map<double, double> mapNumbers;
while (iss >> numbers) {
mapNumbers[numbers]++;
}
std::map<double, double>::iterator itr;
for(itr = mapNumbers.begin(); itr != mapNumbers.end(); ++itr) {
std::cout << itr -> first << " -> " << itr -> second << std::endl;
}
}
int main() {
std::string input;
getline(std::cin, input);
countRealNumbers(input);
return 0;
}