当前位置: 首页 > 知识库问答 >
问题:

计算包含例如“5 3/2”的字符串的其他想法

景辰钊
2023-03-14

我写了一个程序,你可以输入一个字符串。该字符串应为普通术语,例如“5 3/2”,所有数字和运算符必须通过空格分隔。您可以输入的术语应尽可能长,例如,“1*2*5-1*4 1 5 3 3 3”也应有效和/是唯一允许使用的操作员。

我已经有了一个工作代码。但它忽略了*和/之前和-。但其他一切都做得很完美。其思想是创建两个数组,一个将运算符保存在char数组中(称为char operators[]),另一个数组将整数保存在float数组中(称为float values[])。那么我有这个计算方法,

    void calc(float values[], char operators[]) {
    float res_final;
    float res_array[10];
    int counter = (sizeof(values) / sizeof(*values));

    for (int i = 0; i < getBorder(values); i++) {
        if (i == 0) {
            res_array[i] = switchFunction(values[i], values[i + 1], operators[i]);
        }

        res_final = switchFunction(res_array[i], values[i + 2], operators[i + 1]);
        res_array[i+1] = res_final;
        if (i == getBorder(values)) {
            break;
        }
    }
    std::cout << "evaluation of expression is: " << res_final << std::endl;
    }

    float switchFunction(float val_1, float val_2, char op) {
    switch (op) {
    case '+': return val_1 + val_2;
        break;
    case '-': return val_1 - val_2;
        break;
    case '*': return val_1 * val_2;
        break;
    case '/': return val_1 / val_2;
        break;
    }
    return 0;
    }

代码不是很漂亮,但我想不出更有用的了。我有这么多想法,但当涉及到操作员时,都失败了。我想在“”中定义法线,其余的也一样,但这行不通。

所以,如果您对如何在行之前包含点有任何建议,或者您对我的方法有完全不同的建议,我将很高兴听到:)

共有1个答案

狄高畅
2023-03-14

从长远来看,您希望创建一个表示公式的对象

一个好的结构应该是一棵树。这种树的内部节点是运算符,而叶子是数字。

然后编写一个解析器,将字符串解析为树。我会这样做:

FormulaNode parse(input){
    string left, right;
    if(split_string(input, * or /, left, right){
        return FormulaNode(* or /, parse(left), parse(right))
    if(split_string(input, + or -, left, right){
        ...
    }
    return FormulaNode(number, to_value(string))
}

split_string是一种方法,该方法尝试将字符串按某个符号拆分,如果可能,则返回布尔值并将其拆分为左右引用,

FormulaNode(符号、左子节点、右子节点)作为创建内部节点的构造函数,

公式节点(数字,值)是创建叶子的构造函数。

当然,这一切都是伪代码,没想强加给你一种风格,只是为了说明原理。第二个构造函数可能只属于签名公式节点(常量双)。至于符号,我建议创建类似于枚举操作员类型{加法,...}的东西。

编辑:

这是一个更大的架构,其设计有些不同:

class FormulaTree{

    private:

    class FormulaNode{

        private:

            bool is_number;

            //used members if is number
            double value;

            //used members if not is number / is operator
            OperatorType type;
            unique_ptr<FormulaNode> left_child, right_child;

        public:

            FormulaNode(string input);
            double evaluate() const;
    };

        unique_ptr<FormulaNode> root;

    public:

        Formula(string input);
        double evaluate() const;
}

with(伪代码)

FormulaTree::FormulaNode::FormulaNode(string input){

    if(input contains * or /){

        char symbol = first occurence(input, * or /);
        vector<string> split_input= split at first occurence(input, symbol);
        type = OperatorType(symbol);

        is_number = false;
        left_child = make_unique(new FormulaNode(split_input[0]));
        right_child = make_unique(new FormulaNode(split_input[1]));
        return;
    }

    if(input contains + or -){

        ...
    }

    is_number = true;
    value = parse to int(input);
}

(从长远来看,您可能还希望添加一些检查输入是否合法的内容,如“运算符一侧的字符串不为空”、“解析为int有效,不包含非法字符”等等)

(另外,如果您继续展开这个,您需要一些解析器,首先按括号分隔它)

如果你需要我解释关于这个结构的任何事情,只要问,我会编辑。

编辑:

Slava评论说,最好为不同类型派生FormulaNode。这是对的,我最初编辑它是为了展示这样的设计,但我再次删除了它,因为它可能很容易让初学者感到困惑。

特别是因为这样的模式需要一个有点不同的布局——我们希望让树本身来进行解析,因为派生类不应该相互了解。从长远来看,你想学习这样的东西。我建议你尝试一下我介绍的模式,添加你自己的风格,添加更多的功能(比如力量的符号或使用负数表示负数的选项),然后把它放在CodeReview上。我的理由是,这是你无论如何都想做的,当你这样做的时候,你的代码无论如何都会在每个部分受到攻击,直到它“完美”。

 类似资料:
  • Byte[]utf8=str1.getBytes(“Windows-1254”);test3=新字符串(“windows-1254”); 输出为I:3/Ortakl:1/2:°:1/2 但上述代码在控制台程序中工作良好,即main method main method打印类似 isortakli的输出 任何建议都必须是可行的

  • 我试图在Flatter Firebase中执行一个“where”查询,以按名称进行过滤(如果对象名为“Una casa roja”,用户写“casa”,则必须返回该对象)。我不知道我能问谁。我只有这个,但不是我想要的: 谢谢

  • 本文向大家介绍Python查找最长不包含重复字符的子字符串算法示例,包括了Python查找最长不包含重复字符的子字符串算法示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python查找最长不包含重复字符的子字符串算法。分享给大家供大家参考,具体如下: 题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。例如在“arabcacfr”中,最长的不包含重

  • 本文向大家介绍C#计算2个字符串的相似度,包括了C#计算2个字符串的相似度的使用技巧和注意事项,需要的朋友参考一下 计算字符串相似度,直接来C#代码 返回结果就是相似度了,验证码识别上用的到 爱给模板网提供 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍Lua判断字符串中包含中文字符的方法和计算字符串宽度函数分享,包括了Lua判断字符串中包含中文字符的方法和计算字符串宽度函数分享的使用技巧和注意事项,需要的朋友参考一下 一、判断字符串中包含中文字符的方法 遍历数组,对每个字节使用string.byte(),发现有大于127的,就是汉字,可以参照下面的代码。 二、计算字符串宽度函数