복붙노트

[SCALA] 어떻게 스칼라 루프의 탈출합니까?

SCALA

어떻게 스칼라 루프의 탈출합니까?

어떻게 루프를 탈출합니까?

var largest=0
for(i<-999 to 1 by -1) {
    for (j<-i to 1 by -1) {
        val product=i*j
        if (largest>product)
            // I want to break out here
        else
           if(product.toString.equals(product.toString.reverse))
              largest=largest max product
    }
}

어떻게 꼬리 재귀로 루프를 중첩 설정합니까?

스칼라에서 FOSDEM 2009 http://www.slideshare.net/Odersky/fosdem-2009-1013261에서 이야기 22 페이지 :

설명은 무엇입니까?

해결법

  1. ==============================

    1.당신은 루프의 탈옥 세 (정도) 옵션이 있습니다.

    당신은 루프의 탈옥 세 (정도) 옵션이 있습니다.

    총 당신은 시도보다 큰 1000입니다 때까지 숫자를 합계를 가정

    var sum = 0
    for (i <- 0 to 1000) sum += i
    

    중지 할 때를 제외하고 (합> 1000).

    무엇을 할까? 몇 가지 옵션이 있습니다.

    (1A) 테스트하는 조건을 포함 몇 가지 구문을 사용합니다.

    var sum = 0
    (0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)
    

    (경고 -이는 takeWhile 테스트와 foreach 문이 실제로 사용할 수 없습니다 아마 평가시 인터리브 및 방법의 세부 사항에 따라 달라집니다!).

    (1B) 대신에 for 루프의 사용 꼬리 재귀, 그것은 스칼라에 새로운 메소드를 작성하는 것이 얼마나 쉬운을 활용 :

    var sum = 0
    def addTo(i: Int, max: Int) {
      sum += i; if (sum < max) addTo(i+1,max)
    }
    addTo(0,1000)
    

    (1C) while 루프를 사용하여 폴백

    var sum = 0
    var i = 0
    while (i <= 1000 && sum <= 1000) { sum += 1; i += 1 }
    

    (2) 예외를 발생.

    object AllDone extends Exception { }
    var sum = 0
    try {
      for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
    } catch {
      case AllDone =>
    }
    

    스칼라에서 (2A)가 2.8 이상이 이미 C / 자바에서 익숙한 오래된 휴식처럼 많이 보이는 구문을 사용하여 scala.util.control.Breaks에 미리 포장입니다 :

    import scala.util.control.Breaks._
    var sum = 0
    breakable { for (i <- 0 to 1000) {
      sum += i
      if (sum >= 1000) break
    } }
    

    (3) 방법 및 사용 수익에 코드를 넣습니다.

    var sum = 0
    def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
    findSum
    

    이것은 의도적으로 내가 생각할 수있는 적어도 세 가지 이유없는 너무나 쉽게 이루어집니다. 첫째, 큰 코드 블록에, 그것은 간과 "계속"과 "휴식"문, 또는 당신은 당신이 실제보다 다소 벗어나고 있다고 생각하는, 또는 당신이 할 수없는 두 개의 루프를 깰 필요 쉽게 쉽게 어쨌든 - 그래서 표준 사용이 편리하면서, 그 문제가있다, 그래서 당신은 당신의 코드를 다른 방법을 구성하려고합니다. 둘째, 스칼라는 아마 알 수없는 스팅의 모든 종류가 있습니다, 그래서 당신은 일의 탈옥 수 있다면, 당신은 아마 (특히 폐쇄로) 코드의 흐름이 결국 어디 놀랄 것입니다. 자신의 루프가 라고요 메서드 호출, 또는 그들이 또는 실제로 루프하지 않을 수 있습니다 재귀 있습니다 - - 셋째, 스칼라의 "루프"의 대부분은 실제로 정상 루프없는 그들이 looplike 역할을하지만, 그것은 어렵다 "휴식"등이 무엇을해야하는지 알고 일관된 방법을 마련합니다. 그래서, 일관되게, 할 수있는 현명한 것은 모두에서 "휴식"가 아니다.

    주 : 합계의 값을 반환하는 대신 장소에 돌연변이 곳이 모든 기능적 등가물이있다. 다음은 스칼라 더 관용적이다. 그러나 논리는 동일합니다. (창 등 복귀 X,진다).

  2. ==============================

    2.이것은 휴식을 사용하는 메커니즘을 가지고 스칼라 2.8으로 변경되었습니다. 이제 다음을 수행 할 수 있습니다 :

    이것은 휴식을 사용하는 메커니즘을 가지고 스칼라 2.8으로 변경되었습니다. 이제 다음을 수행 할 수 있습니다 :

    import scala.util.control.Breaks._
    var largest = 0
    // pass a function to the breakable method
    breakable { 
        for (i<-999 to 1  by -1; j <- i to 1 by -1) {
            val product = i * j
            if (largest > product) {
                break  // BREAK!!
            }
            else if (product.toString.equals(product.toString.reverse)) {
                largest = largest max product
            }
        }
    }
    
  3. ==============================

    3.을위한 루프의 탈옥하는 것은 좋은 방법이 아닙니다. 당신이에 대한 루프를 사용하는 경우 그것은 당신이 당신이 반복 할 횟수를 알고 있다는 것을 의미한다. 이 상태로 잠시 루프를 사용합니다.

    을위한 루프의 탈옥하는 것은 좋은 방법이 아닙니다. 당신이에 대한 루프를 사용하는 경우 그것은 당신이 당신이 반복 할 횟수를 알고 있다는 것을 의미한다. 이 상태로 잠시 루프를 사용합니다.

    예를 들면

    var done = false
    while (i <= length && !done) {
      if (sum > 1000) {
         done = true
      }
    }
    
  4. ==============================

    4.렉스 커 다른 방법으로 답을 추가하려면 :

    렉스 커 다른 방법으로 답을 추가하려면 :

  5. ==============================

    5.스칼라에는 휴식이 아직 없기 때문에, 당신은 반환 문을 사용하여이 문제를 해결하기 위해 시도 할 수 있습니다. 따라서 그렇지 않으면 반환은 전체 루프를 건너 뛸 것, 함수로 내부 루프를 넣을 필요가있다.

    스칼라에는 휴식이 아직 없기 때문에, 당신은 반환 문을 사용하여이 문제를 해결하기 위해 시도 할 수 있습니다. 따라서 그렇지 않으면 반환은 전체 루프를 건너 뛸 것, 함수로 내부 루프를 넣을 필요가있다.

    스칼라 2.8 그러나 휴식 할 수있는 방법을 포함

    http://www.scala-lang.org/api/rc/scala/util/control/Breaks.html

  6. ==============================

    6.

    // import following package
    import scala.util.control._
    
    // create a Breaks object as follows
    val loop = new Breaks;
    
    // Keep the loop inside breakable as follows
    loop.breakable{
    // Loop will go here
    for(...){
       ....
       // Break will go here
       loop.break;
       }
    }
    

    브레이크 모듈을 사용 http://www.tutorialspoint.com/scala/scala_break_statement.htm

  7. ==============================

    7.그냥 while 루프를 사용합니다 :

    그냥 while 루프를 사용합니다 :

    var (i, sum) = (0, 0)
    while (sum < 1000) {
      sum += i
      i += 1
    }
    
  8. ==============================

    8.반복자를 사용하여, 그 위에 다음 순회를 우리가 차단 상태까지 반복 그 대신에 먼저 전체 범위를 생성하는 범위 값을 생성하고, 방법은, (트림의 @RexKerr 사용 영감)

    반복자를 사용하여, 그 위에 다음 순회를 우리가 차단 상태까지 반복 그 대신에 먼저 전체 범위를 생성하는 범위 값을 생성하고, 방법은, (트림의 @RexKerr 사용 영감)

    var sum = 0
    for ( i <- Iterator.from(1).takeWhile( _ => sum < 1000) ) sum += i
    
  9. ==============================

    9.다음은 꼬리 재귀 버전입니다. 비교가 인정 하듯이, 조금 애매하지만, 나는 그것의 기능을 말할 것에 대한-지능형 :)

    다음은 꼬리 재귀 버전입니다. 비교가 인정 하듯이, 조금 애매하지만, 나는 그것의 기능을 말할 것에 대한-지능형 :)

    def run(start:Int) = {
      @tailrec
      def tr(i:Int, largest:Int):Int = tr1(i, i, largest) match {
        case x if i > 1 => tr(i-1, x)
        case _ => largest
      }
    
      @tailrec
      def tr1(i:Int,j:Int, largest:Int):Int = i*j match {
        case x if x < largest || j < 2 => largest
        case x if x.toString.equals(x.toString.reverse) => tr1(i, j-1, x)
        case _ => tr1(i, j-1, largest)
      }
    
      tr(start, 0)
    }
    

    볼 수있는 바와 같이, TR 함수 내 하나의 피 지능형 외부의 대응 및 TR1이다. 내 버전을 최적화 할 수있는 방법을 알고 있다면 당신은 환영합니다.

  10. ==============================

    10.솔루션 닫기이 될 것입니다 :

    솔루션 닫기이 될 것입니다 :

    var largest = 0
    for (i <- 999 to 1 by -1;
      j <- i to 1 by -1;
      product = i * j;
      if (largest <= product && product.toString.reverse.equals (product.toString.reverse.reverse)))
        largest = product
    
    println (largest)
    

    제이 반복 새로운 범위 않고있을 때 제품의 세대뿐만 아니라 조건은 대한 문에서 수행된다 (안 좋은 표현 - 내가 더 나은 하나를 찾을 수 없습니다). 조건은 그 문제의 크기에 꽤 빨리되는 반전 - 어쩌면 당신은 더 큰 루프를위한 휴식 뭔가를 얻을 수 있습니다.

    String.reverse 암시 나는이 여분의 반전을 할 이유입니다, RichString로 변환합니다. :) 더 수학적 접근 방법은 더 우아한 수 있습니다.

  11. ==============================

    11.타사 깨뜨릴 패키지는 하나 개의 가능한 대안이다

    타사 깨뜨릴 패키지는 하나 개의 가능한 대안이다

    https://github.com/erikerlandson/breakable

    예제 코드 :

    scala> import com.manyangled.breakable._
    import com.manyangled.breakable._
    
    scala> val bkb2 = for {
         |   (x, xLab) <- Stream.from(0).breakable   // create breakable sequence with a method
         |   (y, yLab) <- breakable(Stream.from(0))  // create with a function
         |   if (x % 2 == 1) continue(xLab)          // continue to next in outer "x" loop
         |   if (y % 2 == 0) continue(yLab)          // continue to next in inner "y" loop
         |   if (x > 10) break(xLab)                 // break the outer "x" loop
         |   if (y > x) break(yLab)                  // break the inner "y" loop
         | } yield (x, y)
    bkb2: com.manyangled.breakable.Breakable[(Int, Int)] = com.manyangled.breakable.Breakable@34dc53d2
    
    scala> bkb2.toVector
    res0: Vector[(Int, Int)] = Vector((2,1), (4,1), (4,3), (6,1), (6,3), (6,5), (8,1), (8,3), (8,5), (8,7), (10,1), (10,3), (10,5), (10,7), (10,9))
    
  12. ==============================

    12.스칼라는 단순히 우리가 할 수있는

    스칼라는 단순히 우리가 할 수있는

    scala> import util.control.Breaks._
    
    scala> object TestBreak{
           def main(args : Array[String]){
           breakable {
           for (i <- 1 to 10){
           println(i)
           if (i == 5){
           break;
           } } } } }
    

    출력 :

    scala> TestBreak.main(Array())
    1
    2
    3
    4
    5
    
  13. ==============================

    13.아이러니하게도 scala.util.control.Breaks의 스칼라 브레이크는 예외입니다 :

    아이러니하게도 scala.util.control.Breaks의 스칼라 브레이크는 예외입니다 :

    def break(): Nothing = { throw breakException }
    

    가장 좋은 조언은 다음과 같습니다, 휴식을 사용하여 계속 고토하지 마십시오! IMO 그들은 "해가 될 생각"같은 나쁜 관행 마지막 문제 (뜨거운 토론) 및 모든 종류의 악의 근원이다. 코드 블록은이 예제에서 휴식이 불필요하고, 구조. 우리 에츠 허르 데이크 스트라 † 썼다 :

  14. ==============================

    14.수집 찾기 방법의 영리한 사용은 당신을 위해 트릭을 할 것입니다.

    수집 찾기 방법의 영리한 사용은 당신을 위해 트릭을 할 것입니다.

    var largest = 0
    lazy val ij =
      for (i <- 999 to 1 by -1; j <- i to 1 by -1) yield (i, j)
    
    val largest_ij = ij.find { case(i,j) =>
      val product = i * j
      if (product.toString == product.toString.reverse)
        largest = largest max product
      largest > product
    }
    
    println(largest_ij.get)
    println(largest)
    
  15. ==============================

    15.

    import scala.util.control.Breaks.break
    
    object RecurringCharacter {
      def main(args: Array[String]) {
        val str = "nileshshinde";
    
        for (i <- 0 to str.length() - 1) {
          for (j <- i + 1 to str.length() - 1) {
    
            if (str(i) == str(j)) {
              println("First Repeted Character " + str(i))
              break()     //break method will exit the loop with an Exception "Exception in thread "main" scala.util.control.BreakControl"
    
            }
          }
        }
      }
    }
    
  16. ==============================

    16.나는 많은 스칼라 스타일은 지난 구년에 어떻게 변화했는지 모르겠지만, 재귀를 읽을 수는 기존의 답변의 대부분이 바르를 사용하는 것이 흥미, 또는 하드 발견했다. 조기 종료의 핵심은, 당신의 가능한 후보를 생성하는 게으른 모음을 사용하여 개별적으로 상태를 확인하는 것입니다. 제품을 생성하려면 :

    나는 많은 스칼라 스타일은 지난 구년에 어떻게 변화했는지 모르겠지만, 재귀를 읽을 수는 기존의 답변의 대부분이 바르를 사용하는 것이 흥미, 또는 하드 발견했다. 조기 종료의 핵심은, 당신의 가능한 후보를 생성하는 게으른 모음을 사용하여 개별적으로 상태를 확인하는 것입니다. 제품을 생성하려면 :

    val products = for {
      i <- (999 to 1 by -1).view
      j <- (i to 1 by -1).view
    } yield (i*j)
    

    그런 다음 모든 조합을 생성하지 않고 해당 뷰에서 첫 번째 회문을 찾을 수 있습니다 :

    val palindromes = products filter {p => p.toString == p.toString.reverse}
    palindromes.head
    

    (어쨌든 전체 목록을 확인해야하기 때문에 게으름을 많이 구입하지 않지만) 가장 큰 회문을 확인하는 방법은 다음과 같습니다

    palindromes.max
    

    원래 코드는 실제로 당신이 의도 한 생각하지 않는 이상한 경계 조건을 제외하고 첫 번째 회문 검사와 동일한 후속 제품보다 큰 최초의 회문를 확인한다. 제품은 엄격하게 단조 감소되지 않습니다. 예를 들어, * 998 998보다 큰 999 * 997이지만, 훨씬 나중에 루프에 나타납니다.

    어쨌든, 분리 게으른 생성 및 상태 검사의 장점은 전체 목록을 사용처럼 꽤 많이 쓰기,하지만 그것은 단지 당신이 필요로하는만큼 생성합니다. 당신은 종류의 두 세계의 최고 얻을.

  17. ==============================

    17.나는 아래의 코드 같은 상황을 가지고

    나는 아래의 코드 같은 상황을 가지고

     for(id<-0 to 99) {
        try {
          var symbol = ctx.read("$.stocks[" + id + "].symbol").toString
          var name = ctx.read("$.stocks[" + id + "].name").toString
          stocklist(symbol) = name
        }catch {
          case ex: com.jayway.jsonpath.PathNotFoundException=>{break}
        }
      }
    

    나는 자바 lib 디렉토리를 사용하고 있습니다 및 메커니즘은 아무것도 찾을 수 없습니다 때이 예외를 던질 ctx.read입니다. 나는 그 상황에 갇혀 있었다 : 나는 예외가 발생 된 루프를 중단해야하지만, scala.util.control.Breaks.break 루프를 중단하는 예외를 사용하고, 따라서이 잡힌 catch 블록에 있었다.

    처음으로 루프를하고 실제 길이의 수를 얻을 : 나는이 문제를 해결하는 추한 방법이있어. 상기 2 루프 사용.

    일부 자바 libs와 사용하는 경우, 스칼라에서 브레이크가 잘되지 않습니다 꺼내.

  18. ==============================

    18.나는 스칼라에 새로운 오전,하지만 이것에 대해 예외를 던지고 방법을 반복하지 않도록하는 방법 :

    나는 스칼라에 새로운 오전,하지만 이것에 대해 예외를 던지고 방법을 반복하지 않도록하는 방법 :

    object awhile {
    def apply(condition: () => Boolean, action: () => breakwhen): Unit = {
        while (condition()) {
            action() match {
                case breakwhen(true)    => return ;
                case _                  => { };
            }
        }
    }
    case class breakwhen(break:Boolean);
    

    다음과 같이 사용 :

    var i = 0
    awhile(() => i < 20, () => {
        i = i + 1
        breakwhen(i == 5)
    });
    println(i)
    

    당신은 헤어지고 싶어하지 않는 경우 :

    awhile(() => i < 20, () => {
        i = i + 1
        breakwhen(false)
    });
    
  19. ==============================

    19.

    import scala.util.control._
    
    object demo_brk_963 
    {
       def main(args: Array[String]) 
       {
          var a = 0;
          var b = 0;
          val numList1 = List(1,2,3,4,5,6,7,8,9,10);
          val numList2 = List(11,12,13);
    
          val outer = new Breaks; //object for break
          val inner = new Breaks; //object for break
    
          outer.breakable // Outer Block
          {
             for( a <- numList1)
             {
                println( "Value of a: " + a);
    
                inner.breakable // Inner Block
                {
                   for( b <- numList2)
                   {
                      println( "Value of b: " + b);
    
                      if( b == 12 )
                      {
                          println( "break-INNER;");
                           inner.break;
                      }
                   }
                } // inner breakable
                if( a == 6 )
                {
                    println( "break-OUTER;");
                    outer.break;
                }
             }
          } // outer breakable.
       }
    }
    

    기본 방법은 휴식 클래스를 사용하여 루프를 중단합니다. 파단로 루프를 선언.

  20. from https://stackoverflow.com/questions/2742719/how-do-i-break-out-of-a-loop-in-scala by cc-by-sa and MIT license