J'ai un problème: j'essaie de déterminer combien d'Ints et de Doubles une chaîne a, par exemple:

12.5+45-(67.78)*3

Résultats attendus:

2 Ints: 45, 3

2 Doubles: 12.5, 67.78

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

Comment déterminer cela?
Merci d'avance. Je suis totalement nouveau sur Swift

-1
Cole MacGrath 21 avril 2017 à 07:15

3 réponses

Meilleure réponse

Je suggérerais de décomposer la formule en sous-chaîne et de placer les informations dans un tableau qui vous permet d'accéder à des composants individuels.

Il sera plus facile de compter les opérateurs, les entiers, les nombres, etc. une fois que vous aurez terminé ce premier niveau d'analyse.

Voici un exemple de la façon dont vous pourriez produire le tableau analysé:

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

Vous pouvez ensuite utiliser ce tableau pour vos différents besoins et, en prime, vous disposez des fichiers .start et .end pour accéder à chacune des sous-chaînes de la fomula

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

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

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

La façon dont cela fonctionne est de marquer d'abord tous les index de chaîne qui correspondent à un opérateur (la variable flags).

Les sous-chaînes de formule commenceront sur chaque opérateur et sur tout caractère qui suit un opérateur (la variable de début).

Une fois que nous avons tous les index de chaîne pour les positions de départ des sous-chaînes de formule, il suffit de les convertir en plages (c'est-à-dire de chaque début au suivant) et d'extraire les sous-chaînes dans un tableau.

J'aurais pu simplement placer les sous-chaînes dans le tableau, mais comme vous aurez besoin des positions dans la chaîne de formule, j'en ai également fait un tuple avec la plage d'index (la variable analysée).

Une fois que vous avez analysé le tableau, compter les opérateurs, les entiers, etc. devient une simple question de filtrage.

Notez que cela ne fonctionnera que pour les opérateurs à caractère unique.

0
Alain T. 21 avril 2017 à 20:06

NSRegularExpression peut rechercher tout dans la chaîne. Voici un exemple pour obtenir un nombre à partir d'une chaîne:

Matchs d'expression régulière d'extrait Swift

Vous pouvez utiliser cette chaîne d'expression régulière pour obtenir un nombre flottant: "\d+\.\d+" ou ceci pour obtenir un nombre int: "\\d+"

1
Community 23 mai 2017 à 10:31
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]

 */
1
user3441734 21 avril 2017 à 05:32