Loading...
j.petrov_90 avatar j.petrov_90 373 Точки

Привет, колега,

Изключително съм радостен, че се престрашаваш да пишеш във форума.
Човек, който не се притеснява да признае, че не се сеща за решение - явно го е грижа да го научи.
Все пак, обаче, извини ме но ще потърпиш малко градивна критика.
И не, не съм "хейтър" :)

Въпроса, които си задал е неуместен по ред причини:
1) Домашното е все още в срок, т.е. ако някой сподели "готовото" решение - всички ще го копират без да си размърдат сивото вещество.

2) Казваш, че имаш решение, но не можеш да го разбереш.
Откъде имаш това решение? Някой ти го е дал ли? Явно не си го написал сам, щом някой ти го е дал.
Това би трябвало да те навежда на мисълта, че ще се случи същото това нещо, което съм написал в точка 1, ако сега някой беше "изпляскал" едно решението тук.

3) Въпроси тип - "6та задача на 7мото домашно ми и трудна - помощ" не са препоръчителни. 
Защо? Защото или не си помислил грам по задачата, или си помислил, но по някаква причина не искаш да го споделиш.
Разбери, че подхода към всяка една задача е: да я разбиеш на малки съставни части.
За всяка едно от тези части вече можеш или да потърсиш най-спокойно информация в интернет или да зададеш въпрос тук във форума.
По този начин ще може да ти се помогне в детайли точно за конкретния проблем, за който изпитваш затруднение.

Поздрави

 

1
pesosz avatar pesosz 4 Точки

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

0
27/02/2019 03:46:37
j.petrov_90 avatar j.petrov_90 373 Точки

Привет,

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

Споделих, че не е правилно да се поства цялото решение на задачата докато домашното е още в срок, защото хората ще го copy-paste-нат без да помислят грам.

Без да се заяждам - продължавам да твърдя, че на такъв въпрос няма да получиш смислен отговор.
Защо? Защото не задаваш конкретен въпрос!
Кажи ми: 
- "не разбирам как работи еди си кой конструктор"
- "не разбирам как работи << оператора"
- "не разбирам ред 78 от програмата какво прави" - и копирай тук проблемния ред.
Това са конкретни въпроси, на които мога да ти изпиша за всеки от тях по 50 реда обяснение така, че да ти стане максимално точно.

Когато обаче някой зададе въпрос тип "обяснете ми 5та задача" - кое по напред да ти отговоря по задачата?
В нея има 120 неща. За всяко нещо ли да пиша по 50 реда? Някой според теб ще си отдели ли 2 часа от живота си да пише такова огромно обяснение?
ОК, няма проблем - ще ги отдели и ще го напише. След това ти ще прегледаш какво е написал. Ще прочетеш 116 от тези неща и ще ги пропуснеш, защото вече ги знаеш.
Върху останалите 4 ще се съсредоточиш, защото само тях не знаеш.

Това е едното нещо.
Другото е, че като някой пост-не решението тук - ти го гледаш, съгласяваш се, разбираш го и всичко е 6 точки ... до момента, в който не започнеш да решаваш следващата задача и пак не забиеш на същите тези неща?
Защо ще забиеш на тях? Не защото не си ги разбрал - напротив, а защото докато на човек не му мине нещо през ръцете докато го учи - трудна работа да стане. (да си изцапаш ръцете както се казва)

Като преподавател това е моето мнение:
При така задазен въпроса, ако ти постна решена задачата - ще ти направя "мечешка" услуга.

Завършвам с един известен цитат:
Дай на човек риба и ще го нахраниш за един ден. Научи го да лови риба и ще си го нахранил за цял живот.

Поздрави

1
pesosz avatar pesosz 4 Точки

