Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 21.01.2013, 14:19
Профессор
Отправить личное сообщение для Dmitriyff Посмотреть профиль Найти все сообщения от Dmitriyff
 
Регистрация: 22.07.2012
Сообщений: 164

короче кури тему про графы и обход бинарных деревьев.
Ответить с цитированием
  #12 (permalink)  
Старый 21.01.2013, 14:33
Аватар для megaupload
Профессор
Отправить личное сообщение для megaupload Посмотреть профиль Найти все сообщения от megaupload
 
Регистрация: 18.01.2013
Сообщений: 1,098

Спасибо конечно, но мне кажется это тут не при чем, и я просто создам стек с переменными;
Ответить с цитированием
  #13 (permalink)  
Старый 21.01.2013, 14:55
Профессор
Отправить личное сообщение для Dmitriyff Посмотреть профиль Найти все сообщения от Dmitriyff
 
Регистрация: 22.07.2012
Сообщений: 164

dom - это по сути бинарное дерево, код который я привел из разделов связанных с обходом бинарных деревьев. так что оно тут как раз при чем =-)

Сообщение от megaupload
и я просто создам стек с переменными;
эм... не уловил к чему это, собствено пример который я привел как раз со стеком =-)
Ответить с цитированием
  #14 (permalink)  
Старый 21.01.2013, 14:59
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Сообщение от ksa Посмотреть сообщение
Рекурсия (правильная не как у тебя в первом случае ) циклом не опишется. Она для того и делается.
Потому как не известно не только число итераций, но и уровень вложения.

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

Мы создаём стек ручками, как массив и на каждый уровень вложенности пушим туда объект с текущем состоянием переменных, затем локальные переменные переопределяем и продолжаем алгоритм до тех пор пока рекурсия не закончится и тогда мы начинаем "всплытие", т.е. итеративно разворачиваем полученный массив и делаем на каждой итерации pop (т.е. срезаем крайне правый элемент).

Как пример сложной рекурсии развёрнутой в цикл могу привести свою реализацию метода extend (как в jQuery, т.е. глубокое копирования произвольного количества аргументов произвольной глубины и структуры)

https://github.com/kobezzza/Collecti...re/obj.js#L151
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 21.01.2013 в 15:10.
Ответить с цитированием
  #15 (permalink)  
Старый 21.01.2013, 15:37
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,217

Сообщение от kobezzza
Любую рекурсию можно разложить в цикл. Общий принцип прост (хотя есть сложные рекурсии которые так просто не разложишь).
Это как понять?

Рекурсию для того и используют, что цикл тут не применим... Поскольку даже не понятно сколько штук их будет.

Последний раз редактировалось ksa, 21.01.2013 в 15:39.
Ответить с цитированием
  #16 (permalink)  
Старый 21.01.2013, 15:39
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Сообщение от ksa Посмотреть сообщение
Это как понять?
Ты написал что рекурсию нельзя описать с помощью цикла, я написал, что это не так и описал как это можно сделать и привёл пример кода сложной рекурсивной задачи, где все рекурсии выполняются через цикл

Цитата:
Рекурсию для того и используют, что цикл тут не применим... Поскольку даже не понятно сколько штук их будет.
Почитай мат часть что ли, как работает рекурсия программно на уровне компилятора или если тебе лень попробуй объяснить как работает код по ссылке что я привёл выше без рекурсии.
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 21.01.2013 в 15:42.
Ответить с цитированием
  #17 (permalink)  
Старый 21.01.2013, 15:46
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,217

kobezzza, напиши мне цикличный алгоритм подсчета количества файлов в папках.

Т.е. есть корень диска... Там есть как файлы, так и папки... В каждой папке могут быть как файлы так и папки.
Сделай это без рекурсии, только циклами.

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

Последний раз редактировалось ksa, 21.01.2013 в 15:52.
Ответить с цитированием
  #18 (permalink)  
Старый 21.01.2013, 15:47
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,217

Сообщение от kobezzza
Ты написал что рекурсию нельзя описать с помощью цикла
Я писал про "правильную" рекурсию.
Т.е. когда рекурсивный подход применяется как раз из-за невозможности применения циклов.
Ответить с цитированием
  #19 (permalink)  
Старый 21.01.2013, 15:49
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,217

Сообщение от kobezzza
Мы создаём стек ручками, как массив и на каждый уровень вложенности пушим туда объект с текущем состоянием переменных, затем локальные переменные переопределяем и продолжаем алгоритм до тех пор пока рекурсия не закончится и тогда мы начинаем "всплытие", т.е. итеративно разворачиваем полученный массив и делаем на каждой итерации pop (т.е. срезаем крайне правый элемент).
Смысл сначала куда-то залезть рекурсивно... А потом работать с полученым цыклом?
При том утверждать, что де сделал все без рекурсии!

Сообщение от kobezzza
Мы создаём стек ручками ...
Это уже какой-то частный случай... А не общий подход к рекурси.
Или вся твоя "матчасть" к этому и сводится?

