我有Tree
我执行depth-first
算法。它按照元素应该在HTML中的顺序创建树的list
。
我使用它来generate the HTML
显示在视图上。 (作为问题的每个元素都有2个元素,答案没有;答案是leaf
;质疑branch
)
var html = "<ul>";
foreach (var c in listWithElements)
{
html += "<li>";
if (c is Question)
{
var v = (Question)c;
html += v.Content + "<ul>";
}
else
{
var t = (Answer)c;
html += t.Content + "</li>";
}
}
return html + "</ul>";
这会产生一个完美的结构:
<ul>
<li>QUESTION
<ul>
<li>QUESTION
<ul>
<li>ANSWER</li>
<li>ANSWER</li>
**</ul>**
<li>QUESTION
<ul>
<li>ANSWER</li>
<li>QUESTION
<ul>
<li>QUESTION
<ul>
<li>ANSWER</li>
<li>ANSWER</li>
**</ul>**
<li>ANSWER</li>
**</ul>**
</li>
**</ul>**
</li>
**</ul>**
</li>
<li>ANSWER</li>
</ul>
除了HTML生成部分不创建 ul 结束标记。这不是我没有尝试过,只是我似乎无法找到一个模式来确定插入它们的时间/位置。我暂时添加了结束标记,以便更清楚地显示它们的位置。
我能找到的唯一模式是:标签应放在第二个DIRECT li子的ul结束标签之后。
任何帮助?
答案 0 :(得分:3)
你做不到。您需要有关每个节点的更多信息。例如,如果你看一下这个位:
> <ul> > <li>ANSWER</li> > <li>ANSWER</li> > **</ul>** > <li>ANSWER</li>
您的代码无法“知道”那里应该有“ / ul ”。通过循环,没有给出足够的信息。你需要在Answer对象上有一些标记,上面写着“这是当前组中的最后一个答案”或者什么。
答案 1 :(得分:2)
你可以做这样的事情:(我在小提琴样本中进行了测试,看起来效果很好)
var html = "<ul>";
var stack = [];
var pointer = 0;
stack.push(0);
foreach (var c in listWithElements)
{
while (stack[pointer]==2&& pointer>0){
html += "</ul>";
stack.pop();
pointer--;
}
stack[pointer]++;
html += "<li>";
if (c is Question)
{
stack.push(0);
pointer++;
var v = (Question)c;
html += v.Content + "<ul>";
}
else
{
var t = (Answer)c;
html += t.Content + "</li>";
}
}
return html + "</ul>";
工作小提琴示例 - fiddle
编辑:这个解决方案适用于JS,但它在C#中与列表相同:
static void Main(string[] args)
{
Console.WriteLine("<ul>");
string[] listWithElements = { "q", "a", "a", "q", "a", "q", "a", "a", "q" };
List<int> stack = new List<int>();
stack.Add(0);
foreach (var c in listWithElements)
{
while (stack[stack.Count() - 1] == 2 && stack.Count() > 1)
{
Console.WriteLine("</ul>");
stack.RemoveAt(stack.Count() - 1);
}
stack[stack.Count() - 1]++;
Console.WriteLine("<li>");
if (listWithElements[stack.Count() - 1] == "q")
{
stack.Add(0);
Console.WriteLine("qqq");
Console.WriteLine("<ul>");
}
else
{
Console.WriteLine("aaa");
Console.WriteLine("</li>");
}
}
Console.WriteLine("</ul>");
}
答案 2 :(得分:1)
使用depthfirst搜索会非常简单。如果您更深入一步(远离根),则打印开始标记和您现在所在节点的内容。如果你走出一步(到根),则在执行该步骤之前打印节点的结束标记。只需省略将树转换为列表的步骤,事情变得非常简单。
define node: {string content}
define question: node AND {node right , node left}
define answer: node
define toHTML:
input: node root
output: string html
list visited
stack stack
push(stack , root)
add(visited , root)
while ! isEmpty(stack)
node n = first(stack)
add(visited , n)
append(getContent(n))
if isAnswer(n)
remove(stack , n)
else
question q = (question) n
if contains(visited , q.left)
if contains(visited , q.right)
pop(stack)
append(html , closingTag(q))//append the closingtag of the question
else
push(stack , q.right)
else
push(stack , q.left)