2013-11-21 2 views
1

Я новичок в C# и не имею большого масштаба возможностей для выполнения конкретных задач. Но все еще есть задача создать научный калькулятор.C# отдельный родительский элемент от ребенка. (поиск строк)

То, что я хочу получить, - это разделение родителя с начальным и конечным тегом от дочернего элемента. Также подсчитайте, сколько родителей и порядок, какой родитель является первым, а затем и тогда и так далее.

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

, например:

string somestring = "5+5+(3+1+(0+1))+5+5+(3+1+(0+1))"; 

и из вычисленного результата (пример в JavaScript, но я хочу это в C#):

result = 
[{ 
    "parent" : "content of parent", 
    "child" : ["content of child","content of child"] 
}, 
{ 
    "parent" : "content of parent", 
    "child" :["content of child","content of child","content of child"] 
}]; 

таким образом, что я могу:

  • подсчитать длину массива «результат», чтобы получить число родителей.
  • подсчет длины массива «ребенок», чтобы получить количество детей.
  • получить содержимое элемента, указав номер индекса массива.

Это не должно быть в этом типе массива, но каким-то образом сделать то, что было выше.

Спасибо за ваше время и помощь!

+0

Что вы пробовали до сих пор? Какой элемент в вашей входной строке является родительским, а какой - дочерним? – pasty

+0

@pasty С моим знанием C# я ничего не мог попробовать, я не знаю с чего начать. – Ismail

+0

@pasty, я думаю, он хочет создать дерево выражений. –

ответ

1

Если вы пытаетесь разобрать эту строку , а затем вычислить его значение это не действительный ответ для вас, но если ваша главная цель состоит в том, чтобы вычислить значение данной строки вы можете использовать DataTable.Compute метод.

Это очень легко вычислить с помощью этой функции, вы можете проверить this answer в stackoverflow.

Надеюсь, вы не используете для этого регулярные выражения.

Некоторые люди, столкнувшись с проблемой, думают: «Я знаю, я буду использовать регулярные выражения ». Теперь у них есть две проблемы.

+0

Я также мог использовать .dll из Ncalc (http://ncalc.codeplex.com/), но я хочу научиться самостоятельно создавать его, но не иметь какой-либо сборки в плагине. – Ismail

2

Если вы хотите оценить его самостоятельно, вам нужно будет создать двоичное дерево.

Для родительского узла вы бы дали: 5 + 5 + (3 + 1 + (0 + 1)) + 5 + 5 + (3 + 1 + (0 + 1)) Тогда это создало бы два дочерних узла

. [+] 
./\ 
.[5] [5+(3+1+(0+1))+5+5+(3+1+(0+1))] 

Левая часть в порядке. Правая часть теперь должна быть разделена

. [+] 
./\ 
.[5] [(3+1+(0+1))+5+5+(3+1+(0+1))] 

Левая часть в порядке.Правая часть теперь должны быть расщепляется

.   [+] 
./    \ 
.[(3+1+(0+1))] [5+5+(3+1+(0+1))] 

Обе части должны быть расщепляется

.  [+] 
./  \ 
.[(3+1)] [(0+1)] 

и продолжать как этот

Вы бы в конечном итоге с.

. [+] 
./\ 
.[5] [+] 
. /\ 
. [5] [+] 
.  /\ 
.  [+] [...] 
. / \ 
. [+] [+] 
./\ /\ 
.[3] [1] [0] [1] 

Таким образом, легко оценить результат, найти родителей и детей.

Подробнее: http://en.wikipedia.org/wiki/Binary_expression_tree

+1

И для того, чтобы создать/заполнить древовидную структуру, потребуется какой-то текстовый токенизатор/парсер. – pasty

+0

+1, хороший анализ. –

3

Что вы ищете называется Shunting-yard algorithm. Страница Википедии дает хорошее объяснение алгоритму. Кроме того, я написал article and a C# program, чтобы сделать это для вас, называемого Math Parser .NET. Кроме того, библиотека позволит вам определить свои собственные функции практически для любого!

Кроме того, я также написал программу a tokenizer, чтобы автоматически генерировать код C# или VB.NET на основе ввода, который будет токенизировать ваш вход для вас! Это полезно, если вам нужно написать свой собственный синтаксический анализатор и просто нужно использовать токенизатор, чтобы вы начали.

+1

+1 для бесстыдной рекламы :) –

0

Вы можете использовать синтаксический анализатор lexer + (генератор) для C# для построения дерева выражений. Я написал NLT набор, и у вас есть хороший стартер, включенный в примеры (см. Номер 4 - калькулятор). Это не научный, но это вопрос добавления частей, которые вы хотите. Чтобы дать вам почувствовать, как это работает, это лексический раздел (ключевые части):

"(" -> LPAREN; 
")" -> RPAREN; 
"+" -> PLUS; 
"-" -> MINUS; 
"*" -> MULT, SymbolEnum.MULT; // make the Value equal to MULT as well 
"/" -> DIV; 
"^" -> POWER; 

// regex as pattern 
/[0-9]+/ { 
      $token = SymbolEnum.NUM; 
      $value = Convert.ToDouble($text); 
    }; 

" " { }; 

"#" { lexer.PushState(StatesEnum.COMMENT); }; 
COMMENT /./ { }; 

/./ -> Error; 

%EOF -> EOF; 

Синтаксический короче:

s -> e:exp { e }; 

exp -> LPAREN e:exp RPAREN 
     { e } 
    | e1:exp PLUS e2:exp 
      { new AstNode(SymbolEnum.PLUS, e1, e2) } 
    | e1:exp MINUS e2:exp 
      { new AstNode(SymbolEnum.MINUS, e1, e2) } 
    | e1:exp tok:MULT e2:exp 
      { new AstNode((SymbolEnum)tok, e1, e2) } 
    | e1:exp DIV e2:exp 
      { new AstNode(SymbolEnum.DIV, e1, e2) } 
    | e1:exp POWER e2:exp 
      { new AstNode(SymbolEnum.POWER, e1, e2) } 
    | n:NUM 
      { new AstNode(n) } 
    | LPAREN Error RPAREN 
      // no code 
    ; 
Смежные вопросы