AKB Forums

Go Back   AKB Forums > Technical sections > Algorithms
Home Register Blogs FAQ Members List Calendar Downloads Arcade Mark Forums Read

Algorithms The source of algorithms for your project

Troubles when posting message? Click here! :: Проблемы с отправлением сообщения? Нажмите сюда!

Reply
 
LinkBack Thread Tools Display Modes
Old Nov 25, 2005, 03:59   #1
(vagabond)
 
Gypsy's Avatar
 
Join Date: Dec 2004
Location: Himalayas
Posts: 823
Rep Power: 4
Reputation: 10
Минимальные, оптимальные, красивые решения простых задач :)

Навеяно соседним топиком "Шедевры". Но здесь пишем только свои задачи и решения

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

Начну я сам. В тот день, после поста про незакрытые скобки, я задумался как можно оптимально (быстро и/или с минимальным кодом)
реализовать функцию проверки балланса различных скобок (фигурных, круглых, и т.п.) в заданной строке текста.

У кого какие предложения? У меня есть одно довольно короткое и быстрое решение, выложу потом после ваших версий.

Last edited by Gypsy : Nov 25, 2005 at 04:54.
Gypsy is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 05:09   #2
Грустно...
 
Agregat's Avatar
 
Join Date: Aug 2002
Location: Там, где всегда идут дожди
Posts: 21,343
Rep Power: 10
Reputation: 109
Send a message via ICQ to Agregat Send a message via MSN to Agregat
проходим по строке и кладем в стэк открывающую скобку, когда встречаем закрывающаю берем элемент со стэка, если его нет или он не соответствует закрывающей - то баланс нарушен.
__________________
Хотели, как лучше, а получилось даже хуже...
Лозунг шахматиста: На каждый шах - ответим матом!
В сумасшедшем доме каждый мог говорить все, что взбредет ему в голову, словно в парламенте.
Я. Гашек. "Приключения Бравого Солдата Швейка". Часть 1. Глава IV. Абзац 2.
Agregat is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 05:37   #3
(vagabond)
 
Gypsy's Avatar
 
Join Date: Dec 2004
Location: Himalayas
Posts: 823
Rep Power: 4
Reputation: 10
Ну да. А без стека?

Задача в том чтобы реализовать функцию в минимальном количестве строк кода и в минимальной памяти. Можно ставить ограничения на строку (скажем определить максимальную глубину скобок).

Хотя конечно задача не супер. Если есть более интересные задачи, милости просим...
Gypsy is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 07:26   #4
the mochinger
 
Hans Andersen's Avatar
 
Join Date: Feb 2002
Location: Paranoid Android, @10:50
Posts: 1,705
Rep Power: 7
Reputation: 71
Send a message via ICQ to Hans Andersen Send a message via MSN to Hans Andersen Send a message via Yahoo to Hans Andersen
stek eto chereschur,
int cntopenbraces;
++ delaem pri '('
-- pri ')'
isli kogda nit' cnt < 0, to imba, more )
v konze,
esli cnt == 0 ok
otherwise imba, more '('
__________________
The flower that blooms in adversity is the most rare and beautiful of all.
Hans Andersen is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 11:00   #5
Грустно...
 
Agregat's Avatar
 
Join Date: Aug 2002
Location: Там, где всегда идут дожди
Posts: 21,343
Rep Power: 10
Reputation: 109
Send a message via ICQ to Agregat Send a message via MSN to Agregat
Ганс, читаем внимательнее вместе:
реализовать функцию проверки балланса различных скобок (фигурных, круглых, и т.п.) в заданной строке текста
Если скобка одного типа тогда да - как ты сказал - это элементарно. Я дико обрадуюсь если вы найдете решение лучше моего, которое проверит баланс скобок разных типов.
__________________
Хотели, как лучше, а получилось даже хуже...
Лозунг шахматиста: На каждый шах - ответим матом!
В сумасшедшем доме каждый мог говорить все, что взбредет ему в голову, словно в парламенте.
Я. Гашек. "Приключения Бравого Солдата Швейка". Часть 1. Глава IV. Абзац 2.
Agregat is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 11:17   #6
the mochinger
 
Hans Andersen's Avatar
 
Join Date: Feb 2002
Location: Paranoid Android, @10:50
Posts: 1,705
Rep Power: 7
Reputation: 71
Send a message via ICQ to Hans Andersen Send a message via MSN to Hans Andersen Send a message via Yahoo to Hans Andersen
oh, my bad i am fusking asleep
__________________
The flower that blooms in adversity is the most rare and beautiful of all.
Hans Andersen is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 19:08   #7
Banned
 
