Loading...

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

kostadink2001 avatar kostadink2001 7 Точки

C++ Advanced - 09_04.Tree. getTreeView функцията

Здравейте, 

имплементирах всичко по задачата без getTreeView, реших да я направя с рекурсия, макар и хич да не ме бива много в работата с тях, която да обхожда папките  и да влиза в папка докато не стигне до края на съдържанието й. Рекусията обаче влиза в папките, но след това сякаш не излиза. Линк към кода ми на функцията: https://pastebin.com/Sx7TmKJE

Ще бъда благодарен, ако някой може да каже къде греша и даде насоки как да я напиша правилно. Благодаря предварително!

 

Тагове:
0
C++ Programming
georgi.stef.georgiev avatar georgi.stef.georgiev 921 Точки
Best Answer

Здравей,

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

Като се заглеждам май точно това ти е проблема - ти никъде не връщаш нивото наобратно. т.е. ако имаш:

root

---> nested

--->---> double_nested

---> other

Рекурсията ще влезе в nested и ще увеличи level, след това ще го увеличи за double_nested, и като кода за double_nested приключи, няма да го намали. Много по-лесно ще ти е функцията ти да приема един int параметър, и като я викаш рекурсивно да подаваш стойността на параметъра +1. Така енкапсулираш информацията за нивото вътре в едно изпълнение на фукнцията, а едно изпълнение на функцията ти така описана е точно едно ниво в йерархията (това ти спестява нуждата да връщаш level-а, защото няма глобален level, а всяка функция сама за себе си знае на какво ниво се изпълнява).

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

Поздрави,

Жоро

0
MartinBG avatar MartinBG 4803 Точки

Освен нещата, които ти е казал Жоро, виждам и още един проблем:

std::vector<std::shared_ptr<FileSystemObject>> dirs;

Горното е дефинирано преди тялото на основния цикъл, а вътре само дабавяш елементи към него.

Ако има само една вложена папка, това ще работи (тя ще си сложи нейните елементи вътре и ще извика getTreeView с тях), но ако се случи да има две или повече папки на едно ниво в дървото, те ще извикат getTreeView за всички предишни + техните си елементи.

Златно правило* е променливите да се дефинират там, където се използват, т.е. с възможно най-локален скоуп.

В конкретния пример, това е в тялото на if (dir != nullptr) { ... }. Ако го беше спазил, нямаше да имаш този проблем :)

 

*Друго златно правило е, променливите да се инициализират в момента на декларирането им винаги, когато това е възможно.

В конкретната задача това e не само възможно, но и доста по-лесно и кратко (буквално е един ред) от инициализацията в цикъл, която си направил. Погледни какви конструктори има vector и помисли кой от тях е най-лесен за позване в случая.

 

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

 

Hint: Има и по-хитър вариант с използване на друга структура вместо vector, която ще сортира елементите за нас, но за да го приложиш, ще ти трябва допълнителен метод, който да бъде викан рекурсивно вместо getTreeView, защото последния приема  vector като параметър.

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