Добре, ще се постарая за в бъдеще въпросите ми да са по точно конкретни проблеми. Та за същата задача имам няколко неясни неща, като почнем от:
1 - SortingMain (единият от готовите skeleton файлове към задачата), на ред  49 ето линк към скелета:         https://judge.softuni.bg/Contests/Practice/DownloadResource/4019 

	else if (type == 's') {
		Parser<Song> p(std::cin, stopLine);
		Song s;
		typedef std::set<Song, Reverse<Song, LessThan<Song> > > Set;
		Set songs;
		while (p.readNext(s)) {
			songs.insert(s);
		}
		printContainer<Set>(songs.begin(), songs.end());

Не разбирам какво точно правят тези 2 реда: 

        typedef std::set<Song, Reverse<Song, LessThan<Song> > > Set;
        Set songs;

Това което предполагам, че правят е, typedef дава име на std::set<Song, Reverse<Song, LessThan<Song> > , като го кръщава Set и след това, предполагам, че винаги като извикаме Set, ще се извика това дългото обяснение зад него, но не схващам на долния ред какво се случва.. тоест свикнал съм като създадем например вектор и точно след дефиницията vector<int> Име, да кръстим вектора по някакъв начин, а в тази ситуация се получава някакво двойно кръщаване и ме обърква малко. Също така, самото разписване на: <Song, Reverse<Song, LessThan<Song>, не ми е ясно какво точно прави, може би не схващам std::set какво точно прави, но ми е странно написано и не мога да си го преведа(и преди някой да ме изхейти, да гугълнах за std::set, но явно не знам какво точно да потърся) 

2. Следващото което не ми е ясно е във файла Parser.h, а ето и кода:

 

#include <utility>
#include <string>
#include <sstream>

template<class T>
class Parser {
  std::istream& in;
  std::string stopLine;
public:
  Parser(std::istream& in, std::string& stopLine) : in(in), stopLine(std::move(stopLine)) { }

  bool readNext(T& element) {
    std::string line;
    if (std::getline(this->in, line) && line != this->stopLine) {
      std::istringstream is(line);
      is >> element;
      return true;
    }
    return false;
  }
};

и по-точно: Parser(std::istream& in, std::string& stopLine) : in(in), stopLine(std::move(stopLine)) { } ... нямам никаква идея, какво точно прави това (std::move(stopLine)) и защо е използвано в конструктора.
Също така не мога да разбера от къде се вкарват нови елементи, защото по това което чета от Main-а и Parser.h , имаме:

if (std::getline(this->in, line) && line != this->stopLine) ,  до колкото разбирам кода, в проверката чрез getline(this->in, line) проверяваме дали има още string-ове в стрийма, като в същото време записваме стрийма в line, след това като втора проверка, сравняваме текущия string, дали е равен със string-а stopLine след което надолу със стрийм единствено "extract-ваме" line-a в елемент от тип template, който връщаме обратно към main-a, заедно с flag дали да продължи да пълни set-a,  a в main-a единствено взимаме типа информация, който ще обработваме и след това символ за край на реда... Ето част от кода в мейн-а:

int main() {
	char type;
	std::cin >> type;
	std::cin.ignore();
	std::string stopLine;
	std::getline(std::cin, stopLine);

	if (type == 'i') {
		Parser<int> p(std::cin, stopLine);
		int n;
		typedef std::set<int, Reverse<int, LessThan<int> > > Set;
		Set numbers;
		while (p.readNext(n)) {
			numbers.insert(n);
		}..................

 

 

 

Следващото, което не ми е ясно е във файла Comparators.h, ето и кода:

 

#include <string>
#include <iostream>
#include "Song.h"

template<typename T>
struct LessThan {
  const bool operator()(const T& lhs, const T& rhs) const {
    return lhs < rhs;
  };
};

template<typename T, typename Comparator>
struct Reverse {
  const bool operator()(const T& lhs, const T& rhs) const {
    Comparator comparator;
    return !comparator(lhs, rhs);
  }
};

 

Първо, какви са тези скоби(с червеното) и за какво служат:  const bool operator()(const T& lhs, const T& rhs) const {  някакъв вид operator overloading ли е това? Също така не разбирам начина по който се извикват тези функции, защото в мейн-а се извикват със следния синтаксис: <Song, Reverse<Song, LessThan<Song> , а да не говорим за Reverse структурата.. нея изобщо не я разбирам какво прави и за какво се създава елемент от тип template и след това се връща обратното на comparator(lhs, rhs) , това не е ли равносилно с това да напиша return !double(int 5.5,int 10.2) ... Какво трябва да очаквам да ми върне това? 


Другото което не ми беше ясно, но сега, като го помислих по-обстойно мисля че се сетих защо е... във файла Song.h, от скелета, не схващах защо ни трябва да overload-ваме оператора < , но после се сетих, че се използва в Comparator-а.
 

bool operator<(const Song& thiz, const Song& other) {
	return thiz.getLengthSeconds() < other.getLengthSeconds();
}


И последното: PrintUtils.h

 

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

template<typename Template>
void printContainer(typename Template::iterator begin, typename Template::iterator end) {
  while (begin != end) {
    std::cout << *begin << " ";
    ++begin;
  }
  std::cout << std::endl;
}


Това, мисля че го разбирам... от мейн-а ако не се лъжа подаваме printContainer<Set>(songs.begin(), songs.end()); . което мисля че взима от set-a пойнтър сеочещ към началото и пойнтър сочещ към края на set-a... това което не ми е напълно ясно е, защо слагаме четирите точки.. тоест до сега съм го правил механично, но не като цяло не съм го разбирал защо е така.. Според моята теория е, защото самият template class има като поле iterator, защото попринцип когато викаме 4те точки мисля, че достъпвахме фукнция или конструктор, или нещо от даден клас, но това което ми е странно е че го извикваме така: iterator begin, без скоби () , след begin... като цяло просто ми стана интересно как точно е написан итератора за да го използваме по този начин.

П.С. Знам че 90% от въпросите зададени тук са доста глупави и като цяло сме ги преглеждали на лекциите, но мога да гарантирам, че до сега съм гледал всяка лекция по 2 пъти поне и съм опитвал да пиша всички домашни, като повечето ме отказваха до тук, като стигна 5та задача.. някои почти ме отказаха на няколко пъти и на 4та задача... но като цяло усещам че ми се натрупват много малки неща които не са ми ясни и с всяка следваща лекция става все по-голямо незнанието ми.. Надявам се ако някой намери време да отговори на тези мои въпроси, че ще е достатъчно да наваксам нещата които не са ми ясни до тук. Благодаря, предварително!

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