Loading...
LASlavtchev avatar LASlavtchev 1 Точки

JA2 - Task 2 - Word Matching - нулев тест 3 грешен ли е?

Здравейте,

Мисля, че нулев тест 3 е грешен. При 50% - равно трябва да има 3 попадения, а не 2, както е написано. Процентите са от 1 до 100 включително и така ако задам 100% там ще имам 1 попадение. Сега съм с 90 точки в Judge. Ако дам строго по-голяма ме връща на 60 точки.

Има ли проблем или проблема е при мен.

Благодаря предварително.

Тагове:
0
C++ Fundamentals 13/12/2017 23:47:05
georgi.stef.georgiev avatar georgi.stef.georgiev 921 Точки

Здравей,

Верен е примерът, предполагам пропускаш една част от критерия, щом смяташ, че 3-ти от нулевите тестове е грешен: 

two words – W1 and W2 – “similar” if they have the same length, start with the same letter, and a minimum percentage – P – of their letters match 

Казано е start with the same letter. В 3-я нулев тест щеше да има наистина 3 съвпадения, ако го нямаше това условие за еднакъв старт на думите, но с това условие baaa изобщо не се взема под внимание (иначе щеше да е съвпадение, да, и щяха да са 3 съвпадения).

Най-вероятно липсата на тази проверка ти пречи да изкараш пълните точки (но не съм гледал кода и резултатите ти изрично, така че може да има и друго).

Поздрави,

Жоро

0
LASlavtchev avatar LASlavtchev 1 Точки

Мерси, недогледал съм.

0
shamanic avatar shamanic 0 Точки

Ще използвам същата тема, защото въпросът ми е по същата задача.

Никъде в лекциите или в демотата нямаше информация как да разделяме думи от стринг, когато имаме различни препинателни знаци между тях. Дадохте пример с разделител ',' - getline(string, token, ','), но тук в задачката има и точки и запетаи и малко се затруднявам.

Звучи ми логично да мога да кажа:

while(string >> currentWord) {

   if (string.get() == ',' || string.get() == '.') break;

   cout << currentWord;

}

Как да кажа на c++ "Разделяй стринговете от ей този стрийм, слагай ги ей тук, но когато срещнеш този и този символ, прескочи ги" ?

0
17/12/2017 15:00:56
MagdalenaK avatar MagdalenaK 0 Точки

Здравей,

и мен ме интерсува,блъскам си главата,прерових нета,но нещо не успявам.

Поздрави

0
georgi.stef.georgiev avatar georgi.stef.georgiev 921 Точки

Здравейте,

Като цяло няма лесен вграден начин в C++ да се чете до различни разделители - просто стандартната библиотека не дава такава функционалност. Това не е проблем обаче, защото в програмирането, когато ни липсва един инструмент, си го създаваме.

Пробвайте да помислите ако трябва вие да напишете нещо, което прави такова разделение, как бихте го направили? string-ът е просто масив от символи. Да го разделим на думи е същото като да го разделим на "поредици от символи, които спазват определено условие". В едно от първите домашни имаше задача да четете поредица от числа и да изведете най-дългата поредица от еднакви числа. Сега е същото, само че не са числа, а са символи, и проверката ни не е дали са "еднакви" а дали са "различни от разделителите, които искам да ползвам".

Тоест алгоритъмът (функцията) ни ще приема string text, списък с разделители - примерно vector<char> separators - и ще връща (примерно) vector<string> с думите:

- правим си vector<string> words и един ostringstream currentWord в който ще си генерираме текущата дума

- пускаме един for (int i = 0; i < text.size(); i++)

---- ако текущият (i-ят) символ НЕ е разделител (т.е. НЕ можем да го намерим в separators), значи го добавяме към текущата дума: currentWord << text[i];

---- ако текущият (i-ят) символ Е разделител (т.е. го намираме в separators), значи текущата дума е приключила - добавяме я към списъка с думи и я зачистваме за да може да почнем да пълним следващата дума: words.push_back(currentWord.str()); currentWord = ostringstream() //(създаваме си направо нов ostringstream за да сме сигурни че е празен)

- накрая връщаме words от функцията

Вече имаме функция, която по един string връща всички думи в този string, определени от разделителите, които сме подали. Разбира се може да го подобрим този алгоритъм - примерно да му кажем да не връща празни думи (т.е. ако има два разделителя един до друг, между тях на практика се получава празна дума) и т.н. Тази функция можем да я ползваме във всякакви подобни ситуации. Разбира се, това не е единствения алгоритъм за постигане на това, не е дори единствения подход, но е сравнително прост и чист като решение.

 

