2016-06-07 7 views
0

Ich habe derzeit eine Windows Form eingerichtet, die einen mathematischen Ausdruck innerhalb einer RichTextBox verwendet, und sucht den Ausdruck für alle unsymmetrischen Klammern. Mein Formular besteht aus der RichTextBox und einer Schaltfläche mit der Aufschrift "Check Parens". Ich versuche auch mit einem Stapel nach unausgeglichenen Klammern zu suchen. Was ich will, ist irgendwie anzugeben, welche Klammern unausgeglichen sind. Ich möchte dies tun, indem Sie die Klammern innerhalb der RichTextBox hervorheben oder fetten. Gibt es eine Möglichkeit, dies mit dem Code zu tun, den ich gerade eingerichtet habe? Hier ist mein Code unten, und jedes konstruktive Feedback würde sehr geschätzt werden!Hervorhebung unsymmetrischer Klammern in RichTextBox C# Windows Forms

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; 
    } 

} 

Antwort

0

EDIT: die Lösung unten gegeben, ist dies schlechter. Beispiel ist immer noch enthalten, wenn Sie den Text fett formatieren möchten. Sie könnten die HighlightOffenders-Methode durch

private void HighlightOffenders(IEnumerable<int> listOfIndexes) 
    { 

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

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

    } 

ersetzen. Sie sollten also sowohl linke als auch rechte Paren-Indizes im Auge behalten. Dann knallen Sie einfach die passenden Paare aus ihren jeweiligen Stapeln.

So weit wie die Anzeige des Textes, weiß ich nicht, ob dies der beste Weg ist, aber das ist ein Weg, der funktioniert. Es erfordert das erneute Erstellen der Zeichenfolge, aber es werden die richtigen Ergebnisse in RichTextBox eingefügt. Sie müssen die Tatsache ignorieren, dass mein Formular "Form1" heißt, und dieses durch "checkParentheses" ersetzen. Es gibt wahrscheinlich eine Möglichkeit, Hervorhebung über die eigentlichen Charaktere zu zeichnen, aber ich bin nicht damit vertraut.

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

Das funktionierte für mich, und es macht Sinn, wie Sie es getan haben. Vielen Dank! – HylianSith

1

Hervorhebungen Text in RichEdit hier beschriebenen here . Vollständige Lösung:

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); 
}