Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 29.03.2011, 01:25
jdry вне форума Посмотреть профиль Отправить личное сообщение для jdry Найти все сообщения от jdry
  № 1  
Ответить с цитированием
jdry

Регистрация: Mar 2011
Сообщений: 3
По умолчанию Упорядочивание выполнения функций

Доброго времени суток

В общем, возникла небольшая проблема

есть данные, вводимые в формате : 'Тип преобразования,Знач.1,Знач.2,Знач.3,...'
Типа всего два, определяемые буквами P и C
эти типы определяют функции математических преобразований (например если тип P, то выполняется функция(Знач.1 + Знач.2+..), если C, то ((Знач.1*Знач.2*...)/(Знач.1+Знач.2+...))
вот пример:

P,(C,3,4,2),4,6,(P,(P,3,3),1),5,4


В идеале, сначала надо расчитать значения в скобках, а только потом общую


никак не могу понять, как это можно реальзовать


пожалуйста, помогите ))


извеняюсь если немного загрузил, уже мозги плавятся, не знаю как легче объяснить )))

Старый 29.03.2011, 02:59
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 2  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
если вместо:
Цитата:
P,(C,3,4,2),4,6,(P,(P,3,3),1),5,4
использовать
Цитата:
P((C(3,4,2)),4,6,(P((P(3,3)),1)),5,4)
то это ближе к ecmascript синтаксису и можно использовать eval
К сожалению (или к счастью) AS не поддерживает eval.
Но можно легко вашу задачу решить на JavaScript.

А для решения на AS я вижу такие пути решения:
1) выискать путём RegExp строку обрамлённую скобками, но не содержащая их внутри:
Цитата:
P,(C,3,4,2),4,6,(P,(P,3,3),1),5,4
нашли -
2)заменяем это место на $
Цитата:
P,$,4,6,(P,(P,3,3),1),5,4
3)
Код:
C,3,4,2
- строку без скобок отправляем на эвалюатор:
сплитим строку по "," получаем массив arr.
arr[0] кэйсим по букве C - выбираем
Код AS3:
function C(args:Array):Number
{
return результат
}
передаём ей в качестве аргумента arr.slice(1);
результат вставляем вместо $ в строку (2)
Цитата:
P,2.6666666666,4,6,(P,(P,3,3),1),5,4
повторяем все с операции 1, до тех пор пока не получим число (либо ошибку синтаксиса)))))
КОД писать лень да и нет на чём под рукой..
Да и лабораторки надо самому решать - благо путь я вам показал.
__________________
Отряд Котовскага


Последний раз редактировалось Котяра; 29.03.2011 в 03:10.
Старый 29.03.2011, 09:03
jdry вне форума Посмотреть профиль Отправить личное сообщение для jdry Найти все сообщения от jdry
  № 3  
Ответить с цитированием
jdry

Регистрация: Mar 2011
Сообщений: 3
=)))
спасибо
а как это можно решить на javascript ?

Старый 29.03.2011, 12:15
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 4  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
> 1) выискать путём RegExp строку обрамлённую скобками, но не содержащая их внутри:
Это называется проблемой сбалансированых скобок. Она, увы, в общем случае не решаема с помощью регулярных выражений.
Искать парную скобку прийдется примерно так:
Объявить переменную хранящую количество отркытых скобок,
Объявить переменную хранящую количество закрытых скобок.

Перебирая последовательно символы строки записываем найденные скобки.
Если записываемая скобка закрывающая, проверяем, а не совпадает ли количество открытых и закрытых скобок. Если совпадает - решение найдено. Если не совпадает, увеличиваем количество закрывающих на 1. Соответсвенно, если находим открывающую скобку, увеличиваем количество открывающих на 1. Можно параллельно кешировать позиции скобок в строке для последующих поисков, но это сделает алгоритм громоздким.
Таким образом мы получим одну или более групп в скобках верхнего уровня. (Либо не получим никаких групп - либо ошибка, либо мы уже все сделали). Рекурсивно вызывая эту же функцию для найденных групп мы найдем все вложенные выражения.

Код AS3:
var testString:String = "(--((***)+++)-)xxxxxx(-((***)+++(***))--)x((+++)---)";
var testLenght:int = testString.length;
var nextClosingParen:int;
var lastFoundParen:int;
 
while (nextClosingParen < testLenght)
{
	lastFoundParen = nextClosingParen;
	nextClosingParen = this.findMatchingParen(testString, nextClosingParen);
	if (nextClosingParen == -1) break;
	nextClosingParen++;
	trace(testString.substring(testString.indexOf("(", lastFoundParen), nextClosingParen));
}
 