Сега относно задачата - тази задача не изисква да разделята думите в текста. Може и така, разбира се, но има и друг вариант, които не отделя време за създаване на списък с думи. Този вариант е пак с цикъл да обхождате текста и да гледате дали символите, започващи от позицията, на която се намирате, съвпадат със символите от думата която търсите (по-точно дали определена бройка от тях съвпада, на базата на въведения процент) - ако да, значи сте намерили съвпадение, увеличавате някакъв брояч и продължавате от следващата позиция, ако не - пак продължавате, без да увеличавате брояча.

Отново, има и други решения на тази задача, но това е едно възможно което дори не ползва string функции, освен достъп до символ на определена позиция в string.

Поздрави,

Жоро

1
Jovanna avatar Jovanna 186 Точки

Доста се рових в нета и по метода на проба-грешка, го направих с RegEx, в две части. Защо като "чисти" точки, запетаи и другите, вкарва празни стрингове на тяхно място във вектора: 

    std::string s;
    getline(std::cin, s);   
    std::regex re("([ .,;!?]|[ .,;!?]+)");   
    std::vector<std::string> vectorOfWords;

    std::sregex_token_iterator it(s.begin(), s.end(), re, -1);
    std::sregex_token_iterator reg_end;
    for (; it != reg_end; ++it) {
        vectorOfWords.push_back(it->str());
    }

Кое е най-доброто решение за изчистване на тези празни стрингове, което да работи //какво ли не пробвах и накрая успях с remove_if  и  std::mem_fun_ref(&std::string::empty));  

Но си нямам и представа защо и как го прави.

0
Todir avatar Todir 24 Точки

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

    vector<string> words;
    string text;
    string word;

    getline(cin, text);

    std::replace_if(text.begin(), text.end(), [](char& c){return !isalpha(c);}, ' ');
    istringstream singleWord(text);
    while(singleWord >> word)
    {
        words.push_back(word);

    }

 

1
kolioi avatar kolioi 641 Точки

@ Jovanna

Ако стринга е празен, просто не го добавяй във вектора.

Ето едно решение с strtok() (без кода за една от функциите)

bool match(const string& word1, const string& word2, int percent) {}

int parse(const string& text, const string& word, int percent)
{
	int count = 0;
	string delimiters(".,;!? ");
	char* token = strtok(const_cast<char*>(text.c_str()), delimiters.c_str());
	while (token != NULL)
	{
		if (match(token, word, percent))
			count++;
		token = strtok(NULL, delimiters.c_str());
	}

	return count;
}

int main()
{
	string text;
	getline(cin, text);
	string word;
	int percent;
	cin >> word >> percent;

	cout << parse(text, word, percent) << endl;

	return 0;
}

 

1
sun_seeker avatar sun_seeker 15 Точки

Някакво решение? Че аз стигнах до решение, но не работи ако има в стринга спейсове :) 

0
Jovanna avatar Jovanna 186 Точки

@kolioi, благодаря!

0
19/12/2017 22:33:34
marsp avatar marsp 19 Точки

kolioi

Евала, мерси много за просвещаването! "Match" функцията (или по-точно изчисленията в нея) ги бях измислил, "input"-а и разделението на стринговете ми куцаше (нещо не се обичам аз много със стринговете хаха, сигурно защото и не знаех за съществуването на "strtok" понеже съм noob-че, а може би просто не съм имал късмет да попадна на него докато търсех нещо такова в Stack Overflow & co.). С помощта ти доизкусурих кода.

Имаш бира от мен!
Поздрави!

1
kolioi avatar kolioi 641 Точки

Лесна работа wink

Ето го и кода на липсващата функция

bool match(const string& word1, const string& word2, int percent)
{
	if (word1.length() != word2.length() || word1[0] != word2[0])
		return false;
	
	int count = 0;
	for (size_t i = 0; i < word1.length(); i++)
		if (word1[i] == word2[i])
			count++;

	float percent_match = 100.0f * count / word1.length();

	return percent_match >= percent;
}

Весела Коледа!

0
marsp avatar marsp 19 Точки

Весела Коледа! Ето и моят вариант:

 

bool match(const std::string &word1, const std::string &word2, double &minPercentage)
{
	if (word1.length() != word2.length())
	{
		return false;
	}

	int matchCounter = 0;
	for (unsigned int i = 0; i < word1.length(); i++)
	{
		if (word2[i] == word1[i])
		{
			matchCounter++;
		}
	}

	if (word1.length() == word2.length() && word1[0] == word2[0] && matchCounter >= minPercentage)
	{
		return true;
	}
	else return false;
}

 

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