Создание стека на карте - PullRequest
1 голос
/ 06 декабря 2010

У меня есть строка, которая выглядит следующим образом:

 "7-6-4-1"

или

 "7"

или

 ""

То есть набор чисел, разделенных-.Там может быть ноль или более чисел.

Я хочу вернуть стек с числами, помещенными в указанном порядке (т. Е. Сначала нажать 7 и 1 в первом примере - 1)

Если бы я просто хотел вернуть список, я мог быпросто зайдите str.split("-").map{_.toInt} (хотя это не работает с пустой строкой) /

Хотя нет стека, который можно преобразовать в стек.Так что в настоящее время у меня есть

  {
    val s = new Stack[Int]; 
    if (x.nonEmpty)
        x.split('-').foreach {
    y => s.push(y.toInt)
      }
   s
   }

, который работает, но довольно уродливо.Чего мне не хватает?

РЕДАКТИРОВАТЬ: Благодаря всем респондентам, я многому научился из этого обсуждения

Ответы [ 3 ]

5 голосов
/ 06 декабря 2010
Stack(x.split("-").map(_.toInt).reverse: _*)

Хитрость здесь в том, чтобы передать массив, полученный из split, в компоновщик объектов Stack. По умолчанию элементы располагаются в том же порядке, что и массив, поэтому сначала необходимо изменить массив.

Обратите внимание, что «обрабатывать это как список, а не как отдельный элемент», : _*.


Редактировать: если вы не хотите отлавливать регистр пустых строк отдельно, например, так (используйте нижний для изменяемых стеков, верхний для неизменных):

if (x.isEmpty) Stack() else Stack(x.split("-").map(_.toInt).reverse: _*)
if (x.isEmpty) Stack[Int]() else Stack(x.split("-").map(_.toInt).reverse: _*)

тогда вы можете отфильтровать пустые строки:

Stack(x.split("-").filterNot(_.isEmpty).map(_.toInt).reverse: _*)

, который также «услужливо» обрабатывает такие вещи, как 7-9----2-2-4 для вас (это даст Stack(4,2,2,9,7)).

Если вы хотите обрабатывать еще более опасные ошибки форматирования, вы можете

val guard = scala.util.control.Exception.catching[Int](classOf[NumberFormatException])
Stack(x.split("-").flatMap(x => guard.opt(x.toInt)).reverse: _*)

чтобы вернуть только те элементы, которые действительно могут быть проанализированы.

3 голосов
/ 06 декабря 2010

Не забывайте, что всегда под рукой breakOut, который обеспечивает немного лучшую производительность, чем col: _* (см. Отличное объяснение Даниэля )

Используется здесь с решением Рекса Керра .filterNot(_.isEmpty):

import scala.collection.immutable.Stack
import scala.collection.breakOut

object StackFromString {

  def stackFromString(str: String): Stack[Int] =
    str.split("-").filterNot(_.isEmpty)
      .reverse.map(_.toInt)(breakOut)

  def main(args: Array[String]): Unit = {
    println(stackFromString("7-6-4-1"))
    println(stackFromString("7"))
    println(stackFromString(""))
  }
}

Будет выводить:

Stack(1, 4, 6, 7)
Stack(7)
Stack()
3 голосов
/ 06 декабря 2010
(Stack[Int]() /: (if(x.isEmpty) Array.empty else x.split("-")))(
                  (stack, value) => 
                      stack.push(value toInt))
...