Loading...
VictoriaTsvetanova avatar VictoriaTsvetanova 20 Точки

Техники за писане на алгоритми?

Здравейте, драги съфорумници!

Пиша ви относно един проблем, който ме притеснява от скоро време. Когато сядам да пиша код ми отнема доста време докато измисля алгоритъма. Материала си го разбирам, но ми отнема доста време, за да реша една задача (някой път - няколко минути, друг път - 1 час, друг път - 3-4 часа). Начина, по който решавам задачите е следния: чета условието и след това веднага тръгвам да пиша код. Алгоритъма го измислям едновременно докато пиша кода и  в редки случаи изполвам тетрадка, за да си представя задачата. Често пъти ми се случва докато пиша кода, изведнъж се сещам за нещо друго, което е трябвало да го включа, но не съм се сетила в началото и после ми се налага да трия половината код (че понякога и целия). И така въпросът ми е: Нужно ли е да подходя към друг метод, за да мога да пиша код по-бързо или трябва да променя нещо в метода си и какво точно трябва да промена?

 

И още един въпрос - Как най-добре да решаваме задачи с по-тежки алгоритми? Когато имаме такива задачи, необходимо ли е ООП?

Тагове:
6
Programming Basics 16/03/2016 22:42:00
NMishev avatar NMishev 2 Точки

Полезно ^ 

0
TanyaZheleva avatar TanyaZheleva 354 Точки

Използвай тетрадката по-често :D Наистина помага...особено ако се колебаеш между няколко варианта за решение. Винаги си нахвърляй идеите. Фигурките например винаги описвам на лист (зависимостите) и чак накрая ги вивеждам като код.

Отделяй повече време за самото условие на задачата. Не започвай веднага да измисляш решението...често има скрити уловки. :)

 

2
gvanastasov avatar gvanastasov 52 Точки

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

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

Тетрадката - еми, пак същото - на някой може да им помогне страшно много, на други да не им трябва въобще.

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

Успех

4
RoYaL avatar RoYaL Trainer 6849 Точки

Има едно максима за програмирането, и тя е, че в последното най-лесното в процеса е писането на код.

Това важи за задачи 1+1, за задачи с много по-сложни алгоритми, за архитектури (ООП) и прочие. Обектите сами по себе си не помагат за решаването алгоритмични проблеми. Но в по-комплексния свят на алгоритмите формират структури от данни, които биха ни помогнали за това.

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

Любимият ми пример, когато говорим за алгоритми, винаги е бил намирането на най-голямото число в ненаредена поредца от числа. Много хора подхождат несериозно към този проблем, когато кажа, че той се решава еднакво от човек и от компютър. Обикновено казват, че в поредица от числа написана на лист хартия, те просто виждат най-голямото число.

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

Когато обемите започнат да се увеличават, все повече започваме да приличаме на компютъра в отношение на базовия алгоритъм. Ако получиш лист А4 пълен с числа, след него още един лист А4 пълен с числа и после още един и така 10 листа и трябва да кажеш кое е най-голямото число, най-лесно се вижда, че това което правиш е да помниш избирателно* числа, които ти се струват големи измежду малко подредици и да ги считаш за най-големите, после да помниш друг числа и да ги сравняваш с предходните числа.

* Тук просто за вметка ще обърна внимание на избирателното гледане на числата и това, че мозъкът ни игнорира на практика числата, които не може да са кандидати за най-голямо число. Т.е. ако сме видали 1467, едноцифрените числа въобще не си правим труда да ги обработим, като види 1332 се замисляме малко, но бързо се сещаме че имаше 1467 и го подминаваме. Такова търсене има и в програмирането и се базира на т.нар структури - дървета, но те не са обект на текущия ни алгоритъм.

Ако загърбим това и опростим това, което правим без страничните (евристични) фактори, то се оказва, че ние подхождаме по следния начин: вглеждаме се в първото число, считаме го за максимално, после се вглеждаме във всяко следващо и ако се окаже по-голямо от максималното, го считаме него за максимално и повтаряме проверката за следващите числа докато стигнем до последното, или иначе казано:

Нека най-голямото число е първото в редицата
Докато има числа в редицата:
    За всяко число в редицата:
        Ако числото е по-голямо от най-голямото:
           То числото става най-голямото
            

Когато сме успели да стигнем до това заключение, вече най-лесната част е да обърнем горните 5 реда в код на който и да е език. Може да си направите експерименти да реализиране алгоритъма на произволен език, който сте видяли в wikipedia.