Forever Child's Avatar
 
Join Date: Oct 2001
Location: ...осень колибри
Posts: 7,493
Rep Power: 0
Reputation: 10
Send a message via ICQ to Forever Child Send a message via AIM to Forever Child Send a message via Yahoo to Forever Child
А последовательность учитыается? В смысле, ты считаешь последовательность ошибочной?
Code:
abcd(efg{hijk)lmnop}
А эту считаешь верной?
Code:
abcd(efg{hijk}lmnop)
Или без разницы?
Forever Child is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 19:41   #8
Какое небо, бля, Багдад!
 
knightmare's Avatar
 
Join Date: Oct 2005
Location: Ереван
Posts: 1,646
Rep Power: 3
Reputation: 68
По-моему, тут всё упирается в стек LIFO (c)Agregat
Можно и по-другому, но будет далеко не красиво и, в принципе, тот же LIFO + рудименты.
хотя надо подумать...
__________________
мордой об лавку
LISP is the only language that is truly beautiful.
d
.

Хочу трахнуть Nissan Skyline R34, и ездить на Alessandra Ambrosio
knightmare is offline   Reply With Quote Quote selected
Old Nov 25, 2005, 20:09   #9
Какое небо, бля, Багдад!
 
knightmare's Avatar
 
Join Date: Oct 2005
Location: Ереван
Posts: 1,646
Rep Power: 3
Reputation: 68
Вот еще одна простая задача: случайным образом преремешать символы в строке (доступна только radn()).
__________________
мордой об лавку
LISP is the only language that is truly beautiful.
d
.

Хочу трахнуть Nissan Skyline R34, и ездить на Alessandra Ambrosio
knightmare is offline   Reply With Quote Quote selected
Old Nov 26, 2005, 09:01   #10
ЙЦУКЕН
 
Join Date: Jul 2002
Location: 0x68,0x69,0x72, 0x69,0x6e,0x67, 0x20,0x6e,0x6f, 0x77
Posts: 3,111
Rep Power: 6
Reputation: 10
Send a message via ICQ to nm
насчет скобок:
есть быстрое решение, которое предложил агрегат - но оно требует в максимуме столько же память, сколько занимает проверяемая строка (ерсли учитывать, что скобок у нас всего 4 разных типов -- то их можно паковать в 2 бита , что в 4 раза уменьшит используюмую память)

вполне возможно, что есть решение дле фиксированного размера памяти - хранить указатель только на открывающую скобку, и при нахождении парной данной скобки делать скан по строке обратно от сохраненной позиции. но его нужно обдумать, чтоб корректно обрабатывать вложенные скобки -- правда придется платить призводительностью за фиксированный размер памяти.
nm is offline   Reply With Quote Quote selected
Old Nov 26, 2005, 09:38   #11
Грустно...
 
Agregat's Avatar
 
Join Date: Aug 2002
Location: Там, где всегда идут дожди
Posts: 21,343
Rep Power: 10
Reputation: 109
Send a message via ICQ to Agregat Send a message via MSN to Agregat
можно красиво спрятать стэк - заменив его на рекурсию.
__________________
Хотели, как лучше, а получилось даже хуже...
Лозунг шахматиста: На каждый шах - ответим матом!
В сумасшедшем доме каждый мог говорить все, что взбредет ему в голову, словно в парламенте.
Я. Гашек. "Приключения Бравого Солдата Швейка". Часть 1. Глава IV. Абзац 2.
Agregat is offline   Reply With Quote Quote selected
Old Nov 27, 2005, 10:22   #12
Дикообраз-безобраз
 
AvDav's Avatar
 
Join Date: Jul 2004
Location: У самого синего моря
Posts: 2,509
Rep Power: 4
Reputation: 44
Send a message via ICQ to AvDav
красивое compile-time решение перемешивания
Code:
template <int iter, typename T> struct Random {
	static void Shuffle(T* ptr) {
			size_t i=iter-1, j=i*rand()/(RAND_MAX+1);
			ptr[i]^=ptr[j]^=ptr[i]^=ptr[j];
			Random<iter-1, T>::Shuffle(ptr);
	}
};
template <typename T> struct Random<1, T>{static void Shuffle(T*) {}};
.
.
char s[]="abcdefg";
Random<7, char>::Shuffle(&s[0]);
__________________
Forza Alb-Violeţii.

