确定一个字符串有多少Ints,Doubles和数学运算符

时间:2017-04-21 04:15:49

标签: swift

我遇到了一个问题:我正在尝试确定一个字符串有多少Ints和Doubles,例如:

12.5+45-(67.78)*3

预期结果:

2 Ints: 45, 3

2 Doubles: 12.5, 67.78

7 symbols: .,+,-,(,.,),*

我如何确定?
提前致谢。我对Swift来说是全新的

3 个答案:

答案 0 :(得分:1)

NSRegularExpression可以搜索字符串中的所有内容。这是从字符串中获取数字的示例:

Swift extract regex matches

您可以使用此正则表达式字符串获取Float编号:"\d+\.\d+"或此以获取Int编号:"\\d+"

答案 1 :(得分:1)

let math = "+-/*()"
let teststring = "10+12.44/(3.14*7+20)"

let isOperator = { c in
    math.characters.contains(c)
}


let numbers = teststring.characters.split(whereSeparator: isOperator).map(String.init)
let operators = teststring.characters.filter(isOperator)

let integers = numbers.flatMap { Int($0) }
let doubles = numbers.flatMap { c->Double? in
    if let i = Int(c) {
        return nil
    } else {
        return Double(c)
    }
}

print("\(operators.count) operators \(operators)")
print("\(integers.count) integers \(integers)")
print("\(doubles.count) doubles \(doubles)")

/* prints

 6 operators ["+", "/", "(", "*", "+", ")"]
 3 integers [10, 7, 20]
 2 doubles [12.44, 3.1400000000000001]

 */

答案 2 :(得分:0)

我建议在子字符串中分解公式并将信息放在允许​​您访问单个组件的数组中。

一旦完成第一级解析,就会更容易计算运算符,整数,数字等。

以下是如何生成解析数组的示例:

let formula = "10+12.44/(3.14*7+20)"

let operators = "+-*/()"
let operSet   = Set(operators.characters)


let flags   = formula.characters.indices
              .map{($0,operSet.contains(formula[$0]))}
              // [(String.Index,Bool)]

let starts  = zip(flags,  [(formula.startIndex,true)] + flags)
              .filter{ $0.1 || $1.1 }.map{$0.0.0}
              // [String.Index]

let parsed  = zip(starts, starts.dropFirst() + [formula.endIndex])
              .map{ (string:formula[$0..<$1], start:$0, end:$1) }
              // [(String, String.Index, String.Index)]

// parsed will contain tupples with substrings and start/end indexes
//
// .string    .start   .end
// -------    ------   ----
//   10          0       2
//   +           2       3
//   12.44       3       8
//   /           8       9
//   (           9      10
//   3.14       10      14
//   *          14      15
//   7          15      16
//   +          16      17
//   20         17      19
//   )          19      20

然后您可以使用此数组来满足您的各种需求,作为奖励,您可以使用.start和.end来获取每个公式子串

let operators = parsed.filter{operators.contains($0.string)} 

let integers = parsed.filter{Int($0.string) != nil}

let decimals = parsed.filter{$0.string.contains(".")}

它的工作方式是首先标记对应于运算符的所有字符串索引(flags变量)。

公式子字符串将从每个运算符和运算符后面的任何字符(启动变量)开始。

一旦我们得到公式子串的起始位置的所有字符串索引,我们只需要将它们转换为范围(即从每个开始到下一个),并将子串提取到数组中。

我可以把子串放在数组中,但由于你需要公式字符串中的位置,所以我把它作为一个带有索引范围的元组(解析变量)。

一旦得到解析后的数组,计算运算符,整数等就变成了一个简单的过滤问题。

请注意,这仅适用于单个字符操作符。