Loading...

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

TsenoBorislavovTsenov avatar TsenoBorislavovTsenov 0 Точки

Task 2 - Find - Грешка при компилиране в Judge

Здравейте!

Може ли някой да ме светне защо Judge не иска да компилира кода по долу

#include "Company.h"
#include <vector>
#include <algorithm>

inline Company* find(const std::vector<Company*> company, const int &id)
{
	auto c = *std::find_if(company.begin(), company.end(), [id](Company* comp) { return comp->getId() == id;});
	return c;
}

Компилира и работи успешно под Win10 64bit на VS17

Тагове:
0
C++ Advanced
MartinBG avatar MartinBG 4803 Точки

Малко уточнение към коментар №5 на колегата j.petrov_90:

find_if ще върне iterator, който след дерефернцирането си (при намерен елемент) ще ни даде елемента, към който сочи, който е от тип Company* , а не Company.

 

Както е казал колегата kolioi, ще има проблем, ако в контейнера няма нито един елемент, който да изпълни условието - в Judge със сигурност има тест, който проверява този сценарий. Може и направо да тестваш с празен вектор:

end
1

 

 

2
24/01/2019 14:10:22
TsenoBorislavovTsenov avatar TsenoBorislavovTsenov 0 Точки

Успях да си реша проблема по следния начин:

#ifndef FIND_H
#define FIND_H

#include "Company.h"
#include <vector>
#include <algorithm>

inline Company* find(const std::vector<Company*> &company, const int &id)
{
	if (!company.empty())
	{
		std::vector<Company*>::const_iterator it = std::find_if(company.begin(), company.end(), [&](const Company* comp) -> bool { return comp->getId() == id;});
		if (it != company.end())
		{
			return *it;
		}
		return nullptr;
	}
	return nullptr;
}

#endif 

Благодаря на @MartinBG и @kolioi за тип-чето относно проверката дали е празен контейнера и дали съществува такова ид smiley

0
24/01/2019 17:37:35
kolioi avatar kolioi 641 Точки

Не е необходимо да проверяваш дали вектора е празен. Този код също ще работи (не съм го тествал в Джадж):

auto it = std::find_if(companies.begin(), companies.end(),
	[id](Company* c) {return c->getId() == id; });
if (it != companies.end())
	return *it;

return nullptr;

 

2
TsenoBorislavovTsenov avatar TsenoBorislavovTsenov 0 Точки

Прави сте, кодът ще работи, но мисълта ми зад тази проверка беше ако е празен вектор хич да не правя гимнастики да създавам итератори, да викам find_if или да проверявам дали

if (it != company.end()) 

, и тн, а просто да върна nullptr. Просто ако е празен пропускам целия този цирк: 

std::vector<Company*>::const_iterator it = std::find_if(company.begin(), company.end(), [&](const Company* comp) -> bool { return comp->getId() == id;});
		if (it != company.end())
		{
			return *it;
		}
		return nullptr;

empty() е O(1).

Просто ми изглежда по оптимизирано, поправете ме ако греша.

0
26/01/2019 18:32:52
MartinBG avatar MartinBG 4803 Точки

В случая нама значение, освен ако не се очаква тази функция да бъде викана много често (хиляди пъти) с празен вектор, но дори и тогава е малко вероятно да има разлика в скоростта (най-вероятно едно от първите неща, които find_if прави, е да върне .end() при празен контейнер).

 

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

0
26/01/2019 19:46:44
kolioi avatar kolioi 641 Точки

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

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