string - F# 如何使用字符串输入解析和评估计算器表达式

标签 string parsing f# calculator f#-interactive

我必须在 F# 中创建一个计算器,但我遇到了一个任务。

我需要将总和作为字符串传递到控制台,例如“4 + 5”并解析计算。

有什么想法吗?

任何帮助将不胜感激

open System

let rec calculator() =
    printf "Choose a sum type \n1: Addition\n2: Subtraction\n3: Mulitiplication\n4: Division\n\n\n"

    let input = Console.ReadLine();

    printf "now type in 2 numbers\n"

    let num1 = Console.ReadLine();
    let num2 = Console.ReadLine();

    let a : int = int32 num1
    let b : int = int32 num2

    let addition x y = x + y
    let subtraction x y = x - y
    let multiply x y = x * y
    let divide x y = x / y 

    match input with

    | "1" -> printfn("The result is: %d")(addition a b)
    | "2" -> printfn("The result is: %d")(subtraction a b)
    | "3" -> printfn("The result is: %d")(multiply a b)
    | "4" -> printfn("The result is: %d")(divide a b)

    ignore(Console.ReadKey())
    ignore(calculator())

calculator()

最佳答案

I need to pass a sum in as a string into the console e.g. "4 + 5" and parse and calculate it.

如果您确定您的字符串是由 '+' 分隔的数字序列可能还有空格,你可以这样做:

"4 + 5".Split '+' |> Seq.sumBy (int)

它有什么作用? .Split '+'用字符 + 分隔字符串并创建字符串序列。在此示例中,序列看起来像 [|"4 "; " 5"|] .函数 Seq.sumBy将给定函数应用于序列的每个元素并对结果求和。我们使用函数 (int)将字符串转换为数字。

请注意,如果字符串包含 + 以外的字符,则此解决方案将失败得很惨,空格和数字,或者如果没有数字的字符串由 + 分隔(例如 + 7 + 87 ++ 8 )。

你可能想捕获 System.FormatException .你最终会得到类似的东西

let sumString (input:string) : int = 
    try
        input.Split '+' |> Seq.sumBy (int)
    with
    | :? System.FormatException ->
        print "This does not look like a sum. Let's just assume the result is zero."
        0

这只会输出 0对于任何无效的公式。避免异常的另一种选择是丢弃所有不需要的字符和空字符串:

 let sumString (input:System.String) : int = 
    (input |> String.filter (fun c -> ['0'; '1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'; '9'; '+'] |> List.contains c)).Split '+'
    |> Seq.filter (((<) 0) << String.length)
    |> Seq.sumBy (int)

这段代码有什么作用? String.filter询问我们的匿名函数是否应考虑每个字符。我们的匿名函数检查字符是否在允许字符列表中。结果是一个仅包含数字和 + 的新字符串.我们用 + 分割这个字符串.

在我们将字符串列表传递给 Seq.sumBy (int) 之前,我们过滤我们的空字符串。这是用 Seq.filter 完成的和功能组合:(<)返回 true如果第一个参数小于第二个参数。我们使用柯里化(Currying)来获得 (<) 0 , 检查给定的整数是否大于 0 .我们用 String.length 组成这个函数它将一个字符串映射到一个整数,告诉它它的长度。

让后Seq.filter使用这个函数,我们将结果列表传递给 Seq.sumBy (int)如上。

然而,这可能会导致除求和之外的任何其他结果都非常令人惊讶。 "4 * 5 + 7"会产生 52 .

关于string - F# 如何使用字符串输入解析和评估计算器表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38146978/

相关文章:

Java从另一个类获取字符串返回null

javascript - 在 JS (Node.js) 中读取 txt 文件的行

f# - F# 中的嵌套联合类型

arrays - BigQuery标准SQL:如何按ARRAY字段分组

sql - 通常,字符串(或varchar)字段用作连接字段吗?

php - 为什么字符串在应用 gzcompress 和 gzuncompress 时具有相同的大小?

java - 解析 XML 并转换为集合

c++ - 在 C++ 中有效地解析日志文件的文本

reflection - 在运行时创建匿名记录类型

f# - F# Async.Parallel 会加快计算速度吗?