表达式树的后缀表示法

2024-01-08

关于如何将表达式树转换为后缀表示法,有足够的资源,而且并不难。

但我必须将后缀表达式解析为表达式树。

表达式为:

A 2 ^ 2 A * B * - B 2 ^ + A B - /

我真的不知道如何解释这个表达式。有人知道如何处理这个问题吗?


创建一个包含可能是树一部分的节点的堆栈

  1. 将操作数压入堆栈(A、2、B 等是操作数)作为叶节点,不绑定到任何方向的任何树
  2. 对于运算符,将必要的操作数从堆栈中弹出,创建一个节点,运算符位于顶部,操作数挂在其下方,将新节点压入堆栈

对于您的数据:

  1. 将 A 压入堆栈
  2. 将 2 压入堆栈
  3. 弹出2和A,创建^-节点(下面有A和2),将其压入堆栈
  4. 将 2 压入堆栈
  5. 将 A 压入堆栈
  6. 弹出 A 和 2 并组合形成 *-节点
  7. etc.
  8. etc.

这里有一个LINQPad http://linqpad.net可以试验的程序:

// Add the following two using-directives to LINQPad:
// System.Drawing
// System.Drawing.Imaging

static Bitmap _Dummy = new Bitmap(16, 16, PixelFormat.Format24bppRgb);
static Font _Font = new Font("Arial", 12);

void Main()
{
    var elementsAsString = "A 2 ^ 2 A * B * - B 2 ^ + A B - / 2 ^";
    var elements = elementsAsString.Split(' ');

    var stack = new Stack<Node>();
    foreach (var element in elements)
        if (IsOperator(element))
        {
            Node rightOperand = stack.Pop();
            Node leftOperand = stack.Pop();
            stack.Push(new Node(element, leftOperand, rightOperand));
        }
        else
            stack.Push(new Node(element));

    Visualize(stack.Pop());
}

void Visualize(Node node)
{
    node.ToBitmap().Dump();
}

class Node
{
    public Node(string value)
        : this(value, null, null)
    {
    }

    public Node(string value, Node left, Node right)
    {
        Value = value;
        Left = left;
        Right = right;
    }

    public string Value;
    public Node Left;
    public Node Right;

    public Bitmap ToBitmap()
    {
        Size valueSize;
        using (Graphics g = Graphics.FromImage(_Dummy))
        {
            var tempSize = g.MeasureString(Value, _Font);
            valueSize = new Size((int)tempSize.Width + 4, (int)tempSize.Height + 4);
        }

        Bitmap bitmap;
        Color valueColor = Color.LightPink;
        if (Left == null && Right == null)
        {
            bitmap = new Bitmap(valueSize.Width, valueSize.Height);
            valueColor = Color.LightGreen;
        }
        else
        {
            using (var leftBitmap = Left.ToBitmap())
            using (var rightBitmap = Right.ToBitmap())
            {
                int subNodeHeight = Math.Max(leftBitmap.Height, rightBitmap.Height);
                bitmap = new Bitmap(
                    leftBitmap.Width + rightBitmap.Width + valueSize.Width,
                    valueSize.Height + 32 + subNodeHeight);

                using (var g = Graphics.FromImage(bitmap))
                {
                    int baseY  = valueSize.Height + 32;

                    int leftTop = baseY; // + (subNodeHeight - leftBitmap.Height) / 2;
                    g.DrawImage(leftBitmap, 0, leftTop);

                    int rightTop = baseY; // + (subNodeHeight - rightBitmap.Height) / 2;
                    g.DrawImage(rightBitmap, bitmap.Width - rightBitmap.Width, rightTop);

                    g.DrawLine(Pens.Black, bitmap.Width / 2 - 4, valueSize.Height, leftBitmap.Width / 2, leftTop);
                    g.DrawLine(Pens.Black, bitmap.Width / 2 + 4, valueSize.Height, bitmap.Width - rightBitmap.Width / 2, rightTop);
                }
            }
        }

        using (var g = Graphics.FromImage(bitmap))
        {
            float x = (bitmap.Width - valueSize.Width) / 2;
            using (var b = new SolidBrush(valueColor))
                g.FillRectangle(b, x, 0, valueSize.Width - 1, valueSize.Height - 1);
            g.DrawRectangle(Pens.Black, x, 0, valueSize.Width - 1, valueSize.Height - 1);
            g.DrawString(Value, _Font, Brushes.Black, x + 1, 2);
        }

        return bitmap;
    }
}

