2015-01-29 2 views
0

я должен извлечь все переменные из формулыРаспаковка Формула из строки

Fiddle for below problem

например. (ФБ + АВЫ + ESI)/12

Выхода {FB, AB ESI}

Код, написанные до сего пор

var length = formula.Length; 
      List<string> variables = new List<string>(); 
      List<char> operators = new List<char> { '+', '-', '*', '/', ')', '(', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 
      int count = 0; 
      string character = string.Empty; 
      for (int i = 0; i < length; i++) 
      { 
       if (!operators.Contains(formula[i])) 
        character += formula[i]; 
       else 
       { 
        if (!string.IsNullOrWhiteSpace(character)) 
         variables.Add(character); 
        character = string.Empty; 
        count = i; 
       } 
      } 
      if (!string.IsNullOrWhiteSpace(character)) 
       variables.Add(character); 
      return variables; 

Выход методы является {FB, АВЫ, ESI}, который является правильным

Моей проблемы в том, где содержится числовое Название переменного поле т.е.

например. (FB1 + AB1)/100

Ожидаемый результат: {FB1, AB1}

Но мой обратный метод {FB, AB}

+0

да bcoz я хочу, чтобы удалить номера также из формулы – Nilesh

ответ

1

Вот как вы могли это сделать с помощью регулярных выражений.

 Regex regex = new Regex(@"([A-Z])\w+"); 

     List<string> matchedStrings = new List<string>(); 
     foreach (Match match in regex.Matches("(FB1+AB1)/100")) 
     { 
      matchedStrings.Add(match.Value); 
     } 

Это создаст список строк всех совпадений.

0

Вы можете сделать это таким образом, просто оптимизировать код, вы хотите.

 string ss = "(FB+AB+ESI)/12"; 

     string[] spl = ss.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); 
     string final = spl[0].Replace("(", "").Replace(")", "").Trim(); 
     string[] entries = final.Split(new char[] {'+'}, StringSplitOptions.RemoveEmptyEntries); 
     StringBuilder sbFinal = new StringBuilder(); 
     sbFinal.Append("{"); 
     foreach(string en in entries) 
     { 
      sbFinal.Append(en + ","); 
     } 
     string finalString = sbFinal.ToString().TrimEnd(','); 
     finalString += "}"; 
1

Без регулярных выражений, можно разделить на реальных операторах (не число), а затем удалите все элементы, которые начинаются с номером:

public static List<string> GetVariables(string formula) 
{ 
    if (string.IsNullOrWhitespace(formula)) return new List<string>(); 

    var operators = new List<char> { '+', '-', '*', '/', '^', '%', '(', ')' }; 

    int temp; 
    return formula 
     .Split(operators.ToArray(), StringSplitOptions.RemoveEmptyEntries) 
     .Where(operand => !int.TryParse(operand[0].ToString(), out temp)) 
     .ToList(); 
} 
2

Если имена переменных должны начать с

letter A..Z, a..z 

и если имена переменных в может содержать

letters  A..Z, a..z 
    digits  0..1 
    underscopes _ 

вы можете использовать регулярные выражения:

String source = "(FB2+a_3B+EsI)/12"; 

    String pattern = @"([A-Z]|[a-z])+([A-z]|[a-z]|\d|_)*"; 

    // output will be "{FB2,a_3B,EsI}" 
    String output = "{" + String.Join(",", 
    Regex.Matches(source, pattern) 
     .OfType<Match>() 
     .Select(item => item.Value)) + "}"; 

В случае, если вам нужна коллекция, скажем, массива имен переменных, просто модифицировать Linq:

String names[] = Regex.Matches(source, pattern) 
    .OfType<Match>() 
    .Select(item => item.Value) 
    .ToArray(); 

Однако то, что реализован - это просто наивный токенизатор: вам нужно отделить «имена переменных» от имен функций, имен классов, проверить, не закомментированы ли они и т. д.

0

Что вы пытаетесь сделать, это переводчик.

Я не могу дать вам весь код, но то, что я могу вам дать, - это начало (для этого потребуется много кодирования).

Во-первых, узнайте о reverse polish notation.

Во-вторых, вам нужно узнать о stacks.

В-третьих, вы должны применять оба, чтобы получить то, что хотите интерпретировать.

2

Изменили свой код, чтобы сделать то, что вы просили, но не уверены в подходе к решению, поскольку этот кронштейн и приоритет оператора не принимаются во внимание.

using System; 
using System.Linq; 
using System.Collections.Generic; 

public class Program 
{ 
    public static void Main() 
    { 
     string formula = "AB1+FB+100"; 
     var length = formula.Length; 
     List<string> variables = new List<string>(); 
     List<char> operators = new List<char>{'+', '-', '*', '/', ')', '('}; 
     List<char> numerals = new List<char>{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 

     int count = 0; 
     string character = string.Empty; 
     char prev_char = '\0'; 

     for (int i = 0; i < length; i++) 
     { 
      bool is_operator = operators.Contains(formula[i]); 
      bool is_numeral = numerals.Contains(formula[i]); 
      bool is_variable = !(is_operator || is_numeral); 
      bool was_variable = character.Contains(prev_char); 

      if (is_variable || (was_variable && is_numeral)) 
       character += formula[i]; 
      else 
      { 
       if (!string.IsNullOrWhiteSpace(character)) 
        variables.Add(character); 
       character = string.Empty; 
       count = i; 
      } 

      prev_char = formula[i]; 
     } 

     if (!string.IsNullOrWhiteSpace(character)) 
      variables.Add(character); 

     foreach (var item in variables) 
      Console.WriteLine(item); 
     Console.WriteLine(); 
     Console.WriteLine(); 
    } 
} 

Может также рассмотреть что-то вроде Math-Expression-Evaluator (on nuget)

Смежные вопросы