Loading...
m.nikolov97 avatar m.nikolov97 25 Точки

02. Remove Invalid Companies

Здравейте!

Срещнах няколко проблема с втора задача от домащното:

  1. Имаме list, за чиито елементи се заделя памет динамично. При триенето, след като изтрия с delete въпросния елемент, го махам от листа с remove. Не знам дали това е правилно, но ако използвам само delete, елементът не се махаше от листа и после се омацваше при изписването на компаниите в main-a.
  2. След като го изтрия, както съм посочил в т. 1, нещо се объркваше с итерирането на листа - предполагам, че е, защото в листа всеки елемент носи информация за адреса на предходния и следващия... Това го разреших, като не трия директно щом видя елемент с невалидно айди, а просто събирам итераторите към тези елементи в един вектор и после обикалям вектора и ги трия от листа.

След като направих тези 2 неща (моля някой да ме коригира, ако не ги правя правилно), програмата си ми работеше, но явно е твърде бавна, защото ми дава 50/100 (time limit). Хрумна ми да направя iterator-a static, за да не обикалям всеки път елементите, които вече съм проверил, но и това не ми подобри performance-a. Ще съм много благодарен, ако някой отдели време да ми съдейства! Ето го кода ми: 

#ifndef REMOVE_INVALID_H
#define REMOVE_INVALID_H

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

using namespace std;

void removeInvalid(list <Company*>& allCompanies)
{

	vector <list <Company*>::iterator> allInvalidIds; // store iterators to all elements with invalid IDs

	list <Company*>::iterator it = allCompanies.begin();

	for (it; it != allCompanies.end(); ++it)
	{

		if ((*it)->getId() < 0)
		{
			allInvalidIds.push_back(it);
		}
	}

	for (size_t i = 0; i < allInvalidIds.size(); ++i)
	{

		delete (*allInvalidIds[i]); //deallocate the memory
		allCompanies.remove(*allInvalidIds[i]); //delete the element from the list
	}

}

#endif // !REMOVE_INVALID_H

 

Тагове:
0
C++ Advanced 05/12/2019 13:35:34
Vankata83 avatar Vankata83 72 Точки

Можеш направо да изтриваш елементите от List ето така:

while (it != companies.end()) {
        if ((*it)->getId() < 0) {
            delete *it;
            it = companies.erase(it);
        } else
            it++;
    }

вместо да използваш и вектор.

А ето тук разликата между erase и remove:

https://stackoverflow.com/questions/799314/difference-between-erase-and-remove

0
zzerro avatar zzerro 16 Точки

Аз пробвах какво ли не, за да намеря решение с for-range цикъл(без да ползвам итератор), но не ми даде повече от 50т. Сигурен съм, че може и ще опитвам пак. С итератор трябва да триеш с erase.

Във for не е нужно да попълваш всички полета, даже може нито едно, но задължително трябва да имаш два пъти точка и запетая. for(;;) е същото като while(1).

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