Loading...
nikolaykk avatar nikolaykk 94 Точки

Homework: Primitive Data Types and Variables-Bits Inverter

Здравейте,

Ето моето решение на задачата. Ще се радвам да видя други такива,а също и коментари как да се опрости малко.

http://pastebin.com/1RAkA91Z

ModEdit: Моля прочети правилата на форума преди да пускаш новите теми - по-конкретно т.12

Тагове:
0
Programming Basics 28/05/2015 00:45:43
TonislavAtanasov avatar TonislavAtanasov 86 Точки

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

Хинт: Масиви не ти трябват.

Хинт 2: Можеш да се справиш само с два вложени for цикъла, с единия обхождаш въвежданите числа, а с вътрешния обхождаш всяко число и flip-ваш бита на съответната позиция. Прегледай пак битовите оператори, в лекцията се обяснява как да го направиш. Трябва да запомняш някъде къде се намираш в момента, за да знаеш дали си на правилната позиция глобално.

И понеже днес съм много отзивчив, Хинт 3: Обхождай числата от ляво на дясно.

Много хинтове станаха. Хайде успех :)

1
16/06/2015 12:26:49
nikolaykk avatar nikolaykk 94 Точки

Здравей колега,

Благодаря за препоръките- ще си взема бележка.

Не знам дали ти е направила впечатление датата на поста, но тогава все още не бяхме взели битовите операции, а и не бях стигнал до тях в книгата на Наков. След едноседмична борба се чувствам доста по конфортно при работата с битови операции и нямампроблем с решаването на задачите.Относно другите ти забележки - предполагам, че с времето ще се изчистят. Все пак учим от 1 месец, а  и мозакът ми не е ползван на 100% от университета, а това беше доста отдавна:)

Поздрави. 

0
KatyaMarincheva avatar KatyaMarincheva 572 Точки

Здравей Николай,

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

Първо, всеки който започва да пише код, минава през overkill етап - когато не знаем, че езика си има вградена функционалност да върши нещо, и минаваме през много, много код и проверки за да свършим пак същото.

Конкретно, първото нещо което може да се замени с вградена функционалност е добавянето на нулички отляво на бинарния стринг, ето този ред сам си проверява дали имаш общо 8 bits, и сако ако не са 8, си добавя нуличките точно отляво:

binNumber += Convert.ToString(int.Parse(Console.ReadLine()), 2).PadLeft(8, '0');

Всичко получено от ConsoleReadLine() като следващо число, си отива направо в binNumber и не ни трябва масив от n input-numbers. Иначе, докато си работиш със стрингове, идеята за ToCharArray() е един много добър вариант, защото стрингът сам по себе си също е char array, но е immutable, не можеш да правиш промени в него. И със StringBuilder може, за разнообразие, но не би било оптимизация в дадения случай.

Та това е първи вариант от преработката на твоето решение: http://pastebin.com/JjaihSNg

Само колкото до варианти, последният етап на вземане на точно 8 бита от binNumber, може и с комбинация от Skip(x).Take(8), но като пърформанс ползването на LINQ методи често бави много, и твоят вариант си остава несравнимо по-добър. http://pastebin.com/0c1xZyGP.

Сега стигаме до първата важна промяна, която е необходима - избягването на колекции. Ако имаш цикъл, в който получаваш едно по едно n числа, първото нещо което хрумва на всеки е да ги складира някъде и после да си ги обработва - но няма смисъл. Най-важното, което научих откакто се преместих да уча в СофтУни е да си обработвам инпута в момента на получаване: чета едно число, обработвам го, печатам output за това число, и чак след това чета следващото число. Judge няма нищо против да получава output-a на части, освен ако в задачата не пише изрично да не печаташ преди да ти се подаде команда "END" - тук нямаме такъв случай.

Другият особен момент е, че на нас ни трябва индекс, който се отнася за цялата поредица от числа, а не за конкретното число, за да си изчислим къде попада (1 + step * x). Същото ни трябва в най-различни варанти в много изпитни задачи - начинът е: int index = 0, index++ (докато с for loop обикаляме цялото число), if (index % step == 1) -> правим bit invert. така индексът ще има точно толкова позиции, колкото бита има в цялата поредица от числа, а ако index % step == 1, това значи че се намираме на позиция (1 + step * x).

Тази тактика сама няма да даде 100 точки в judge, защото ако step =1, ние трябва да инвъртваме битовете на всяка позиция без изключние, а index % 1 = 0 за всеки индекс. Затова добавяме второ условие: if ((step == 1) || (index % step == 1)) -> ще правим инвъртване.

Ето още един трети вариант от преработката на твоето решение: всяко число се обработва в момента на получаване: http://pastebin.com/VMxmim3U. Като в този случай използването на StringBuilder наистина спестява време при връщането към стринг накрая.

Иначе колегата Тонислав наистина е прав специално за използването на побитови операции: в тази задача броенето на позициите точно пасва на индексирането на стринг, много е удобно да се направи със стринг, в част от побитовите задачи дори е даден втори вариант на авторското решение - със стринг, не с побитови операции. Проблемът е, че при повечето задачи точно индексирането става ад, ако решиш да работиш със стринг - индексирането на стринг и битове е противоположно, и започваш да се чудиш сега кое беше на нулева, кое на крайна позиция, кое е от ляво, кое от дясно - по тази причина е добър навик всяка побитова задача да се решава И побитово.

В този смисъл от последния вариант, от прерабтката на твоето решение, до побитовото авторско решение, остават само 2 стъпки: вътрешният цикъл този път да е от 7 до >= 0, и инвъртването да се прави побитово: авторско решение.

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

 

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