![]() |
|
||||||||||
|
|||||
|
Регистрация: 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 В идеале, сначала надо расчитать значения в скобках, а только потом общую никак не могу понять, как это можно реальзовать пожалуйста, помогите )) извеняюсь если немного загрузил, уже мозги плавятся, не знаю как легче объяснить ))) |
|
||||||
|
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
если вместо:
Цитата:
Цитата:
К сожалению (или к счастью) AS не поддерживает eval. ![]() Но можно легко вашу задачу решить на JavaScript. А для решения на AS я вижу такие пути решения: 1) выискать путём RegExp строку обрамлённую скобками, но не содержащая их внутри: Цитата:
2)заменяем это место на $ Цитата:
сплитим строку по "," получаем массив arr. arr[0] кэйсим по букве C - выбираем передаём ей в качестве аргумента arr.slice(1); результат вставляем вместо $ в строку (2) Цитата:
КОД писать лень да и нет на чём под рукой.. Да и лабораторки надо самому решать - благо путь я вам показал. ![]()
__________________
Отряд Котовскага Последний раз редактировалось Котяра; 29.03.2011 в 03:10. |
|
|||||
|
Регистрация: Mar 2011
Сообщений: 3
|
=)))
спасибо а как это можно решить на javascript ? |
|
|||||
|
Modus ponens
|
> 1) выискать путём RegExp строку обрамлённую скобками, но не содержащая их внутри:
Это называется проблемой сбалансированых скобок. Она, увы, в общем случае не решаема с помощью регулярных выражений. Искать парную скобку прийдется примерно так: Объявить переменную хранящую количество отркытых скобок, Объявить переменную хранящую количество закрытых скобок. Перебирая последовательно символы строки записываем найденные скобки. Если записываемая скобка закрывающая, проверяем, а не совпадает ли количество открытых и закрытых скобок. Если совпадает - решение найдено. Если не совпадает, увеличиваем количество закрывающих на 1. Соответсвенно, если находим открывающую скобку, увеличиваем количество открывающих на 1. Можно параллельно кешировать позиции скобок в строке для последующих поисков, но это сделает алгоритм громоздким. Таким образом мы получим одну или более групп в скобках верхнего уровня. (Либо не получим никаких групп - либо ошибка, либо мы уже все сделали). Рекурсивно вызывая эту же функцию для найденных групп мы найдем все вложенные выражения. 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: 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; } } } 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; } } } 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; } } } 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. |
|
|||||
|
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
Олег, тоже задачка понравилась?)))
вот на js: <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. |
|
|||||
|
Регистрация: Mar 2011
Сообщений: 3
|
спасибо
очень признателен |
|
|||||
|
Modus ponens
|
Я когда-то присматривался, хотел написать что-то вроде продвинутого компилятора CSS для флеша (т.е. простейший мини-язык, который бы позволял в CSS описать какой ресурс к чему относится и выполнить какие-нибудь действия при, например инициализации ресурса), и искал самый простой синтаксис, как можно через рефлекшн получить ссылки и значения... вобщем, я где-то подсознательно почти изобрел S-выражения
А потом понял, что все хорошие вещи уже придуманы до меня.
__________________
Hell is the possibility of sanity |
![]() |
![]() |
Часовой пояс GMT +4, время: 03:06. |
|
|
« Предыдущая тема | Следующая тема » |
|
|