假设我有一个字符串 "(paid for) + (8 working hours) + (company rules)" 。现在我想检查这个完整的字符串是否用括号括起来。基本上我想检查字符串是否是这样的:“((付费)+(8个工作小时)+(公司规则))”。如果它已经用括号括起来,那么我将保持原样,否则我会将括号应用于完整的字符串,以便输出为:“((支付)+(8个工作小时)+(公司规则)) ” 。通过计算括号的数量,我无法解决这个问题。
任何人都可以提出解决方案吗?
是Stack
个好主意,但是当您想查看完整的字符串是否被括号包围时,我建议您将遇到的开头括号的索引Stack
放在. 这样,每次您在堆栈中弹出一个项目时,检查它是否为0
,这意味着与此结束括号相对应的开始括号位于字符串的开头。最后一个关闭括号的检查结果将告诉您是否需要添加括号。
例子:
String s = "((paid for) + (8 working hours) + (company rules))";
var stack = new Stack<int>();
bool isSurroundedByParens = false;
for (int i = 0; i < s.Length; i++) {
switch (s[i]) {
case '(':
stack.Push(i);
isSurroundedByParens = false;
break;
case ')':
int index = stack.Any() ? stack.Pop() : -1;
isSurroundedByParens = (index == 0);
break;
default:
isSurroundedByParens = false;
break;
}
}
if (!isSurroundedByParens) {
// surround with parens
}
使用堆栈..就像当你找到一个(括号推动它并当你看到)弹出堆栈时..最后当字符串被完全解析时堆栈应该是空的......这将确保你不会丢失括号..
在您的情况下,如果堆栈之间变为空,则整个字符串都没有括号
例如:对于输入字符串:
(付费)+(8个工时)+(公司规定)
第一个(将被推送,当它遇到时)它将弹出堆栈,现在检查是否还有更多要解析的字符串并且堆栈不为空。如果堆栈为空,则意味着整个字符串不在括号中。
而对于字符串:
(((付费)+(8个工作时间)+(公司规则))
在最后一个 ) 出现之前,堆栈不会为空。
希望这可以帮助...
查找右括号索引
public int FindClosingBracketIndex(string text, char openedBracket = '{', char closedBracket = '}')
{
int index = text.IndexOf(openedBracket);
int bracketCount = 1;
var textArray = text.ToCharArray();
for (int i = index + 1; i < textArray.Length; i++)
{
if (textArray[i] == openedBracket)
{
bracketCount++;
}
else if (textArray[i] == closedBracket)
{
bracketCount--;
}
if (bracketCount == 0)
{
index = i;
break;
}
}
return index;
}
static void Main()
{
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded(""));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("("));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded(")"));
Console.WriteLine("Expected: {0}, Is: {1}", true, IsSurrounded("()"));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(()"));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("())"));
Console.WriteLine("Expected: {0}, Is: {1}", true, IsSurrounded("(.(..)..(..)..)"));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(..)..(..)"));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(..)..(..)..)"));
Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(.(..)..(..)"));
}
非常快
如果第一个左括号有它的右括号,那么结果不可能是真的。最后一个右括号也是如此。
static bool IsSurrounded(string text)
{
if (text.Length < 2 || text.First() != '(' || text.Last() != ')')
return false;
for (var i = 1; i < text.Length - 1; i++)
{
if (text[i] == ')')
return false;
if (text[i] == '(')
break;
}
for (var i = text.Length - 2; i > 0; i--)
{
if (text[i] == '(')
return false;
if (text[i] == ')')
break;
}
return true;
}
当有更多的递归括号时不应该使用,例如((..)) + ((..))
为确保有括号,您可以简单地添加它们:
text = "(" + text + ")"
否则,Botz3000 建议的堆栈:
string text = "(paid for)";
Stack<int> parenthesis = new Stack<int>();
int last = 0;
for (int i = 0; i < text.Length; i++)
{
if (text[i] == '(')
parenthesis.Push(i);
else if (text[i] == ')')
{
last = parenthesis.Pop();
}
}
if (last == 0)
{
// The matching parenthesis was the first letter.
}
您可以使用堆栈之类的东西来检查括号的正确数量。为每个开口计数,为每个闭合支架倒数。相同数量的左大括号和右大括号意味着它匹配。如果您在计数为零时遇到右括号,那就是不匹配。如果您想知道您的字符串是否完全被括号括起来,请检查它们是否都匹配,然后检查您的字符串是否以一个开头。
static void BraceMatch(string text)
{
int level = 0;
foreach (char c in text)
{
if (c == '(')
{
// opening brace detected
level++;
}
if (c == ')')
{
level--;
if (level < 0)
{
// closing brace detected, without a corresponding opening brace
throw new ApplicationException("Opening brace missing.");
}
}
}
if (level > 0)
{
// more open than closing braces
throw new ApplicationException("Closing brace missing.");
}
}