I have a code-like string like the following:
a
{
bcd
{
ef
{
gh
{
i
}
j
}
}
k
{
lm开发者_如何学JAVAn
{
op
}
qr
{
st
}
uv
{
wx
}
y
}
z
}
I wish to parse this string such so that I can create a hierarchical array from this code where each tree gets created based on {
and a tree ends at }
.
The array would look like:
[
"a",
"{",
[
"bcd",
"{",
[
"ef",
"{",
[
"gh",
"{",
[
"i"
],
"}",
"j"
],
"}"
],
"}",
"k",
"{",
[
"lmn",
"{",
[
"op"
],
"}",
"qr",
"{",
[
"st"
],
"}",
"uv",
"{",
[
"wx"
],
"}",
"y"
],
"}",
"z"
],
"}"
]
Can any one help me in getting an algo of this?
You can also pass me a code in any of these languages Java/C#/PHP/VB.NET/JavaScript/ActionScript.
If this is all you want to do you could write it like this (C#):
class Node
{
public string Name { get; private set; }
public IEnumerable<Node> Children { get; private set; }
public Node(string name, IEnumerable<Node> children)
{
Name = name;
Children = children;
}
}
class Parser
{
public Node Parse(string s)
{
return Parse(s.Split(new char[0], StringSplitOptions.RemoveEmptyEntries));
}
public Node Parse(IEnumerable<string> tokens)
{
using (var enumerator = tokens.GetEnumerator())
{
enumerator.MoveNext(); // move to first token
return Parse(enumerator);
}
}
Node Parse(IEnumerator<string> enumerator)
{
string name = enumerator.Current;
enumerator.MoveNext();
var children = new List<Node>();
if (enumerator.Current == "{")
{
enumerator.MoveNext();
while (enumerator.Current != "}")
{
children.Add(Parse(enumerator));
}
enumerator.MoveNext();
}
return new Node(name, children);
}
}
This code doesn't check the return value of MoveNext()
, which means it would produce weird results on invalid inputs (including the possibility of an infinite loop).
It also requires that the tokens are delimited by whitespace. So a string like a{b{c}}
would be parsed as one node with the name a{b{c}}
.
Creating a special type Node
is much better than using weakly-typed array (even if you use weakly-typed language). And there is no need to include the braces in the result.
If you want to do something more complicated, I would recommend using some parser library.
If the string might be very long and you're reading it from a file or network, you might want to use some form of stream instead of ordinary string.
You are not really picky about the language, so I'm pretty curious why you want this. Here's some code that should do what you want in C#:
public static object[] ParseSpecial(string s)
{
string dummy = "";
Stack<List<object>> result = new Stack<List<object>>();
result.Push(new List<object>());
foreach (char character in s)
{
switch (character)
{
case '{':
if (dummy.Length > 0)
result.Peek().Add(dummy);
dummy = "";
result.Peek().Add("{");
result.Push(new List<object>());
break;
case '}':
if (dummy.Length > 0)
result.Peek().Add(dummy);
dummy = "";
List<object> temp = result.Pop();
result.Peek().Add(temp.ToArray());
result.Peek().Add("}");
break;
default:
dummy += character;
break;
}
}
if (dummy.Length > 0)
result.Peek().Add(dummy);
return result.Peek().ToArray();
}
精彩评论