Последний раз редактировалось ksa, 21.01.2013 в 15:54.
Ответить с цитированием
  #20 (permalink)  
Старый 21.01.2013, 15:52
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Сообщение от ksa Посмотреть сообщение
Я писал про "правильную" рекурсию.
Т.е. когда рекурсивный подход применяется как раз из-за невозможности применения циклов.
Я как не странно тоже.
function extend(deep, target, var_args) {
	deep = deep || false;
	target = target || {};
	var aLength = arguments.length,
		
		aEl, key,
		src, copy,
		clone,
		copyIsArray,
		
		i = 1, j,
		
		stack = [],
		level,
		
		last, lastEl;
	
	// Внешний цикл по расширяющим аргументам
	while (++i < aLength) {
		if ((aEl = arguments[i])) {
			// Цикл для эмуляции рекурсии
			while (aEl) {
				level = [];
				
				// Цикл по свойствам объекта
				for (key in aEl) {
					src = target[key];
					copy = aEl[key];
					
					// Защита от бесконечного копирования
					if (target === copy) { continue; }
					
					// Рекурсивное копирование свойств
					// (рекурсия развёрнута)
					if (
						deep && copy
						&& ((copyIsArray = Array.isArray(copy)) || typeof copy === 'object')
					) {
						// Если копируемое свойство - массив
						if (copyIsArray) {
							copyIsArray = false;
							clone = src && Array.isArray(src) ? src : [];
						
						// Если копируемое свойство - объект
						} else {
							clone = src && typeof src === 'object' ? src : {};
						}
						
						// Запоминаем вложенность, чтобы в дальнейшем к ней вернуться
						level.push({
							target: target,
							clone: clone,
							
							aEl: aEl,
							copy: copy,
							
							key: key
						});
					} else {
						target[key] = copy;
					}
				}
				
				// Если на уровне имеются вложенности,
				// то добавляем новый уровень в стек и
				// проиводим сдвиг в крайне правый элемент нового уровня
				if ((last = level.length)) {
					stack.push(level);
					
					last = level[last - 1];
					// Ставим флаг, что элемент учавствует в обходе
					last['__COLLECTION_TMP__'] = true;
					
					// Устанавливаем новую точку отсчёта
					target = last.clone;
					aEl = last.copy;
					
				// На уровне нет вложенностей
				} else if ((last = stack.length)) {
					j = stack.length;
					while (j--) {
						lastEl = stack[j][stack[j].length - 1];
						
						// Если звено не имеет детей и уже было использовано,
						// то удаляем крайне правый элемент и сдвигаем позицию обхода
						if (lastEl['__COLLECTION_TMP__'] && !stack[j + 1]) {
							lastEl.target[lastEl.key] = target;
							target = lastEl.target;
							aEl = lastEl.aEl;
							stack[j].pop();
							
							// В звене не осталось элементов,
							// значит его можно удалить
							if (!stack[j].length) {
								stack.pop();
							}
						
						// Если первое условие не верно,
						// значит продолжать цикл нет смысла
						} else {
							break;
						}
					}
					
					// Устанавливаем новую позицию обхода
					if ((last = stack.length)) {
						last = stack[last - 1];
						lastEl = last[last.length - 1];
						lastEl['__COLLECTION_TMP__'] = true;
						
						target = lastEl.clone;
						aEl = lastEl.copy;
					}
				}
				
				// Операция закончена
				if (!stack.length && !level.length) {
					break;
				}
			}
		}
	}
	
	return target;
};

alert(JSON.stringify(extend(true, {}, {a: {b: 1}, c: {e: 2}}, {a: {b: {e: 2}}})));


Цитата:
Смысл сначала куда-то залезть рекурсивно... А потом работать с полученым цыклом?
Притом утверждать, что де сделал все без рекурсии!
Я писал, что мы руками создаём стек, и эмулируем рекурсию циклом, а смысл: нет проблемы переполнения стека и работает значительно шустрее, к примеру мой вариант extend от 2 до 8 раз быстрее рекурсивного (в зависимости от браузера).

Цитата:
Это уже какой-то частный случай... А не общий подход к рекурси.
Или вся твоя "матчасть" к этому и сводится?
Ты можешь бесконечно спорить на эту тему, но факт остаётся фактом. Любую рекурсию можно раскрыть так.
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 21.01.2013 в 15:59.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по replace. Как заменить все точки в строке? Pluto Общие вопросы Javascript 14 21.04.2017 12:32
Как изменять имена переменных циклом Ivan Draga Общие вопросы Javascript 5 21.01.2011 08:46
Как заменить встроенную функцию Alert? KIVagant Общие вопросы Javascript 4 22.04.2010 11:13
DOM vs iframe. Как в ифрейме заменить выделенный текст (его innerHTML)? Бухалыч Events/DOM/Window 4 20.08.2009 14:30
Как заменить эл-ты одного списка эл-тами другого ? Mayar Элементы интерфейса 5 28.04.2009 11:21