bool IsOperator(string s)
{
    switch (s)
    {
        case "*":
        case "/":
        case "^":
        case "+":
        case "-":
            return true;

        default:
            return false;
    }
}

Output:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

表达式树的后缀表示法 的相关文章

  • 绘制多边形

    我正在使用 Google Maps API V3 根据路径绘制多边形 该路径是随机未排序坐标点 LatLng 的数组 这会产生以下形状 Polylines intersect Problem 由于多边形的形状取决于路径中点的顺序 因此如何对
  • 子序列和

    给定一个整数数组 例如 1 2 3 1 查找是否存在总和为0并返回它 例如 1 2 3 or 2 3 1 检查每个子序列是O n 2 这效率太低了 有改进的想法吗 创建一个新数组 其中每个元素等于前一个元素加上该元素的总和 Input 1
  • Florian 的 Grisu2 算法如何工作?

    我遇到了一个关于将 double 转换为 ascii 的问题 经过搜索 我得到了 Florian 的论文 使用整数快速准确地打印浮点数 http www cs tufts edu nr cs257 archive florian loits
  • 实施二分查找有哪些陷阱? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 二分查找比看起来更难实现 虽然二分搜索的基本思想相对简单 但细节可能出人意料地棘手 Donald Knuth 新的二分搜索实现中最有可
  • Java递归方法求阶乘返回负输出[重复]

    这个问题在这里已经有答案了 我知道这是溢出 但问题是 20 是相对较小的数字 这不应该发生 对吧 有没有更好的方法来查找大数 例如 1000 的阶乘 而不会得到这种奇怪的结果 public class RecursiveFunctionsE
  • 如何对对象进行排序? (画家算法)

    所以我有 4 个矩形形状 我正在尝试应用排序算法 画家算法 https en wikipedia org wiki Painter 27s algorithm 来知道我需要先绘制哪些形状 在 3d 中 然后绘制哪个形状 Note 相机位于右
  • 使用面向对象的分析和设计对电梯进行建模[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 当涉及到面向对象的设计和分析时 有一组问题似乎在面试和课堂上很常见 这是其中之一 不幸的是 我在大学的 OOP 教授从未真正给出过答案 所以我一
  • 动态规划 (DP) 中的重叠子问题是什么?

    为了使动态规划适用 问题必须具有两个关键属性 最优子结构 and 重叠子问题 1 https en wikipedia org wiki Dynamic programming 对于这个问题 我们只关注后一个属性 有各种不同的定义重叠子问题
  • 数量重新分配逻辑 - 具有外部数据集的 MapGroups

    我正在研究一种复杂的逻辑 需要将数量从一个数据集重新分配到另一个数据集 在例子中我们有Owner and Invoice 我们需要从数量中减去Invoice准确地Owner匹配 在给定汽车的给定邮政编码处 减去的数量需要重新分配回同一辆车出
  • 我正在尝试寻找“调酒师算法”

    我正在解决旧编程竞赛中的一些示例问题 在这个问题中 我们输入了我们有多少调酒师以及他们知道哪种配方 每杯鸡尾酒的制作时间为 1 分钟 我们需要计算是否可以在 5 分钟内使用所有调酒师完成订单 解决这个问题的关键是尽可能高效地分配鸡尾酒 这就
  • “对象之间通过传递消息进行通信”到底是如何实现的?

    在几本有关面向对象编程的介绍性文本中 我遇到过上述陈述 来自维基百科 在 OOP 中 每个对象都能够接收消息 处理数据 以及发送消息与其他对象相关 并且可以被视为具有独特角色或责任的独立 机器 该语句在代码中到底意味着什么 class A
  • 在矩阵/位图中查找质量簇

    这是此处发布的问题的延续 在 2D 位图上查找质心 https stackoverflow com questions 408358 finding the center of mass on a 2d bitmap正如给出的例子 它讨论了
  • 如何在 Unity 中对齐“轨道”或模块化对象?

    我正在开发一个简单的游戏 用户可以在其中放置不同但模块化的对象 例如 轨道 道路等 我的问题是 当将一个物体靠近另一个物体时 如何匹配和放置不同的物体 我的第一种方法是为每个模块对象创建一个隐藏的子对象 一个盒子 并将其放在可以放置其他对象
  • 如何衡量字符串的复杂度?

    我有一些长字符串 1 000 000 个字符 每个字符串仅包含定义字母表中的符号 例如 A 1 2 3 示例字符串 string S1 1111111111 meta complexity 0 string S2 1111222333 me
  • 压缩很多小字符串的算法?

    我正在寻找一种压缩小 ASCII 字符串的算法 它们包含大量字母 但也可以包含数字和很少的特殊字符 它们很小 平均约为 50 100 字节 最多 250 个字节 例子 Android show EditText setError above
  • 优化两个三位数乘积的最大回文数?

    我正在研究一个面试问题 我被问到这个问题 我应该编写一个程序 从两个三位数的乘积中找到最大的回文数 这里是question https projecteuler net problem 4 我想出了这种从底部开始的蛮力方法 public c
  • 如何在 Perforce 树中查找未跟踪的文件? (svn状态的模拟)

    有人有脚本或别名来查找 Perforce 树中未跟踪 实际上 未添加 的文件吗 编辑 我更新了对此已接受的答案 因为看起来 P4V 在 2009 年 1 月的版本中添加了对此的支持 EDIT 请用p4 status现在 不再需要跳圈了 参见
  • 机器人探索算法

    我正在尝试为机器人设计一种算法 试图找到位于未知位置的旗帜 该旗帜位于一个包含障碍物的世界中 机器人的任务是夺取旗帜并将其带到他的基地 代表他的起始位置 机器人在每一步只能看到有限的邻域 他事先不知道世界是什么样子 但他有无限的内存来存储已
  • 将数字的各个数字部分相加/求和的最快方法

    不久前 我在数学论坛上看到一个问题 其中一个人正在讨论一遍又一遍地将数字中的数字相加 直到达到个位数 即 362 将变成 3 6 2 这将变成 11 然后 11 将变成 1 1 将变成 2 因此 362 将返回2 我写了一些很好的代码来得到
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其

随机推荐

  • 在C中迭代整数中的数字

    我有一个像 1191223 这样的整数 我想迭代这些数字 我不知道如何在 C 中做到这一点 有什么简单的方法可以做到这一点吗 Thanks 向前 还是向后 假设一个正整数 unsigned int n 1191223 while n 0 d
  • Mac OS X 上的命令行 IntelliJ

    我正在尝试在 Mac OS X 的命令行上启动 IntelliJ 以使用它的 diff 工具 理论上idea sh diff file1 file2应该管用 在实践中 文件存在一些问题 我认为我已经解决了这些问题 删除了 readlink
  • Android Studio Kotlin 正则表达式与预期不同

    我遇到了特定正则表达式的问题 该正则表达式在 Android Studio 中运行时返回的值与预期不同 设想 代码很简单 val regex lt N E G d 2 d toRegex print regex findAll N20323
  • 解析并生成 JSON

    数学的内置格式列表 http reference wolfram com mathematica guide ImportingAndExporting html相当广泛 然而 JSON 并不在该列表中 Mathematica 中是否有用于
  • 如何使用 Google 地图 API 设计其样式

    我正在尝试更改 Google 地图的样式 但我不确定如何更改 谷歌给了我这些对象属性 stylers hue ff0022 saturation 16 lightness 5 但我不确定如何使用以下代码 生成的谷歌地图 使其工作 div s
  • 获取 HDFS 中 parquet 文件的大小,以便在 Scala 中使用 Spark 重新分区

    我在 HDFS 上有许多 parquet 文件目录 每个目录包含数千个小 大多数 使用以下代码 我可以将本地镶木地板文件重新分区为更少数量的部分 val pqFile sqlContext read parquet file home ha
  • R - 计算列表组件的数量[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我知道在 R 中 您可以通过带有双括号的列表进行索引 即mylist 1 如何计算该列表中的元素数量 不是每个列表项中的元素数量 而是最大
  • 将 C++ 中的所有重音字母更改为普通字母

    问题 如何将 C 或 C 中的所有重音字母更改为普通字母 我的意思是这样的e a c会成为eeeeaaaacc 我已经尝试过的 我尝试过手动解析字符串并一一替换它们 但我认为必须有一种我不知道的更好 更简单的方法 这将保证我不会忘记任何重音
  • Chrome/WebKit 在使用背景、边框半径和顶部/底部边框时创建实心条

    Google Chrome 在边框半径 背景颜色以及顶部和底部边框方面存在问题 这是要重现的证据和代码 http jsfiddle net 6ADtd 4 http jsfiddle net 6ADtd 4 div div div back
  • 如何从登录屏幕进入下一个屏幕? JPanel、JFrame?

    我有一个关于构建 GUI 应用程序的问题 我觉得这个问题的标题不太准确 但我想不出更好的标题 构建应用程序的正确方法是什么 我是否应该只创建一个 JFrame 然后根据需要更改该 JFrame 中的面板 或者当我从一件事转移到另一件事时 我
  • 使用 ndk clang 3.4/3.5 编译 __thread 没有运气

    我试图在这个小程序中使用 thread 但没有运气 知道 ndk 10c clang 3 4 3 5 是否支持此 TLS 相同的程序可以使用 ndk gcc 4 8 4 9 和本机 clang gcc 编译器正常编译 这是程序和编译行 th
  • 将 Firebase 导出到 BigQuery 的数据扁平化为 1 行 = 1 个事件的表(嵌套数据中的嵌套数据)

    我想我可以通过提出一个更简单的问题并引用一个更简单的数据示例来获得我需要的东西here https stackoverflow com questions 38839559 flatten bigquery nested field con
  • C++14 中标准布局类的定义

    A 标准布局class 在 C 14 中的 class 7 中定义 如下 重点是我的 A 标准布局class 是一个类 7 1 没有非标准布局类型的非静态数据成员 类 或此类类型的数组 或引用 7 2 没有虚函数 10 3 也没有虚基类 1
  • 如何通过google帐户快速检查用户是否已经在firebase中注册

    我想为用户执行一个操作首次登录 注册 使用谷歌帐户和另一个操作 如果用户之前已经登录过 如果某个用户已经并且仍然使用他们的 Google 帐户登录 我们可以使用这行代码 Auth auth addStateDidChangeListener
  • JSON.Net读取错误

    我正在尝试使用 Json Net 解析一些 JSON 数据 这是我的数据 UIDClan 1 UIDKnjiga 1 Naslov Title1 DatumZaKada 2013 08 09 00 00 00 DatumIstekRez n
  • 在Java中访问其他类文件

    我们刚刚开始为我的学位学习 Java 我得到了一个文件夹 其中包含各种 Java 类 每个类都有自己的 java 文件 文件名与其所在类的名称相同 有一个文件托管一个公共类 其中包含以下内容 public static void main
  • 修改不是先前提交的提交[重复]

    这个问题在这里已经有答案了 我经常会有如下的工作流程 提交对一组文件的更改 将更改提交到不同的文件组 意识到我错过了一些属于第一次提交的更改 Curse 我无法利用git commit amend因为这不是我需要更改的最新提交 将更改添加到
  • 修复了推回内容的元素

    我正在寻找一种在页面顶部有一个固定元素的方法 该元素会根据页面宽度改变高度 并且还会推回下面的内容 到目前为止我已经解决了一些问题 但我希望有一个更干净的解决方案 我所做的是让两个顶部元素具有相同的内容 一个设置为固定位置 另一个设置为相对
  • 在加载时无需事件即可将数据从子级传递到父级,这在 vue 世界中可能吗?

    我觉得如果没有 click 事件或事件或输入字段或某些需要交互的东西 则不可能将数据从子级传递到父级 只需在加载时通 过使用此数据中的变量和控制将数据从子级数据变量传递到另一个数据变量中的父级父变量 只是加载时 可能吗 将 JSON 数据从
  • 表达式树的后缀表示法

    关于如何将表达式树转换为后缀表示法 有足够的资源 而且并不难 但我必须将后缀表达式解析为表达式树 表达式为 A 2 2 A B B 2 A B 我真的不知道如何解释这个表达式 有人知道如何处理这个问题吗 创建一个包含可能是树一部分的节点的堆