Xcode 8.2 Playground中描述的“PAGE”格式是什么?(Which is the format described 'PAGE' in Xcode 8.2 Playground?)
I cloned RxSwift from here.
When I opened Rx.playground I faced such a rich document as shown below.
Which is the format of this?
I googled 'xcode page' but the search result is so fuzzy :[
原文:https://stackoverflow.com/questions/41253795
最满意答案
在这里,我将您的示例输入拆分为如何使用堆栈以及在每个输入处做出的决策的表示。
// _ = nullptr or empty // # = pointer to subtree (not just a number) // | ___ | | | begin (empty element on stack) // | 2__ | | | 2 make number node and set to top->left if empty, else top->right // | 2+_ | | | + set top->input if not set, else pop parent into left of new node // | 2+_ | ___ | | ( make new node on stack // | 2+_ | 3__ | | 3 make number node and set to top->left if empty, else top->right // | 2+_ | 3*_ | | * set top->input if not set, else pop parent into left of new node // | 2+_ | 3*_ | ___ | ( make new node on stack // | 2+_ | 3*_ | 2__ | 2 make number node and set to top->left if empty, else top->right // | 2+_ | 3*_ | 2+_ | + set top->input if not set, else pop parent into left of new node // | 2+_ | 3*_ | 2+2 | 2 make number node and set to top->left if empty, else top->right // | 2+_ | 3*# | | ) pop it off into its parent // | 2+# | | | ) pop it off into its parent // | #+_ | | | + set top->input if not set, else pop parent into left of new node // | #+5 | | | 5 make number node and set to top->left if empty, else top->right
请注意,我有许多重复的语句,一个类型
(
一个用于)
一个用于数字0-9
,一个用于每个操作+-*/
。 您已经在代码中使用了这些分区,因此您处于正确的轨道上。
(
唯一的工作应该是在堆栈顶部创建一个新节点。在你的代码中,没有必要设置input = '('
因为它将被实际输入覆盖以及它在堆栈就是跟踪它所需要的所有东西。你应该将input
初始化为'\0'
或其他意味着空的东西。
)
的工作应该是从堆栈顶部弹出并将其放在需要去的地方。 如果它是null,那么它将是下一个顶部的左边节点,否则它将是顶部的右边节点。 你不需要像你一样循环堆栈,因为它总是只是我们对弹出感兴趣的顶部。一个数字的工作应该是将自己创建为一个新节点并将自己置于需要去的地方。 就像
)
如果它是null那么它将是顶部的左边节点,否则它将是顶部的右边节点。 在您的代码中,您创建节点但不要将它放在堆栈之外的任何位置。 它在那里没有任何好处,因为数字节点将始终是叶节点(没有右边或左边)。最后,操作的工作应该是简单地将自己设置为顶部的
input
。 但是,有一个特殊情况,顶部已经填充(当你做1+2+3
,1+2
是顶部的节点)。 那么你在这种情况下可以做的就是从顶部弹出,在顶部推一个新节点,在左边添加旧顶部,然后将自己设置为顶部input
。 你不需要循环。完成所有操作后,您只需设置
root = tree_stack.top()
。如果你想要我可以提供的代码,但我希望我的解释是足够的。
代码:这似乎对我有用
void Expression_Tree::build_expression_tree(char input[], int size) { // assuming empty tree_stack, it shouldn't really be a member // variable since its only used for building //std::stack<ETNode*> tree_stack; // make empty node, should really make a default constructor set all this up tree_stack.push(new ETNode); tree_stack.top()->left = nullptr; tree_stack.top()->right = nullptr; tree_stack.top()->input = '\0'; for (int i = 0; i < size; i++) { if (input[i] == ' ') { i++; } if (input[i] >= '0' && input[i] <= '9') // this 9 had a typo before { // create number leaf ETNode *temp = new ETNode; temp->left = nullptr; temp->right = nullptr; temp->input = input[i]; // put where it needs to go if (tree_stack.top()->left == nullptr) tree_stack.top()->left = temp; else tree_stack.top()->right = temp; } else if (input[i] == '(') { // make empty node ETNode *temp = new ETNode; temp->left = nullptr; temp->right = nullptr; temp->input = '\0'; tree_stack.push(temp); } else if (input[i] == ')') { // pop top from the stack ETNode *temp = tree_stack.top(); tree_stack.pop(); // put where it needs to go if (tree_stack.top()->left == nullptr) tree_stack.top()->left = temp; else tree_stack.top()->right = temp; } else if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/') { // shuffle node if already filled if (tree_stack.top()->input != '\0') { ETNode *old = tree_stack.top(); tree_stack.pop(); ETNode *temp = new ETNode; temp->left = old; temp->right = nullptr; tree_stack.push(temp); } tree_stack.top()->input = input[i]; } } // set root node root = tree_stack.top(); }
Here I've split up your example input into a representation of how the stack can be used and the decisions made at each input.
// _ = nullptr or empty // # = pointer to subtree (not just a number) // | ___ | | | begin (empty element on stack) // | 2__ | | | 2 make number node and set to top->left if empty, else top->right // | 2+_ | | | + set top->input if not set, else pop parent into left of new node // | 2+_ | ___ | | ( make new node on stack // | 2+_ | 3__ | | 3 make number node and set to top->left if empty, else top->right // | 2+_ | 3*_ | | * set top->input if not set, else pop parent into left of new node // | 2+_ | 3*_ | ___ | ( make new node on stack // | 2+_ | 3*_ | 2__ | 2 make number node and set to top->left if empty, else top->right // | 2+_ | 3*_ | 2+_ | + set top->input if not set, else pop parent into left of new node // | 2+_ | 3*_ | 2+2 | 2 make number node and set to top->left if empty, else top->right // | 2+_ | 3*# | | ) pop it off into its parent // | 2+# | | | ) pop it off into its parent // | #+_ | | | + set top->input if not set, else pop parent into left of new node // | #+5 | | | 5 make number node and set to top->left if empty, else top->right
Note that I have many duplicate statements, one type for
(
one for)
one for a number0-9
and one for each operation+-*/
. You already have these divisions in your code so you're on the right track.
(
's only job should be to create a new node on the top of the stack. In your code, there is no point to setinput = '('
because its going to be overwritten by an actual input later and its position in the stack is all that's needed to keep track of it. You should initializeinput
to'\0'
or something else meaning empty.
)
's job should be to pop the top off the stack and put it where it needs to go. That'll be either the next top's left node if its null, otherwise it'll be top's right node. You don't need to loop down the stack like you do, because it'll always just be the top that we're interested in popping.A number's job should be to create itself as a new node and put itself where it needs to go. Just like
)
that'll either be the top's left node if its null, otherwise it'll be top's right node. In your code, you make the node but you don't put it anywhere besides on the stack. Its not doing any good there because a number node will always be a leaf node (no right or left).Finally an operation's job should be to simply set itself to the top's
input
. However, there's a special case where the top has already been filled in (when you do1+2+3
the1+2
is the node on top). So what you can do in that case is pop off the top, push a new node on top, add the old top as the left, and THEN just set itself to top'sinput
. You don't need a loop.After all is done, you can just set
root = tree_stack.top()
.If you want the code I can supply it but I hope my explanation is enough.
Code: This seems to work for me
void Expression_Tree::build_expression_tree(char input[], int size) { // assuming empty tree_stack, it shouldn't really be a member // variable since its only used for building //std::stack<ETNode*> tree_stack; // make empty node, should really make a default constructor set all this up tree_stack.push(new ETNode); tree_stack.top()->left = nullptr; tree_stack.top()->right = nullptr; tree_stack.top()->input = '\0'; for (int i = 0; i < size; i++) { if (input[i] == ' ') { i++; } if (input[i] >= '0' && input[i] <= '9') // this 9 had a typo before { // create number leaf ETNode *temp = new ETNode; temp->left = nullptr; temp->right = nullptr; temp->input = input[i]; // put where it needs to go if (tree_stack.top()->left == nullptr) tree_stack.top()->left = temp; else tree_stack.top()->right = temp; } else if (input[i] == '(') { // make empty node ETNode *temp = new ETNode; temp->left = nullptr; temp->right = nullptr; temp->input = '\0'; tree_stack.push(temp); } else if (input[i] == ')') { // pop top from the stack ETNode *temp = tree_stack.top(); tree_stack.pop(); // put where it needs to go if (tree_stack.top()->left == nullptr) tree_stack.top()->left = temp; else tree_stack.top()->right = temp; } else if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/') { // shuffle node if already filled if (tree_stack.top()->input != '\0') { ETNode *old = tree_stack.top(); tree_stack.pop(); ETNode *temp = new ETNode; temp->left = old; temp->right = nullptr; tree_stack.push(temp); } tree_stack.top()->input = input[i]; } } // set root node root = tree_stack.top(); }
相关问答
更多-
如何使用堆栈在一次扫描中评估中缀表达式?(How to evaluate an infix expression in just one scan using stacks?)[2022-04-01]
很晚,但这是答案。 两个堆栈: operator stack {用于运算符和括号}。 operand stack 。 算法 如果字符存在被读取: 如果字符是operand operand stack上的operand stack ,则如果字符是( ,按下operator stack 。 否则,如果字符是operator 虽然operator stack的顶部不比这个字符的优先级小。 来自operator stack Pop operator operator stack 。 从operand stack弹出 ... -
您没有提供接受字符串的构造函数。 根据您编写的代码,您应该做什么 new InfixToPostfix().convertString(expression); You don't provide a constructor that accepts a string. What you should do given the code you have written, is new InfixToPostfix().convertString(expression);
-
中缀到二进制表达式树(Infix to Binary Expression Tree)[2023-02-03]
正如昨晚谈到的那样,我要点: 图形节点: //abstract base-class class GraphNode { constructor(){ Object.defineProperty(this, "parent", { writable: true, //enumerable: false, //so it doesn't show up in JSON value: null ... -
Scheme Infix到Postfix(Scheme Infix to Postfix)[2023-10-06]
(根据OP的评论更新;请参阅原始答案下方的新部分。) 使用堆栈列表并使其成为循环变量之一。 例如 (let loop ((stack (list)) ... ; other loop variables here, ; like e.g. what remains of the infix expression ) ... ; loop body ) 然后,只要你想在下一次迭代中改变堆栈上的内容,那么基本上就是这样做。 ( ... -
while (!stack.isEmpty() && Prec(c) <= Prec(stack.peek())) postfix += " " + (stack.pop()); 在添加操作员的任何位置添加操作员之前,请添加一个额外的空间 while (!stack.isEmpty() && Prec(c) <= Prec(stack.peek())) postfix += " " + (stack.pop()); Add an extra ...
-
中缀到Postfix(Infix to Postfix)[2023-08-09]
每次调用不包含NULL指针作为其第一个参数的strtok()都会将strtok()函数的内部指针重置为字符串的开头。 在你的int evaluate_postfix(char* postfix);的循环开始时int evaluate_postfix(char* postfix); 功能,你打电话 token = strtok(postfix, " "); 这意味着在循环开始时,令牌ALWAYS指向后缀开头的第一个非空格字符。 因此每个循环都会看到一个运算符,并尝试从堆栈中弹出()两个值。 但是你的堆栈很快 ... -
下面有几件事情,你应该检查你做的转换,以确定中缀表达式是否有效: 将最后的else添加到确定字符类型的链中,即运算符,数字或括号。 当字符未被识别时,您的代码会击中该分支,这意味着中缀表达式无效。 您可能需要添加另一个“有效”分支以允许空格。 添加一个检查以查看运算符在另一个运算符之前,如2 + * 3 。 您可以在“这是一个操作员”分支中设置bool标志并在其他地方重置。 在弹出左括号之前添加检查堆栈是否为空。 上面的while循环可以结束有两个原因 - 堆栈变空,或者找到相应的左括号。 如果由于堆栈为空 ...
-
假设输入表达式是“3 + 4”,在第54行 expression=expression.replaceAll("[\t\n ]", "")+"="; 表达式变为“3 + 4 =”在标记器操作之后,标记为[“3”,“+”,“4 =”],其在行65上产生对标记“4 =”的错误结果 if(isInteger(token) == true) 因此,当你在第89行上弹出时,价值数量是不够的 value2 = valueStack.pop(); 要解决该问题,请删除第54行中的+“=” expressi ...
-
这取决于运营商的相关性。 一些运算符是左关联的。 例如,2-3-4应解释为(2-3)-4,而不是2-(3-4)。 其他运算符是右关联的。 例如,在C中,x = y = z应解释为x =(y = z),而不是(x = y)= z。 It depends on the associativity of the operators. Some operators are left-associative. For example, 2-3-4 should be interpreted as (2-3)-4, n ...
-
将中缀表达式读入堆栈(Read infix expression into a stack)[2023-06-23]
在这里,我将您的示例输入拆分为如何使用堆栈以及在每个输入处做出的决策的表示。 // _ = nullptr or empty // # = pointer to subtree (not just a number) // | ___ | | | begin (empty element on stack) // | 2__ | | | 2 make number node and set to top->left if empty, else top ...