Задача 2 Odd Occurrences
Здравейте, нещо блокирах на 2-ра задача от асоциативните контейнери. Дава ми грешен отговор на тест1 и тест4. Време и памет са ок.
#include <iostream>
#include <map>// въпреки, че не ги ползвам пробвах едно решение с тях и не ми хареса...
#include <unordered_map>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main (){
setlocale(LC_ALL,"bulgarian");// абсолютно ненужно
string str;
getline(cin, str);
stringstream ss;
vector<pair <string, int>> myVector;
ss << str;
string temp;
while (!ss.eof()) {
ss >> temp;
string lowString="";
bool is_exist=false;
// следва превръщане в малки букви
for(int i=0;i<temp.size();i++ ){
lowString+=tolower(temp[i]);
}/// следва проверка дали вече има подобен стринг
for (int i=0;i<myVector.size();++i ){
if( myVector[i].first==lowString){
myVector[i].second++;/// ако го има увеличавам втория пейр и брейквам, няма смисъл да продължавам да търся
is_exist=true;break;}
}
if (is_exist==false){myVector.push_back(make_pair(lowString, 1));}///ако го няма създавам нова двойка във вектора
}
/// следва печат, не знам дали има друг метод, за добавяне на запетайки, без да се добави на последния елемент
vector<string> outVector;
for (int i=0;i<myVector.size();i++){
if (myVector[i].second%2==1){outVector.push_back(myVector[i].first);}
}
for (int i=0;i<outVector.size()-1;i++){
cout<<outVector[i]<<", ";
}
cout<<outVector[outVector.size()-1]<<endl;
}
Огромно благодаря, Ванка. Принципно еоф "чете" до края на файл, и понеже стрийма е горе-долу унифициран, в случая "чете" до края на реда, който съм взел с гетлайн. За съжаление, ако накрая на реда (след последния стринг ) има набити няколко интервала, не се държи нормално. Използвах го за 1-ва задача и сработи на 100%. Ако си я тествам обаче аз и сложа 2-3 интервала се сбърква runtime. Същото е и с 2-ра. Няколко допълнителни интервала на края и умира. Явно това е било и в джъдж. На 2 от тестовете има 2(или повече) интервала, а не 1. Няма да го ползвам повече.
Още веднъж, благодаря. Спести ми много нерви :) Цял следобед я мъча.
Поздрави, Тошо.
А принципно става 2.07, заради едно setlocale(LC_ALL,"bulgarian"); което сложих от нямане какво да праявя.
Принципно е за да печата на кирилица на конзолата. Не се сработи с писането обаче. Като го махнах стана 1.82МБ
е и от инклудовете изтрих маповете...
Вече и аз знам какво прави eof :)
Привет,
За да може да печаташ на кирилица на конзолата, освен това setlocale(LC_ALL,"bulgarian"); , трябва да добавиш най-горе #include <locale>, ако не си. Това е библиотеката която ти е нужна за четенето на кирилица. Предполагам, че за това не е сработило при теб. :)
Поздрави!
Здравейте,
//2.OddOccurrences
#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <unordered_map>
int main()
{
using namespace std;
string inputString;
getline(cin, inputString);
istringstream istr(inputString);
string word;
vector<string> outSrting;
vector<string> oddOcc;
unordered_map<string, int> countOccurences;
while (istr >> word)
{
transform(word.begin(), word.end(), word.begin(), ::tolower);
outSrting.push_back(word);
}
for (string & elem : outSrting)
{
auto result = countOccurences.insert(pair<string, int>(elem, 1));
if (result.second == false)
{
result.first->second++;
}
}
for (unordered_map<string, int>::iterator it = countOccurences.begin();
it != countOccurences.end(); ++it)
{
if (it->second % 2 != 0) {
oddOcc.push_back(it->first);
}
}
for(vector<string>::iterator it = oddOcc.begin(); it != oddOcc.end() - 1; ++it)
{
cout << *it << ", ";
}
cout << *(oddOcc.end() - 1) << endl;
return 0;
}
Здравейте,
Аз използвам unordered_map за решаването на задачата и при мен изхода ми се получава както в условието, но в judge се нареждат наобратно. При използване на map не получавам изхода. Ако може да ми дадете някаква насоки къде греша.
И има ли вариант при принтирането да не създавам още един вектор а да принтирам от мапа.
При използването на unordered_map няма никакво правило по което се подреждат елементите - на твоя компютър като се стартира програмата излизат в един ред, на друг компютър - в друг ред. Тук смисъла да изплозваш вектор като записваш всеки един string още в началото, е за да може да им пазиш реда на постъпване. След това като тръгнеш да ги печаташ почваш да обхождаш този вектор, вземаш всеки елемент и проверяваш от мапа дали е с четна стойност или не.
Грешката при теб, е че обхождаш мапа, за да провериш дали е четен или не. Мапа от своя страна вече не пази елементите по тяхното постъпване. Map пази по азбучен ред, а пък unsorted_map въобще не пази сортировка.
Ето ви едно решение с вктор и без мапове. Пускам го за да ви покажа някои алтернативни начини за решаване, например разделянето на стринговете при печатане. Програмата използва само 1.80 MB памет.
Не съм пробвал кода ти, но ако наистина проблема му е, че печата в обратен ред или трябва да смениш логиката с която пълниш вектора или просто го обхождай с реверсивен итератор. Дефинира се така:
std::vector<std::string>::reverse_iterator rItr;
for (rItr = myVector.rbegin(); rItr != myVector.rend(); ++ rItr)
Интересно :)
Ето решение, в което ползвам мултисет само за брояч, а после наново обхождам входа заради реда. Предлагам и друг начин да оправиме изхода: