【发布时间】:2012-04-05 20:47:11
【问题描述】:
我已经搜索了好几个小时,但找不到任何与这个问题类似的东西,尽管我确信它必须在之前完成:(
用户首先键入数字和 +/- 符号的组合。例如: 5 + (7-(4+1)-3) + 11。 我有一个类 Add 和一个类 Subtract,程序从输入构建这两个类的树。所以在这个例子中,树看起来像:
Add: 5
Subtract: 7
11 Add: 4
3 1
现在每个类都有一个递归 StepEvaluate 方法,它首先将整个总和打印到控制台。因此,对于前面示例的 Subtract 子树,该对象将打印“7 - (4+1) - 3”。然后它会列出树的每个节点,并要求用户单击一个分支以添加/减去最初为 0 的运行总数。它最终会在最后打印答案。所以如果我们取 5 + (7-3) + 11,控制台的输出将是:
5 + (7-3) + 11
We are going to add to the total with each choice.
The current total is 0.
Choose from the following:
5
+
7-3
+
11
You chose: 11
The current total is 11.
Choose from the following:
5
+
7-3
You chose: 7-3
7 - 3
We are going to subtract from the total with each choice.
The current total is 0.
Choose from the following:
7
-
3
You chose: -3
The current total is -3.
The only remaining choice is 7.
The current total is 4.
So the answer is 4.
The current total is 15.
The only remaining choice is 5.
The current total is 20.
So the answer is 20.
现在我的控制台是一个文本框。在表单构造函数中,创建了一个新线程 Eval 来评估并输出上述结果。每次用户按下按钮时,它都会恢复线程 Eval 并暂停当前线程。然后,Eval 计算出下一个要输出的字符串(使用上面的递归类),将字符串写入静态变量,恢复主线程的执行并暂停 Eval 的执行。然后主线程读取这些静态变量并将其输出到文本框(生产者-消费者)。在按钮点击之间,用户的输入被写入静态变量,因此 Eval 可以在恢复后读取这些变量。
我想在表单上有另一个按钮,它将返回一行。如果这会删除“您选择 A”这一行,那么用户可以更改他的选择,因此下一个输出可以是“您选择 B”。
我已阅读备忘录和命令模式,并了解基于状态和基于操作的撤消/重做。但是我不知道如何使用上述递归和生产者/消费者线程来实现这一点。我真正需要的只是一种使 Eval 的执行点回到一行的方法。但我很确定我不能那样做......
如果您想要加减法的代码,请看这里:
class Add : MathsOperation
{
public List<MathsOperation> Children;
private int total;
public override void StepEvaluate()
{
MathsOperation currentEvaluation;
writeToConsole(this.ToString());
List<MathsOperation> toBeEvaluated = new List<MathsOperation>(Children);
writeToConsole("We are going to add to the total with each choice.");
while (toBeEvaluated.Count > 1)
{
writeToConsole("The current total is " + total + ".");
writeToConsole("Please choose from the following:");
string choices = "";
foreach (MathsOperation child in toBeEvaluated)
{
choices += Environment.NewLine + child.ToString();
if (child != Children.Last())
choices += Environment.NewLine + "+";
}
writeToConsole(choices);
currentEvaluation = read();
if (currentEvaluation is Number)
{
//add to the total and write output
}
else
{
currentEvaluation.StepEvaluate();
//add the static variable Result to the total and write output
}
toBeEvaluated.Remove(currentEvaluation);
}
currentEvaluation = toBeEvaluated.First();
writeToConsole("The only remaining choice is " + currentEvaluation.ToString());
if (currentEvaluation is Number)
{
//add to the total and write output
}
else
{
currentEvaluation.StepEvaluate();
//add the static variable Result to the total and write output
}
toBeEvaluated.Remove(currentEvaluation);
writeToConsole("So the answer is " + total.ToString());
//write total to static variable Result
}
private void writeToConsole(string txt)
{
//Write to static variable, resume main thread and pause this one
}
private MathsOperation read()
{
//read the static variable. I have replaced this with return new for simplicity
return new MathsOperation();
}
}
如果您有任何想法,我将非常乐意接受。
非常感谢您的帮助。
【问题讨论】:
-
我一直在考虑更多,线程并没有真正影响问题。我正在做的是递归树遍历,一步一步地输出到控制台。在任何一步,用户都可以后退。
标签: c# multithreading recursion undo producer-consumer