计算字符串中两个字符的总对数

时间:2013-09-09 16:29:38

标签: .net vb.net math numbers

基本上我需要计算一个字符串中的总体数量,这是为了显示一些信息,比如在一个RegularExpression应用程序中建议打开的子标记表达式的总数。

然后我需要计算已关闭的“()”的总数,而不是“(”和“总数”)的总和。

例如在这个字符串中:

Hello (world)

预期结果为:1关闭

下面:

Hello (world) ((how are (you)?

预期结果将是:2关闭和2打开

在这里:

Hello ) ( World?

预期结果将是:2开启

只是觉得可以给我一些想法,可以改进计算它们的方法吗?

我得到了“(”和“)”字符的总数,现在我不知道该怎么做。

  

更新:

我用这个字符串示例进行测试:

(((X)))

但是我得到4个未闭合且只有1个关闭,我正在使用此代码:

Public Function Replace_All_Characters_Except(ByVal str As String, _
                                              ByVal chars As Char(), _
                                              replaceWith As Char) As String

    Dim temp_str As String = String.Empty

    For Each c As Char In str
        For Each cc As Char In chars
            If c = cc Then temp_str &= cc
        Next cc
    Next c

    Return temp_str

End Function

    Dim Total_Parentheses As String = Replace_All_Characters_Except(TextBox_RegEx.Text, {"(", ")"}, String.Empty)
    Dim Total_Unagrupated As Integer = Total_Parentheses.Replace("()", String.Empty).Length
    Dim Total_Agrupated As Integer = (Total_Parentheses.Length - Total_Unagrupated) \ 2

    MsgBox(Total_Parentheses)
    MsgBox(Total_Unagrupated)
    MsgBox(Total_Agrupated)

3 个答案:

答案 0 :(得分:6)

我会在这里使用Stack

Stack<char> stack = new Stack<char>();
string input = @"Hello (world) ((how are (you)?";
//string input = "Hello ) ( World?";

int closed = 0;
int opened = 0;

foreach (var ch in input)
{
    if (ch == '(')
        stack.Push('#');
    else if (ch == ')')
    {
        if (stack.Count == 0)
            opened++;
        else
        {
            closed++;
            stack.Pop();
        }
    }
}

opened += stack.Count;

Console.WriteLine("Opened:{0} Closed:{1}", opened, closed);

修改

    Dim stack As New Stack(Of Char)
    Dim input As String = "Hello (world) ((how are (you)?"
    'Dim input As String = "Hello ) ( World?"

    Dim opened As Integer = 0
    Dim closed As Integer = 0

    For Each ch As Char In input
        If ch = "(" Then
            stack.Push("#")
        ElseIf ch = ")" Then
            If stack.Count = 0 Then
                opened = opened + 1
            Else
                closed = closed + 1
                stack.Pop()
            End If
        End If
    Next

    opened = opened + stack.Count

    Console.WriteLine("Opened:{0} Closed:{1}", opened, closed)

答案 1 :(得分:1)

执行此操作的一种方法是从括号中删除字符串中的所有字符。然后,迭代地从字符串中删除闭合对,直到没有剩余。其余字符无与伦比。伪代码:

string sanitize(string s, List<string> valid_characters){
    string sanitized = "";
    for (char c in s){
        if (valid_characters.contains(c)){
            sanitized.append(c);
        }
    }
    return sanitized;
}

string s = ")Hello((World)())(";

s = sanitize(s, {"(", ")"});
int total_parens = s.length;
while(s.contains("()")){
    s = s.replace("()", "");
}
int unmatched_parens = s.length;
int matched_parens = total_parens - unmatched_parens;
int matched_pairs = matched_parens/2;

这里,“)你好((世界)())(”变成消毒“)(()())(”,而total_parens是8.它减少到“)(()) (“,”)()(“,最后”)(“。unmatched_parens为2,matched_pairs为3。

答案 2 :(得分:0)

如果您想知道问题中描述的“打开情境”的数量,我能想到的最好方法是循环(通过函数调用):

Private Function isOpen(inputString As String) As Integer()

    Dim outArray(2) As Integer
    Dim outOpen As Integer = 0
    Dim outClose As Integer = 0


    Dim openCount As Integer = 0
    Dim closeCount As Integer = 0
    For Each curChar As Char In inputString
        If (curChar = ")") Then
            closeCount = closeCount + 1
            If (openCount > 0) Then
                outClose = outClose + 1
                openCount = openCount - 1
                closeCount = closeCount - 1
            ElseIf (openCount = 0) Then
                outOpen = outOpen + 1
                openCount = 0
                closeCount = 0
            End If
        ElseIf (curChar = "(") Then
            openCount = openCount + 1
        End If
    Next

    If (openCount <> closeCount) Then
        outOpen = outOpen + Math.Abs(openCount - closeCount)
    End If

    Return New Integer() {outOpen, outClose}
End Function

通过以下方式调用:

Dim temp() As Integer = isOpen(inputString)
Dim totOpened As Integer = temp(0)
Dim totClosed As Integer = temp(1)