【问题标题】:Highlighting Unbalanced Parentheses in RichTextBox C# Windows Forms在 RichTextBox C# Windows 窗体中突出显示不平衡的括号
【发布时间】:2016-10-07 16:19:13
【问题描述】:

我目前设置了一个 Windows 窗体,它在 RichTextBox 中获取一个数学表达式,并在表达式中搜索任何不平衡的括号。我的表单由 RichTextBox 和一个显示“Check Parens”的按钮组成。我也在尝试使用堆栈检查不平衡的括号。我想要的是以某种方式指出哪些括号是不平衡的。我想通过突出显示或加粗 RichTextBox 中的括号来做到这一点。有没有办法用我现在设置的代码来做到这一点?下面是我的代码,如果有任何建设性的反馈,我们将不胜感激!

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

}

【问题讨论】:

    标签: c# winforms stack highlight parentheses


    【解决方案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);
    }
    

    【讨论】:

      【解决方案2】:

      编辑:鉴于下面的解决方案,这是次要的。如果您想加粗文本,仍然包含示例。您可以将 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);
              }
      
          }
      

      因此,您应该同时跟踪左括号索引和右括号索引。然后只需将匹配对从各自的堆栈中弹出即可。

      就显示文本而言,我不知道这是否是最佳方式,但这是一种可行的方式。它需要重建字符串,但它会将正确的结果放在 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));
          }
      }
      

      【讨论】:

      • 这对我有用,而且你是如何做到的很有意义。非常感谢!
      猜你喜欢
      • 2016-03-19
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      相关资源
      最近更新 更多