Last edited by AvDav : Nov 27, 2005 at 11:19.
AvDav is offline   Reply With Quote Quote selected
Old Dec 1, 2005, 22:12   #13
Какое небо, бля, Багдад!
 
knightmare's Avatar
 
Join Date: Oct 2005
Location: Ереван
Posts: 1,646
Rep Power: 3
Reputation: 68
Re: Минимальные, оптимальные, красивые решения простых задач :)

ООП и скорость компиляции/выполнения по-моему имеют мало общего...
__________________
мордой об лавку
LISP is the only language that is truly beautiful.
d
.

Хочу трахнуть Nissan Skyline R34, и ездить на Alessandra Ambrosio
knightmare is offline   Reply With Quote Quote selected
Old Dec 2, 2005, 08:16   #14
(vagabond)
 
Gypsy's Avatar
 
Join Date: Dec 2004
Location: Himalayas
Posts: 823
Rep Power: 4
Reputation: 10
Re: Минимальные, оптимальные, красивые решения простых задач :)

Quote:
Originally Posted by Gypsy
Можно ставить ограничения на строку (скажем определить максимальную глубину скобок).
Quote:
Originally Posted by Agregat
можно красиво спрятать стэк
Короче у меня такое решение. Тоже разновидность идеи стека, но используется всего (N+5) int-ов, где N - количество видов скобок. То есть используемая память не зависит от длины строки.

Если считать количество видов скобок постоянной величиной, то решение линейное. Всего один проход по строке, и для каждого символа N тестов плюс немного арифметики.

Есть ограничения:
- максимальная глубина (вложенность) < 16.
- максимальная глубина отдельно взятого типа скобок <= 8

Создаем массив из N int-ov, изначально все нулевые.
Сканируем строку слева направо.

- При каждой открытой скобке вносим текущий уровень глубины в соответсвующий элемент массива (с помощью побитового сдвига). Увеличиваем уровень глубины.

Скажем встретили '(' на нулевой глубине, в первом элементе пишем 1, потом встретили '{', во втором элементе пишем 2, потом опять '(', в первом элементе уже получается (1 3).

- При каждой закрытой скобке, проверяем какое число было внесено последним в элемент соответствующий текущему типу скобок. Если там текущий уровень глубины, то все в порядке (закрылась та же скобка что открывалась последней), а если нет, значит получили дисбаланс.

Код я постарался сделать как можно короче, просто ради интереса

Допустим даны следующие определения.
Типов скобок может быть сколько угодно (но >1), алгоритм от этого не пострадает. В принципе это и есть основное преимущество данного решения.

Code:
char pOC[] = "{([})]";
#define NUM_BRACKETS (sizeof(pOC)>>1)
Функция проверки баланса:
Code:
int CheckBalance(char* p)
{
	int i, c, b = 1, m = 0, n[NUM_BRACKETS], s = NUM_BRACKETS;
	while (i=0, (c=*p++) && b)
	    while ((pOC[i]==c) && ((n[i]<<=4)|=++m),
	           (pOC[s+i]==c) && (b=((n[i]&0xF)==m--), n[i]>>=4), ++i-s);

	return b && (m==0);
}
Такие дела. Я думаю можно найти и более интересные решения...

Last edited by Gypsy : Dec 2, 2005 at 08:54.
Gypsy is offline   Reply With Quote Quote selected
Old Dec 2, 2005, 08:42   #15
(vagabond)
 
Gypsy's Avatar
 
Join Date: Dec 2004
Location: Himalayas
Posts: 823
Rep Power: 4
Reputation: 10
Re: Минимальные, оптимальные, красивые решения простых задач :)

Quote:
Originally Posted by knightmare
Вот еще одна простая задача: случайным образом преремешать символы в строке.
Можно просто пройтись по строке делая случайные swap-ы (как уже предлагалось). Пусть будет не compile-time если не хочешь, эффект тот же

Просто тут дело в том, что зная random seed перед генерацией случайной строки, можно ее собрать обратно (применив те же swap-ы в обратном порядке).

Если ты хочешь чтоб перемешивание было односторонней функцией, тут одним только rand-ом вряд ли обойдешься.
Gypsy is offline   Reply With Quote Quote selected
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 21:34.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
This board was founded on September 29, 2001
Powered by Viper Internet

Affordable Web Hosting | ParevNet

Buy text link