2016-06-07 6 views
0

В настоящее время у меня есть настройка Windows Form, которая принимает математическое выражение внутри RichTextBox и ищет выражение для любых несбалансированных круглых скобок. Моя форма состоит из RichTextBox и кнопки с надписью «Check Parens». Я также пытаюсь проверить несбалансированные круглые скобки, используя стек. Я хочу, чтобы как-то указать, какие скобки не сбалансированы. Я хотел бы сделать это, выделив или выделив круглые скобки внутри RichTextBox. Есть ли способ сделать это с кодом, который я установил прямо сейчас? Вот мой код ниже, и любая конструктивная обратная связь будет высоко оценена!Выделение неуравновешенных скобок в RichTextBox C# Формы Windows

public partial class checkParentheses : Form 
{ 
    const char leftParens = '('; 
    const char rightParens = ')'; 

    public checkParentheses() 
    { 
     InitializeComponent(); 
    } 

    public void checkParensButton_Click(object sender, EventArgs e) 
    { 
     int value; 
     checkBalancedParens(mathEquation.Text, out value); 
    } 

    bool checkBalancedParens(string expression, out int error) 
    { 
     var parens = new Stack<int>(expression.Length);//Create stack 
     error = -1; //Error at -1 

     for (int i = 0; i < expression.Length; i++)//Check for unbalanced Parentheses 
     { 
      char p = expression[i]; 
      if (p == leftParens)//if p finds left parens 
      { 
       parens.Push(i);//push to top of stack 
      } 
      else if (p == rightParens)//if p finds right parens 
      { 
       if (parens.Count == 0)//if stack has zero items 
       { 
        error = i + 1; 
        return false; 
       } 
       parens.Pop();//Returns to top of stack 
      } 
     } 
     if (parens.Count > 0)//if stack has more than 0 items 
     { 
      error = parens.Peek() + 1; //Peek at top of stack 
      MessageBox.Show("Unbalanced"); 
      return false; 
     } 
     MessageBox.Show("Balanced");//Otherwise, expression is balanced 
     return true; 
    } 

} 

ответ

0

EDIT: данное решение ниже, это неполноценно. Пример еще включен, если вы хотите выделить жирным шрифтом текст. Вы могли бы заменить метод HighlightOffenders с

private void HighlightOffenders(IEnumerable<int> listOfIndexes) 
    { 

     foreach (var index in listOfIndexes.Reverse()) 
     { 

      mathEquation.Select(index,1); 
      mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Bold); 
     } 

    } 

Итак, вы должны следить за обоих левых PAREN индексов и правильных PAREN индексов. Затем просто соберите соответствующие пары из своих соответствующих стеков.

Что касается отображения текста, я не знаю, является ли это лучшим способом, но это способ, который будет работать. Он требует перестроения строки, но в RichTextBox он внесет правильные результаты. Вам нужно будет игнорировать тот факт, что моя форма называется «Form1» и заменяет ее «checkParentheses». Вероятно, есть способ сделать выделение поверх реальных персонажей, но я не знаком с ним.

public partial class Form1 : Form 
{ 
    const char leftParenChar = '('; 
    const char rightParenChar = ')'; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public void checkParensButton_Click(object sender, EventArgs e) 
    { 
     checkBalancedParens(mathEquation.Text); 
    } 

    bool checkBalancedParens(string expression) 
    { 
     var leftParensIndexes = new Stack<int>(expression.Length); 
     var rightParensIndexes = new Stack<int>(expression.Length); 
     var isError = false; 


     for (int i = 0; i < expression.Length; i++)//Check for unbalanced Parentheses 
     { 
      char p = expression[i]; 
      if (p == leftParenChar)//if p finds left parens 
      { 
       leftParensIndexes.Push(i);//push to top of stack 
      } 
      else if (p == rightParenChar)//if p finds right parens 
      { 
       rightParensIndexes.Push(i); 

       //keep a record if there is an error, but don't stop yet. 
       if (leftParensIndexes.Count == 0) 
       { 
        isError = true; 
       } 
       else 
       { 
        //eliminate the matching pair if it exists 
        rightParensIndexes.Pop(); 
        leftParensIndexes.Pop(); 
       } 


      } 
     } 
     if (leftParensIndexes.Count > 0)//if stack has more than 0 items 
     { 
      isError = true; 
     } 
     HighlightOffenders(rightParensIndexes.Concat(leftParensIndexes)); 
     return !isError; 
    } 

    private void HighlightOffenders(IEnumerable<int> listOfIndexes) 
    { 
     var text = mathEquation.Text; 
     mathEquation.Clear(); 
     int lastIndex = 0; //store the last index you finished at (for string math) 
     int count = 0; //the number of items that we've added (also for string math) 

     foreach (var index in listOfIndexes.Reverse()) 
     { 

      mathEquation.AppendText(text.Substring(lastIndex, index - lastIndex - count)); 
      mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Bold); 
      mathEquation.AppendText(text.Substring(index,1)); 
      mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Regular); 
      lastIndex = index; 
      count++; 

     } 
     mathEquation.AppendText(text.Substring(lastIndex + count-1, text.Length - lastIndex - count + 1)); 
    } 
} 
+0

Это сработало для меня, и имеет смысл, как вы это сделали. Спасибо! – HylianSith

1

Выделив текст в RichEdit описано здесь here . Полное решение:

private void checkParensButton_Click(object sender, EventArgs e) 
{ 
    // clean up previous selection 
    mathEquation.SelectAll(); 
    mathEquation.SelectionBackColor = Color.White; 

    var indexes = EnumerateUnbalancedParentheses(mathEquation.Text); 
    foreach (var index in indexes) 
    { 
    mathEquation.Select(index, 1); 
    mathEquation.SelectionBackColor = Color.Aqua; 
    } 
} 

private static IEnumerable<int> EnumerateUnbalancedParentheses(string expression) 
{ 
    var openingParentheses = new Stack<int>(); 
    var closingParentheses = new Stack<int>(); 

    for (var i = 0; i < expression.Length; ++i) 
    { 
    var symbol = expression[i]; 
    if (symbol == '(') 
    { 
     openingParentheses.Push(i); 
    } 
    else if (symbol == ')') 
    { 
     if (openingParentheses.Count > 0) 
     openingParentheses.Pop(); 
     else 
     closingParentheses.Push(i); 
    } 
    } 

    return openingParentheses.Concat(closingParentheses); 
}