Как изглеждат горните 5 реда в смисъла на програмирането, ако да речем числата са 200 и получаваме всяко на нов ред:

1. Нека MAX = (четене на първото число от стандартния вход)
2. От 1 до 199 изпълни:
2.1. Нека CURRENT = (четене на число от стандартния вход)
2.2. Провери дали CURRENT > MAX
2.2.1. Ако да, Нека CURRENT = MAX
3. Изпиши на стандартния изход MAX

Ако имаме базисни познания по програмиране ще знаем, че повечето езици имат променливи, цикли и условни конструкции. Това не важи за всички езици, но важи за повечето. За тези, които нямат такива конструкции, вече се е намерил някой, който де пита какъв е еквивалентът им, така че търсейки в гугъл за това ще попаднете на неговия въпрос и респективно ще намерите отговора.

Точка 1. от горният алгоритъм е създаването на променлива MAX. Точка 2 е цикъл от 1 до 199. Точка 2.1. е създаването на променлива CURRENT, точка 2.2 е IF /условна конструкция). Точка 2.2.1 е съдържанието между къдравите скоби на условната конструкция.

Ако приемем, че не знаем как да постигнем това на C#, нека си експериментираме и зададем съответните въпроси в гугъл

1. How to declare integer variable in C#

Variables and Constants - MSDN - Microsoft

https://msdn.microsoft.com/en-us/library/wew5ytx4(v=vs.90).aspx

A variable is one type of field. The following code is a simple example of how to declare an integer variable, assign it a value, and then assign it a new value. C#.

int max = 1;

2. How to read integer from Console C#

c# - Reading an integer from user input - Stack Overflow

stackoverflow.com/questions/.../reading-an-integer-from-user-input

Jun 27, 2014 - Console.WriteLine("1. Add account."); Console.WriteLine("Enter choice:

* Променяме горния int max = 1 на наученото от линка:

int max = Convert.ToInt32(Console.ReadLine());

3. C# repeat statement

(е, тук не излезе for, но ще се направим на разсеяни и ще използваме каквото излезе)

do (C# Reference) - MSDN - Microsoft

https://msdn.microsoft.com/en-us/library/370s1zax.aspx

The do statement executes a statement or a block of statements repeatedly until a specified expression evaluates to false. The body of the loop must be ...

(модифициаме кода от 5 на 199, тъй като това е нашият "бизнес сценарий"):

int x = 0;
do
{
    Console.WriteLine(x);
    x++;
} while (x < 199);

3.1. Вместо да печатаме "x" ние вече знаем от точка 2 как да четем число от конзолата и искаме точно тази операция да повторм 199 пъти, така че сменяме горното каре на

int x = 0;
do
{
    int current = Convert.ToInt32(Console.ReadLine());
    x++;
} while (x < 199);

4. Compare variables C#

Equality Comparisons (C# Programming Guide) - MSDN

https://msdn.microsoft.com/en-us/library/dd183752.aspx

It is sometimes necessary to compare two values for equality. ... as equivalence, which means that the values that are contained by the two variables are equal.

if (current > max)
{
    max = current;
}

 

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

            int max = Convert.ToInt32(Console.ReadLine());
            int x = 0;
            do
            {
                int current = Convert.ToInt32(Console.ReadLine());
                if (current > max)
                {
                    max = current;
                }
                x++;
            } while (x < 199);

            Console.WriteLine(max);

 

Е, разбира се можеше да се постигне с for цикъл и int.Parse, но тук симулирахме среда, в която приехме, че дори не разбираме от C# и просто това ни попадна като отговор и го приехме за чиста монета.

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

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

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

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

Разбира се, за да е готов човек да участва в тези фази, трябва да има солидна подготовка с писането на код. Т.е. да му е минал толкова код през ръцете, че вече да пише машинално и да не прави като експеримента ни по-горе - да гугълва за синтаксис. Докато човек е начинаещ пред него стоят предизвикателствата да се научи да мисли, да научи от какъв инструментариум може да се възползва (т.е. теоретичната му подготовка - вместо да пише в гугъл "как да повторя действие в C#" да напише "как да напиша цикъл в C#", защото знае че има цикли) и да научи синтаксиса. Като съм ги подредил по важност - от най-важното до най-маловажното.

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

Поздрави,

Иван

30
gvanastasov avatar gvanastasov 52 Точки

евала за готиния отговор, немога да натисна стрелкичката за нагоре 2 пъти :)

1
alex1966 avatar alex1966 255 Точки

Ехаа, затова е в топ 40 на българите в stackoverflow..

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