Професионална програма
Loading...
+ Нов въпрос
Filipbg avatar Filipbg 26 Точки

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? Несхващам описанието на задачата. 

 
0
C++ Fundamentals
dmartinov avatar dmartinov 36 Точки

Ммммм....нещо не виждам къде пълниш числата във вектора :) И тоя входен поток дето си създал.....не го ползваш никъде ;) Така както си го написал създаваш един вектор с n на брой елементи, които обаче не съдържат нищо.

Идеята на задачата е да получиш от конзолата някаква поредност от числа, да провериш колко пъти се появяват в тази поредност и накрая да принтираш този резултат във възходящ ред. 

Моят жокер за решаването е - разгледай внимателно лекцията, още в самото начало където Живко показа как се достъпва map и какво се случва ако търсеното value го няма.

0
19/10/2019 17:29:59
Filipbg avatar Filipbg 26 Точки

Гледах пак лекцията, макар че доста неща с map и pair ме объркват. Промених си подхода И се опитвам да съединя прочетеното число с брояч. За да намеря колко пъти го има в потока. Чете ми ги числата, но брояча не работи. 

#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <map>
using namespace std;

int main()
{
    map<double, int> numbersMap;
    string line;
    getline(cin, line);
    istringstream numbersStream(line);
    double numberToRead = 0;
    int counter = 0;
    while(numbersStream >> numberToRead)
    {
        numbersMap.insert(pair<double, int>(numberToRead, counter));
        if(numbersMap.find(numberToRead) != numbersMap.end())
        {
            ++counter;
        }
        else
        {
            cin >> numberToRead;
        }
    }
    for(pair<double, int>number : numbersMap)
    {
        cout << number.first << " -> " << number.second << endl;
    }
    return 0;
}

 

0
galin_kostadinov avatar galin_kostadinov 163 Точки

Привет!

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;

Поздрави!

0
20/10/2019 14:57:59
dmartinov avatar dmartinov 36 Точки

Няма нужда да смесваш 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;
}
 

0