Loading...
supersane avatar supersane 234 Точки

[Data Structures] Exam 13 Sept 2015

Здравейте, тъй като наближава изпита по структури от данни, започнах да се подготвям решавайки изпита, който беше даван на миналата инстанция на курса. Тъй като в този курс най-вече се учим да използваме подходящи структури от данни, за конкретната ситуация, за да имаме максимално добра оптимизация, е изключително важно времето, за което минават тестовете, и затова е изключително важно да няма random лагвания на Judge конкретно за този изпит, но ето какво се случва. Тъй като не съм сигурен дали проблема се проявява от самия Judge или от конкретно моето решение, нека започна малко от по-назад. Първо, задачата не е трудна за реализация, тънкостите се проявяват в 1-3 теста, където има тест на това колко бързо ни работят структурите(ако видите начина на оценяване, ще ви е ясно, че дори и един тест е критично важен за крайния резултат). Та общо взето важния момент, който забелязвам е, че трябва да се използват такива структури, че хем бързо да добавяме игри, хем после, когато ги търсим по prefix да са ни сортирани, за да можем максимално бързо да ги извлечем. Затова в Хеш Речник добавям играта заедно с нейната парола, и в SortedSet пазя имената на регистрираните игри, за да мога после максимално бързо да извлека по даден префикс. Добавяйки обаче в този SortedSet, който се имплементира върху подредено дърво, вече при командата RegisterGame аз имам сложност, която не е константа ами е log(n).  И ETO какво се получава в джъдж, тестовете, които съм задраскал са с променен код, но останалите са с един и същ код, и е факт, че 2 пъти получвам 100 точки, но повече пъти не ги получавам. Та общо взето пиша тук, за да попитам дали използваните стуктури и алгоритъм от мен не е "стабилен", и затова да се получава това разминаване и евентуално ако е нещо свързано със самия джъдж, да бъде нещо като "бъг репорт". Тук оставям и целия си код ако се интересувате от друга част свързана с него.

Тагове:
a_rusenov avatar a_rusenov 1103 Точки

Друг вариант - sortedGames го променяш на OrderedSet и ползваш .Range() с граници с [prefix, prefix + char.MaxValue). Долната граница е ясна - всички по-големи или равни на префикса (т.е. които започват с него). Горната граница гарантира, че няма да вземе геймовете с различен префикс, защото ако един стринг е > prefix + char.MaxValue то някоя буква преди последната е станала по-голяма (следователно не започва с префикса).

Важно е на сета да му се подаде ординал компаратор - new OrderedSet<string>((s1, s2) => String.CompareOrdinal). Така сравняването на стринговете ще става по ASCII кода на символите.

И тук вече имаш сложност O(log n + k), където k е броят елементи в интервала. В средния случай това е по-добре от линейния вариант.

Относно лагванията в Judge, запознати сме с този проблем - затова и този път изпитът ще бъде само с компоненти тестове, без Judge.

4
supersane avatar supersane 234 Точки

А може ли да обясниш, каква е разликата между OrderedSet и SortedSet. Това, което аз знам, е че в OrderedSet, можеш да достъпваш елемнтите с индексатор, и те отново са сортирани. Не ми е ясно обаче това достъпване с чупените скоби каква сложност има, отново ли е log n? И какво е точно предимството на OrderedSet пред SortedSet? Също така, не знаех какво точно прави този ординал компаратор, сега вече знам, но ми се появява въпроса ако не се подаде това в конструктора, по какъв начин ги сравнява? Много ще се радвам ако ми обясниш тези неща, защото наистина ми са доста мъгляви! Също така метода .Range(), каква сложност има? Също в моето решение, в кейса където търся игра по префикс, мисля че само в най-лошия случай сложноста се пада O(n), защото аз така или иначе брейквам foreach-a, когато взема 10 елемента, освен ако те не са в края разбира се. Доста въпроси зададох, но така пък ми се изясняват доста повече неща! Благодаря за оказаната помощ.

0
a_rusenov avatar a_rusenov 1103 Точки

Да, има индексация при OrderedSet<T>, сложността е дълбочината на дървото (т.е. О(log n) при едно балансирано дърво). Другото предимство са Range, RangeFrom и RangeTo методите за изваждане на всички елементи в даден интервал (виж демата от презентацията за Collections and Libraries). Има още няколко бонус метода като IsSupersetOf, Difference, GetFirst (връща най-малкия), GetLast (връща най-големия).

Range() има сложност O(log n + k), k е броят елементи. log n, защото има значение колко е дълбоко дървото. Той работи като пуска един In-Order DFS обаче без да обхожда ненужни поддървета (такива каквито не може да са в интервала).

Твоят вариант прави линейно търсене. В конкретния случай имаш ограничение до 10 елемента, затова и не е толкова бавно. Но пък представи си, ако често правиш префиксно търсене по Z на 1 000 000 елемента (измежду които няма такава дума) по твоя начин. :) В същия случай Range() ще направи едно log n спускане и ще установи, че няма такива елементи.

2
11/03/2016 16:45:42
Filkolev avatar Filkolev 4482 Точки

SortedSet няма метод Range(). Относно сложността не мога да цитирам конкретно, но е много бързо, то е просто отрязване на поддърво, което предполагам е логаритмична сложност или близка (търсене на границите в балансираното дърво).

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

0
11/03/2016 16:50:04
supersane avatar supersane 234 Точки

@a_rusenov, супер мерси много за обяснението, доста ми се изясниха нещата, само не разбрах каква е разликата ако в конструктора има ((s1, s2) => String.CompareOrdinal), имам предвид, да, с това ще сравнява по АSCII кода, а без него как го прави сравняването?

0
RoYaL avatar RoYaL Trainer 6849 Точки

Ами да да сравни тежестите на два елемнта, ще използва CompareTo(). До колкото съм наясно обаче без други опции овърлоудът на този метод за обект от тип стринг е culture specific.

0
supersane avatar supersane 234 Точки

Тогава, каква е причината да се подава в конструктура, за оптимизация или за да се подсигурим, че ако нещо не е наред с culture на машината, това сравнение няма да гръмне?

0
RoYaL avatar RoYaL Trainer 6849 Точки

Културата на машината може да е всякаква, да. Виж в документацията на String.CompareTo (s1, s2) има разни примери

0
a_rusenov avatar a_rusenov 1103 Точки

@Filkolev, е ти изби рибата. Как така range query с константна сложност в дърво?

2
Filkolev avatar Filkolev 4482 Точки

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

0
RoYaL avatar RoYaL Trainer 6849 Точки

Фил, извикването на Range() е lazy и затова връщането на View отнема константно време. Тъй като се извиква функцията DoubleRoundedRangeTester на червео-черното дърво. Тя връща делегат, а не оценява реално. Подава се после на коструктора на View, който дава тестера на GetEnumerator(). Когато обаче поискаш елемент от този Range, View-то ще се енумерира и тогава ще обходи дървото по регистрирания енумератор (пак от линка горе - EnumerateRangeInOrder)

2
RoYaL avatar RoYaL Trainer 6849 Точки

Мисля, че структурата е OrderedSet и е част от Wintellect.PowerCollections

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