【问题标题】:Calculator which can take words as input可以输入单词的计算器
【发布时间】:2011-09-18 00:10:32
【问题描述】:

我想写一个可以输入单词的计算器。 例如“二加五乘以 7”应该给出 37 作为输出。 我不会撒谎,这是一个家庭作业,所以在做这件事之前,我想如果我能指出一些可能对这些事情有用的东西,我不知道。

另外,我想,如何做到这一点也可以。它必须用 C++ 编写。不接受其他语言。

谢谢。

[编辑] -- 感谢您的回答。这是一门入门课程。因此,让事情尽可能简单将不胜感激。我应该早点提到这一点。

[编辑 2] -- 达到了一个阶段,我可以输入数字并优先获得正确的输出。现在只想看看如何将单词转换为数字。感谢所有试图提供帮助的人。这就是 SO 摇滚的原因。

【问题讨论】:

  • 到目前为止,您针对该问题做了哪些尝试?如果您不知道从哪里开始,请从您所知道的开始。你能把文字变成数字吗?你怎么知道你的单词是运算还是数字?
  • 这是一个可怕的任务;英语有很多特点,做到这一点几乎是不可能的。为什么这么早就教学生做错事?
  • @Dennis 我不认为如果有一组有限的输入并且程序可以排除任何不属于特定范围的任何内容,这并不是那么糟糕。否则,我同意你的看法。
  • @jonsca。我已编辑问题以回答您的评论。基本上,“(4+6)*2”现在有效。现在想知道如何将单词转换为数字。
  • @Ian 写一个你刚刚手工完成的句子,看看你需要什么步骤来转换它。我认为您需要确定一组数字是否相关。 Seven hundred ninety one plus 1:根据你的数字单词列表检查每个单词,“七”、“百”、“九十”、“一”匹配,但“加”不匹配。但是,它与您的运营商匹配,因此将所有数字放在一起。进一步将数字分解为 {"seven", "hundred"} 和 {"ninety","one"}。从那里试一试。它现在变得越来越复杂,但它只需要大量的编码......

标签: c++ string calculator


【解决方案1】:

只要可接受的输入足够严格,编写recursive descent parser 应该很容易。这个语法应该与只接受数字和符号的简单计算器的语法差别不大。

使用 std::istream 类和提取运算符 (>>),您可以轻松地将输入分解为单独的单词。

这里有一个lecture,它展示了如何为带有数字和符号的普通计算器执行此操作。

与您的情况的主要区别在于解析数字。而不是符号“0-9”,您的输入将包含“零”、“一”、“九”、“百”、“千”等词。要解析这样的词流,您可以执行类似的操作这个:

  1. 将单词分组,由“乘数”嵌套,如“千”、“百”、“十亿”等;这些组可以嵌套。十位数(“十”、“二十”、“三十”)、十位数(“十一”、“十二”、“十三”、...)和单位(“一”、“二”、“三”、... ..) 不要嵌套任何东西。你把像“130297”这样的东西变成这样的东西:

               +--------+---------+-----+
              /         |         |      \
          thousand   hundred   ninety   seven
           /    \       |
       hundred  three  two
          |
         one
    
  2. 对于每个组,递归地求和它的所有分量,然后乘以它的“乘数”:

                       103297
               +--------+------+----+
              /         |      |     \
          (* 1000) + (* 100) + 90  +  7
           /    \       |
       (* 100) + 3      2
          |
          1
    

【讨论】:

  • 谢谢。我已经达到了您提到的要使用的阶段 - 对字符串进行标记。如何将三千零七之类的东西转换为-3007?你碰巧知道任何算法吗?
  • @Martiho,感谢您的帮助。例如,当输入为 92 时,我将如何处理?它应该转换为 92。
  • 你应该只得到两个没有嵌套的组。一个代表“九十”,一个代表“二”。然后它们应该相加。
  • 我可以通过这种方式做到这一点。谢谢
【解决方案2】:

这是我在学校最喜欢的一些东西。

正确的做法是将其实现为解析器——编写语法,标记您的输入,然后解析。然后你可以递归地评估它。

如果这些听起来都不熟悉(即这是一门介绍性课程),那么您可以用一种不太健壮的方式将它们组合在一起——只需按照自然的方式进行即可。将句子转换为数字和运算,然后进行运算。

【讨论】:

    【解决方案3】:

    注意:我假设这是一门入门级课程,而不是编译器理论课程。如果您正在学习与此相关的特定内容(例如我提到的算法以外的算法),您几乎肯定会应用这些概念

    首先,您必须了解各个单词。为此,您可以将其拼凑起来——一次读一个单词并尝试理解它。逐步建立一个函数,它可以读取您需要使用的一组数字。

    如果输入足够简单(只有您提供的基本形式的表达式,没有括号或任何东西),您可以简单地在读取数字和运算符之间交替,直到输入被完全读取(但如果这应该是健壮,如果你最后读到的是一个运算符,你需要停止并显示一个错误),所以你可以为数字和运算符编写单独的方法。

    要了解如何计算表达式,请使用shunting yard algorithm 以适当的运算符优先级解析表达式。您可以将单词的初始解析与 this 结合起来,只需使用它为算法提供标记。

    要实际计算结果,您需要评估已解析的表达式。为此,您可以简单地使用堆栈作为输出:当您通常推送一个运算符时,您改为弹出 2 个值,将运算符应用于它们,然后推送结果。调车场算法完成后,栈上会有一个值,包含最终结果。

    【讨论】:

    • 谢谢。现在它开始变得有意义了。我现在可以做到这一点 - “2+2*5”给出 12。现在如何解决将单词转换为数字的问题?有什么算法吗?一个可以给三千五百加3。我如何理解这一点?
    • 是否允许“三千五百”?破折号“三千五百”怎么样。您必须处理无效输入吗?通常,您应该这样做,但有时良好的错误处理比有效输入的处理更难 - 因为这是一个介绍类(编译器介绍,也许???)
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2013-01-06
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多