Loading...
spasimira25 avatar spasimira25 25 Точки

Задача 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;

  }

 

Тагове:
0
C++ Fundamentals
Vankata83 avatar Vankata83 72 Точки

Между другото аз съм използвал map и vector и ми заема 1.82 MB, а като пробвах твоето решение ми зае 2.07 MB

Не знам дали judge е фактор в това (натовареност и др.)

Само вмятам :)

1
spasimira25 avatar spasimira25 25 Точки

Огромно благодаря, Ванка. Принципно еоф "чете" до края на файл, и понеже стрийма е горе-долу унифициран, в случая "чете" до края на реда, който съм взел с гетлайн. За съжаление, ако накрая на реда (след последния стринг ) има набити няколко интервала, не се държи нормално. Използвах го за 1-ва задача и сработи на 100%. Ако си я тествам обаче аз и сложа 2-3 интервала се сбърква runtime. Същото е и с 2-ра. Няколко допълнителни интервала на края и умира. Явно това е било и в джъдж. На 2 от  тестовете има 2(или повече) интервала, а не 1. Няма да го ползвам повече.

Още веднъж, благодаря. Спести ми много нерви :)  Цял следобед я мъча.
Поздрави, Тошо.

0
spasimira25 avatar spasimira25 25 Точки

А принципно става 2.07, заради едно setlocale(LC_ALL,"bulgarian"); което сложих от нямане какво да праявя.
Принципно е за да печата на кирилица на конзолата. Не се сработи с писането обаче. Като го махнах стана 1.82МБ
е и от инклудовете изтрих маповете...

 

0
Vankata83 avatar Vankata83 72 Точки

Вече и аз знам какво прави eof :)

0
alexandar_zhelev avatar alexandar_zhelev 1 Точки

Привет,

За да може да печаташ на кирилица на конзолата, освен това setlocale(LC_ALL,"bulgarian"); , трябва да добавиш най-горе #include <locale>, ако не си. Това е библиотеката която ти е нужна за четенето на кирилица. Предполагам, че за това не е сработило при теб. :)

Поздрави!

0
Boyanandreev avatar Boyanandreev 3 Точки

Здравейте,

 

//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 не получавам изхода. Ако може да ми дадете някаква насоки къде греша.

И има ли вариант при принтирането да не създавам още един вектор а да принтирам от мапа.

0
Vankata83 avatar Vankata83 72 Точки

При използването на unordered_map няма никакво правило по което се подреждат елементите - на твоя компютър като се стартира програмата излизат в един ред, на друг компютър - в друг ред. Тук смисъла да изплозваш вектор като записваш всеки един string още в началото, е за да може да им пазиш реда на постъпване. След това като тръгнеш да ги печаташ почваш да обхождаш този вектор, вземаш всеки елемент и проверяваш от мапа дали е с четна стойност или не.

Грешката при теб, е че обхождаш мапа, за да провериш дали е четен или не. Мапа от своя страна вече не пази елементите по тяхното постъпване. Map пази по азбучен ред, а пък unsorted_map въобще не пази сортировка.

0
kolioi avatar kolioi 625 Точки

Ето ви едно решение с вктор и без мапове. Пускам го за да ви покажа някои алтернативни начини за решаване, например разделянето на стринговете при печатане. Програмата използва само 1.80 MB памет.

#include <iostream>
#include <sstream>
#include <vector>
#include <cctype>
#include <utility>

using namespace std;

void make_lower(string& word)
{
	for (char& ch : word)
		ch = tolower(ch);
}

int main()
{
	string line;
	getline(cin, line);

	istringstream iss(line);
	string word;
	using word_count = pair<string, int>;
	vector<word_count> words;
	while (getline(iss, word, ' '))
	{
		make_lower(word);
		int i;
		for (i = 0; i < words.size(); i++)
			if (word == words[i].first)
			{
				words[i].second++;
				break;
			}
		if (words.size() == i)
			words.push_back(make_pair(word,1));
	}

	string separator = "";
	for (const auto& p : words)
		if (p.second % 2 == 1)
		{
			cout << separator << p.first;
			separator = ", ";
		}
	cout << endl;
}

 

0
dmartinov avatar dmartinov 37 Точки

Не съм пробвал кода ти, но ако наистина проблема му е, че печата в обратен ред или трябва да смениш логиката с която пълниш вектора или просто го обхождай с реверсивен итератор. Дефинира се така:

std::vector<std::string>::reverse_iterator rItr;

for (rItr = myVector.rbegin(); rItr != myVector.rend(); ++ rItr)

0
zzerro avatar zzerro 16 Точки

Интересно :)

Ето решение, в което ползвам мултисет само за брояч, а после наново обхождам входа заради реда. Предлагам и друг начин да оправиме изхода:

#include <iostream>
#include<sstream>
#include<set>

using namespace std;

int main()
{
    string szIn;
    getline(cin, szIn);

    for(size_t i = 0; i < szIn.size(); ++i)
        szIn[i] = tolower(szIn[i]);

    istringstream issParser(szIn);
    string szWord;

    multiset<string> multisetStr;
    while(issParser >> szWord)
        multisetStr.insert(szWord);

    issParser.clear();
    issParser.str(szIn);
    ostringstream ossOut;

    multiset<string>::iterator itrMultiset;

    while(issParser >> szWord)
    {
        itrMultiset = multisetStr.find(szWord);
        if(itrMultiset != multisetStr.end() && multisetStr.count(*itrMultiset) & 1)
        {
            ossOut << *itrMultiset <<  ", ";
            multisetStr.erase(szWord);
        }
    }

    ossOut.seekp(-2, ios_base::end);
    ossOut << " ";
    cout << ossOut.str();

    return 0;
}

 

0
25/11/2019 12:06:40
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.