private function findMatchingParen(input:String, from:int = 0):int
{
	var current:String;
	var inputLength:int = input.length;
	var position:int = from;
	var openParens:int;
	var closingParens:int;
	var matchPosition:int = -1;
 
	while (position < inputLength)
	{
		current = input.charAt(position);
		if (current == ")")
		{
			closingParens++;
			if (closingParens == openParens)
			{
				matchPosition = position;
				break;
			}
		}
		else if (current == "(")
		{
			openParens++;
		}
		position++;
	}
	return matchPosition;
}
Да, но есть еще такой момент. Приведенный способ не принимает во внимание тот факт, что вам что-то нужно будет дальше делать с результатом. И получается так, что одну и ту же строку прийдется просматривать более одного раза, а именно столько раз, сколько вложеных групп в ней есть (хотя и уменьшая диапазон с каждым разом).
Поэтому, лучше было бы сделать это следующим образом:
Создать дерево, в котором каждый узел обладает ссылкой на родителя, ссылкой на функцию и массивом аргументов, аргументы могут быть сложными (другие узлы) или простыми (литералы-значения).
Алгоритм действий будет следующим:
- найти первую отркывающую скобку.
- создать узел
- назначить созданный узел текущим
- записать позицию сразу после скобки.
- если следующий символ - закрывающая скобка - назначить текущим родительский узел
- если следующий символ - открывающая скобка - создать новый узел,
- назначить ему родителем текущий узел, назначить новый узел текущим.
- если ни то и ни другое - это имя функции - прочитать все символы до пробела и найти функцию с соответсвующим именем
- если это была функция, сохранить этот факт на будущее, просмотреть следующий символ,
- если следующий - открывающая скобка - создать новый узел (аналогично #6)
- если следующий - закрывающая скобка - аналогично #5
- если ни то и ни другое - это аргумент-лист, прочитать его буквальное значения и записать в текущий узел, повторить.

Прийду на работу, напишу как это выглядит в коде

UPDATE:
Код AS3:
package tests
{
	import flash.display.Sprite;
 
	import tests.nodes.ComplexNode;
	import tests.nodes.Lexer;
	import tests.nodes.Node;
 
	public class TestParensParser extends Sprite
	{
		private var _input:String;
		private var _position:int;
		private var _currentNode:Node;
		private var _word:String;
		private var _isMethodName:Boolean;
		private var _inputError:String = "Input error";
 
		public function TestParensParser()
		{
			super();
			this.text();
		}
 
		private function text():void
		{
			this._input = "(minus (plus (plus 10 20 30) (minus 10 20)) 15.5)";
			// ---------------------------------- = 60  ------- = -10
			// ------------------------------------------------ = 50
			// ------------------------------------------------------ = 34.5
			this._word = "";
			this._isMethodName = true;
			this.read();
			trace(this._currentNode.value); // 34.5
		}
 
		private function read():void
		{
			this._position = 0;
			var inputLenght:int = this._input.length;
			this._currentNode = null;
			var lexer:Lexer = new Lexer();
			lexer.closeHandler = this.closeHandler;
			lexer.defaultHandler = this.defaultHandler;
			lexer.delimiterHandler = this.delimiterHandler;
			lexer.openHandler = this.openHandler;
 
			while (this._position < inputLenght)
			{
				lexer.process(this._input.charAt(this._position));
				this._position++;
			}
		}
 
		public function plus(...rest):Number
		{
			var result:Number;
			var i:int;
 
			if (rest && rest.length)
			{
				for (i = 1, result = rest[0]; i < rest.length; i++)
					result += rest[i];
			}
			return result;
		}
 
		public function minus(...rest):Number
		{
			var result:Number;
			var i:int;
 
			if (rest && rest.length)
			{
				for (i = 1, result = rest[0]; i < rest.length; i++)
					result -= rest[i];
			}
			return result;
		}
 
		private function closeHandler():void
		{
			if (!this._currentNode || !(this._currentNode is ComplexNode)
				|| !(this._currentNode as ComplexNode).method)
			{
				throw this._inputError;
			}
			if (this._word)
			{
				if (this._isMethodName) this.methodHandler();
				else this.valueHandler();
			}
			if (this._currentNode.parent)
				this._currentNode = this._currentNode.parent;
			this._isMethodName = false;
		}
 
		private function valueHandler():void
		{
			if (this._currentNode && this._word)
			{
				if (this._currentNode is ComplexNode)
				{
					(this._currentNode as ComplexNode)
					.add(new Node(parseFloat(this._word)));
				}
				else throw this._inputError;
			}
			this._word = "";
		}
 
		private function methodHandler():void
		{
			if (this._currentNode && this._currentNode is ComplexNode)
			{
				(this._currentNode as ComplexNode).method = this[this._word];
				this._isMethodName = false;
			}
			else throw this._inputError;
			this._word = "";
		}
 
		private function delimiterHandler():void
		{
			if (this._isMethodName && this._word) this.methodHandler();
			else if (this._word) this.valueHandler();
		}
 
		private function defaultHandler():void
		{
			this._word += this._input.charAt(this._position);;
		}
 
		private function openHandler():void
		{
			var newNode:ComplexNode = new ComplexNode();
			if (this._word)
			{
				if (!this._isMethodName) this.valueHandler();
				else this.methodHandler();
			}
			this._isMethodName = true;
			if (this._currentNode) (this._currentNode as ComplexNode).add(newNode);
			newNode.parent = this._currentNode;
			this._currentNode = newNode;
		}
	}
}
Код AS3:
package tests.nodes
{
	public class Node
	{
		public var parent:Node;
 
		public function get value():* { return this._value; }
 
		protected var _value:*;
 
		public function Node(value:* = undefined)
		{
			super();
			this._value = value;
		}
	}
}
Код AS3:
package tests.nodes
{
	public class ComplexNode extends Node
	{
		public var method:Function;
 
		public override function get value():*
		{
			var calculated:Array = [];
 
			for each (var member:Node in this._parameters)
			{
				calculated.push(member.value);
			}
			return this.method.apply(null, calculated);
		}
 
		private var _parameters:Vector.<Node> = new <Node>[];
 
		public function ComplexNode(value:* = undefined) { super(value); }
 
		public function add(child:Node):Node
		{
			this._parameters.push(child);
			return child;
		}
	}
}
Код AS3:
package tests.nodes
{
	public class Lexer
	{
		public var close:String = ")";
		public var delimiter:String = " ";
		public var open:String = "(";
 
		public var closeHandler:Function;
		public var delimiterHandler:Function;
		public var openHandler:Function;
		public var defaultHandler:Function;
 
		public function Lexer() { super(); }
 
		public function process(character:String):void
		{
			switch (character)
			{
				case this.close: this.closeHandler(); break;
				case this.delimiter: this.delimiterHandler(); break;
				case this.open: this.openHandler(); break;
				default: this.defaultHandler();
			}
		}
	}
}
Возможно есть баги, писал не скорую руку. Кроме того, предполагается, что все значения - числа, ну и с ошибками вы как-нибудь по-другому наверное хотели бы разбираться. Но принцип должен быть ясен.
__________________
Hell is the possibility of sanity


Последний раз редактировалось wvxvw; 29.03.2011 в 15:27.
Старый 29.03.2011, 15:32
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 5  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
Олег, тоже задачка понравилась?)))
вот на js:
Код AS3:
<html>
	<body>
		<script type="text/javascript">
			var str="P((C(3,4,2)),4,6,(P((P(3,3)),1)),5,4)";
			var P=function()
			{
				var sum=0;
				for(var i=0;i<arguments.length;i++) {
				sum+=arguments[i];
				}
				return sum;
			}
 
			var C=function()
			{
				var numenator=1;
				var denumenator=0;
				for(var i=0;i<arguments.length;i++) {
				numenator*=arguments[i];
				denumenator+=arguments[i];
				}
				return numenator/denumenator;
			}
			window.alert(str + " = "+eval(str));
		</script>
	</body>
</html>
__________________
Отряд Котовскага


Последний раз редактировалось Котяра; 29.03.2011 в 16:10.
Старый 29.03.2011, 15:34
jdry вне форума Посмотреть профиль Отправить личное сообщение для jdry Найти все сообщения от jdry
  № 6  
Ответить с цитированием
jdry

Регистрация: Mar 2011
Сообщений: 3
спасибо
очень признателен

Старый 29.03.2011, 15:42
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 7  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Я когда-то присматривался, хотел написать что-то вроде продвинутого компилятора CSS для флеша (т.е. простейший мини-язык, который бы позволял в CSS описать какой ресурс к чему относится и выполнить какие-нибудь действия при, например инициализации ресурса), и искал самый простой синтаксис, как можно через рефлекшн получить ссылки и значения... вобщем, я где-то подсознательно почти изобрел S-выражения А потом понял, что все хорошие вещи уже придуманы до меня.
__________________
Hell is the possibility of sanity

Создать новую тему Ответ Часовой пояс GMT +4, время: 03:06.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 03:06.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.