1
votes

Imprimer des caractères à des indices pairs et impairs à partir d'une chaîne

En utilisant scala, comment imprimer une chaîne dans les indices pairs et impairs d'une chaîne donnée? Je suis conscient de l'approche impérative en utilisant var . Je recherche une approche qui utilise l'immuabilité, évite les effets secondaires (bien sûr, jusqu'au besoin d'imprimer le résultat) et concise.


0 commentaires

4 Réponses :


2
votes
val s = "abcd"
// ac
(0 until s.length by 2).map(i => s(i))
// bd
(1 until s.length by 2).map(i => s(i))
just pure functions with map operator

6 commentaires

Merci. Pourriez-vous s'il vous plaît expliquer le `` s (_) ''? Pouvez-vous s'il vous plaît poster un code équivalent désugarré pour moi?


@ dexter2305 Ne l'utilisez pas s'il s'agit d'une affectation ou d'une performance sensible. Vous devriez vraiment éviter l'accès aléatoire s (i) pour les chaînes car il s'agit de O (n)


@SarveshKumarSingh. Je pensais que s (i) appelle String :: charAt sous le capot qui est le temps constant. Pourriez-vous expliquer plus en détail pourquoi c'est O (n)?


@SarveshKumarSingh Les chaînes ne sont que des wrappers sophistiqués sur Array [Char] , elles sont constantes de leur apply .


@ LuisMiguelMejíaSuárez Oui, j'avais vraiment tort à ce sujet (je ne comprends pas pourquoi j'ai eu cette mauvaise impression) ... bon à savoir à partir de maintenant. docs.scala-lang.org/overviews/collections/…


Merci pour tous les commentaires



3
votes

Une autre façon d'explorer est d'utiliser zipWithIndex

scala> val str = "1234"
str: String = 1234

str.zipWithIndex
res: scala.collection.immutable.IndexedSeq[(Char, Int)] = Vector((1,0), (2,1), (3,2), (4,3))

Dans ce cas, vous pouvez vérifier les résultats en utilisant la fonction imprimante

scala> printer(1)
24
scala> printer(0)
13


1 commentaires

Je suggérerais de passer un Boolean au lieu d'un Int .



3
votes

Voici une solution récursive de queue renvoyant des caractères pairs et impairs (List [Char], List [Char]) en une seule fois

val (even, odd) = f("abcdefg")
println(even.mkString)

qui pourrait être imprimé comme tel

def f(in: String): (List[Char], List[Char]) = {
  @tailrec def run(s: String, idx: Int, accEven: List[Char], accOdd: List[Char]): (List[Char], List[Char]) = {
    if (idx < 0) (accEven, accOdd)
    else if (idx % 2 == 0) run(s, idx - 1, s.charAt(idx) :: accEven, accOdd)
    else run(s, idx - 1, accEven, s.charAt(idx) :: accOdd)
  }
  run(in, in.length - 1, Nil, Nil)
}


1 commentaires

Surtout du style, mais je préfère utiliser :: pour préparer des éléments dans une Liste , cela rend évident à première vue que l'opération est un préfixe et que la collection préfixée est un list et rien d'autre pour lequel les préfixes peuvent être linéaires. (btw, bonne idée de commencer par la fin pour que la liste construite soit déjà dans l'ordre)



3
votes

Vous pouvez utiliser la fonction glissant , qui est assez simple:

scala> "abcdefgh".sliding(1,2).mkString("")
res16: String = aceg

scala> "abcdefgh".tail.sliding(1,2).mkString("")
res17: String = bdfh


0 commentaires