मैं स्काला में एक लूप से कैसे टूट सकता हूं?


276

मैं एक पाश कैसे तोड़ूं?

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 में Scala Talk से http://www.slideshare.net/Odersky/fosdem-2009-1013261 22 वें पेज पर:

तोड़ो और जारी रखो स्काला उनके पास नहीं है। क्यों? वे थोड़ा अत्यावश्यक हैं; बेहतर कई छोटे कार्यों का उपयोग करें कैसे क्लोजर के साथ बातचीत करें। उनकी जरूरत नहीं है!

स्पष्टीकरण क्या है?


आपकी तुलना को एक दूसरे के बराबर-संकेत की आवश्यकता है: यदि (product.toString == product.toString.reverse) या शायद एक समान-विधि-कॉल।
उपयोगकर्ता अज्ञात

हाँ, मुझे याद है कि जब मैं इसे टाइप कर रहा था
TiansHUo

मुझे पता है कि मैं एक पुराने प्रश्न को फिर से जीवित कर रहा हूं, लेकिन मुझे यह जानना अच्छा लगेगा कि इस कोड का उद्देश्य क्या है? मैं पहली बार यह है कि आप में से दिए गए संयोजनों के साथ सबसे बड़े "विलोमपद" उत्पाद संभव खोजने की कोशिश कर रहे थे iऔर j। यदि यह कोड लूप से बाहर आए बिना पूरा होने के लिए चलता है, तो परिणाम होता है, 906609लेकिन लूप से जल्दी 90909टूटने के कारण, परिणाम लूप से बाहर हो रहा है, कोड को "अधिक कुशल" नहीं बना रहा है क्योंकि यह परिणाम को बदल रहा है।
रयान एच।

जवाबों:


371

आपके पास छोरों को तोड़ने के लिए तीन (या तो) विकल्प हैं।

मान लीजिए कि आप कुल संख्या 1000 से अधिक होने तक संख्याओं को जोड़ना चाहते हैं। आप प्रयास करें

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

सिवाय इसके कि आप कब रुकना चाहते हैं (राशि> 1000)।

क्या करें? कई विकल्प हैं।

(1 ए) कुछ निर्माण का उपयोग करें जिसमें एक शर्त शामिल है जिसे आप परीक्षण करते हैं।

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

(चेतावनी - यह इस बात पर निर्भर करता है कि मूल्यांकन के दौरान टेकवाइल टेस्ट और फॉर्च्यूस को कैसे इंटरलेक्ट किया गया है, और शायद इसका उपयोग अभ्यास में नहीं किया जाना चाहिए!)।

(1 बी) लूप के बजाय टेल रिकर्सियन का उपयोग करें, इसका फायदा उठाकर स्कैला में एक नई विधि लिखना कितना आसान है:

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

(1 सी) थोड़ी देर लूप का उपयोग करने के लिए वापस गिरें

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

(२) अपवाद फेंकना।

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+ में यह पहले से ही scala.util.control.Breaksसिंटैक्स का उपयोग करने में पहले से पैक है जो सी / जावा से आपके परिचित पुराने ब्रेक की तरह दिखता है:

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

(३) कोड को एक विधि में रखें और रिटर्न का उपयोग करें।

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

यह जानबूझकर किया गया है, कम से कम तीन कारणों से जो मैंने सोचा हो सकता है के लिए बहुत आसान नहीं है। सबसे पहले, बड़े कोड ब्लॉक में, "जारी" और "ब्रेक" बयानों को अनदेखा करना आसान है, या यह सोचने के लिए कि आप वास्तव में हैं, या दो छोरों को तोड़ने की ज़रूरत है जो आप नहीं कर सकते। वैसे भी आसानी से - इसलिए मानक उपयोग, जबकि काम, इसकी समस्याएं हैं, और इस प्रकार आपको अपने कोड को एक अलग तरीके से बनाने की कोशिश करनी चाहिए। दूसरा, स्कैला में सभी प्रकार के घोंसले होते हैं जिन्हें आप शायद नोटिस भी नहीं करते हैं, इसलिए यदि आप चीजों से बाहर निकल सकते हैं, तो आप शायद आश्चर्यचकित होंगे कि कोड प्रवाह समाप्त कैसे हुआ (विशेष रूप से क्लोजर के साथ)। तीसरा, स्काला के अधिकांश "लूप्स" वास्तव में सामान्य लूप नहीं हैं - वे विधि कॉल हैं जिनके पास अपना लूप है,looplike, यह जानने के लिए एक सुसंगत तरीके के साथ आना मुश्किल है कि "ब्रेक" और इस तरह क्या करना चाहिए। तो, सुसंगत होने के लिए, समझदार बात यह है कि "ब्रेक" बिल्कुल नहीं है।

नोट : इन सभी के कार्यात्मक समतुल्य हैं जहाँ आप sumइसे स्थान पर बदलने के बजाय इसका मूल्य लौटाते हैं । ये अधिक मुहावरेदार स्काला हैं। हालाँकि, तर्क वही रहता है। ( returnबन जाता है return x, आदि)।


9
पुन: अपवाद, हालांकि सख्ती से सच है कि आप एक अपवाद फेंक सकते हैं, यह यकीनन अपवाद तंत्र का दुरुपयोग है (प्रभावी जावा देखें)। अपवाद वास्तव में उन स्थितियों को इंगित करने के लिए हैं जो वास्तव में अप्रत्याशित हैं और / या कोड से कठोर भागने की आवश्यकता है, अर्थात किसी प्रकार की त्रुटियां। इसके अलावा, वे निश्चित रूप से बहुत धीमी गति से होते थे (वर्तमान स्थिति के बारे में निश्चित नहीं) क्योंकि जेवीएम के पास उन्हें अनुकूलित करने के लिए बहुत कम कारण है।
जोनाथन

28
@ जोनाथन - अपवाद केवल धीमे हैं यदि आपको स्टैक ट्रेस की गणना करने की आवश्यकता है - ध्यान दें कि मैंने मक्खी पर एक उत्पन्न करने के बजाय फेंकने के लिए एक स्थिर अपवाद कैसे बनाया! और वे पूरी तरह से वैध नियंत्रण निर्माण हैं; वे स्काला लाइब्रेरी में कई स्थानों पर उपयोग किए जाते हैं, क्योंकि वे वास्तव में एकमात्र तरीका है जिससे आप कई तरीकों से वापस लौट सकते हैं (यदि आपके पास क्लोजर का ढेर है तो कुछ ऐसा है जो आपको कभी-कभी करने की आवश्यकता होती है)।
रेक्स केर

18
@Rex Kerr, आप ब्रेक कंस्ट्रक्शन की कमजोरियों को इंगित कर रहे हैं (मैं उनसे सहमत नहीं हूँ), लेकिन फिर आप सामान्य वर्कफ़्लो के अपवादों का उपयोग करने का सुझाव देते हैं ! लूप से बाहर निकलना एक असाधारण मामला नहीं है, यह एल्गोरिथ्म का हिस्सा है, यह गैर-मौजूदा फ़ाइल (उदाहरण के लिए) पर लिखने का मामला नहीं है। तो संक्षेप में सुझाव दिया "इलाज" खुद "बीमारी" से भी बदतर है। और जब मैं breakableअनुभाग में एक वास्तविक अपवाद को फेंकने पर विचार करता हूं ... और उन सभी हुप्स सिर्फ बुराई से बचने के लिए break, हम्म ;-) आपको स्वीकार करना होगा, जीवन विडंबना है।
ग्रीनोल्डमैन

17
@macias - क्षमा करें, मेरी गलती है। JVM नियंत्रण प्रवाह के लिए थ्रॉवेबल्स का उपयोग कर रहा है। बेहतर? सिर्फ इसलिए कि वे आमतौर पर अपवाद हैंडलिंग का समर्थन करने के लिए उपयोग किए जाते हैं इसका मतलब यह नहीं है कि उनका उपयोग केवल अपवाद हैंडलिंग के लिए किया जा सकता है। एक बंद स्थान के भीतर से एक परिभाषित स्थान पर लौटना नियंत्रण प्रवाह के संदर्भ में एक अपवाद को फेंकने के समान है । कोई आश्चर्य नहीं, फिर, यह वह तंत्र है जिसका उपयोग किया जाता है।
रेक्स केर

14
@RexKerr खैर, इसके लायक यह है कि आपने मुझे आश्वस्त किया है। आम तौर पर मैं सामान्य प्रोग्राम प्रवाह के लिए अपवादों के खिलाफ एक से रेल करूंगा, लेकिन दो मुख्य कारण यहां लागू नहीं होते हैं। वे हैं: (1) वे धीमे हैं [इस तरह से उपयोग नहीं किए जाने पर], और (2) वे आपके कोड को पढ़ने वाले किसी व्यक्ति को असाधारण व्यवहार का सुझाव देते हैं [न कि यदि आपका पुस्तकालय आपको उन्हें कॉल करने देता है break] यदि यह एक जैसा दिखता है breakऔर यह प्रदर्शन करता है एक की तरह break, जहाँ तक मैं चिंतित हूँ यह एक है break
टिम गुडमैन

66

यह स्केल 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
क्या यह हुड के तहत अपवाद का उपयोग करता है?
माइक

यह स्कैला का उपयोग प्रक्रियात्मक भाषा के रूप में कार्यात्मक प्रोग्रामिंग लाभ (यानी पूंछ पुनरावृत्ति) की अनदेखी कर रहा है। सुंदर नहीं।
गेल्डर ज़ामरेनो

32
माइक: हाँ, स्काला लूप से बाहर निकलने के लिए एक अपवाद फेंक रहा है। गेल्डर: यह पोस्ट किए गए प्रश्न का उत्तर देता है "मैं स्कैला में एक लूप से कैसे टूटता हूं?"। यह 'सुंदर' है या नहीं प्रासंगिक नहीं है।
होहानुली

2
@ ह्होनौली, इसलिए यह कोशिश में है कि यह टूट न जाए, इसे रोकें?
ग्रीनल्डमैन

2
@ गेल्डर ज़ामरेनो इस मामले में पूंछ पुनरावृत्ति एक लाभ क्यों है? क्या यह केवल एक अनुकूलन नहीं है (जो नवागंतुक के लिए छिपा हुआ है और अनुभवी के लिए भ्रमित रूप से लागू होता है)। क्या इस उदाहरण में पूंछ पुनरावृत्ति के लिए कोई लाभ है?
user48956 16

32

फॉर-लूप को तोड़ना एक अच्छा विचार नहीं है। यदि आप फॉर-लूप का उपयोग कर रहे हैं तो इसका मतलब है कि आप जानते हैं कि आप कितनी बार पुनरावृति करना चाहते हैं। 2 शर्तों के साथ एक समय-लूप का उपयोग करें।

उदाहरण के लिए

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

2
यह मुझे लगता है कि स्काला में छोरों को तोड़ने का सही तरीका है। क्या इस जवाब में कुछ गलत है? (upvotes की कम संख्या पर विचार)।
जुस 12

1
वास्तव में सरल और अधिक पठनीय। यहां तक ​​कि ब्रेक करने योग्य - ब्रेक वाली बात सही है, यह बदसूरत दिखता है और आंतरिक ट्राइ-कैच में समस्या है। यद्यपि आपका समाधान एक फॉर्च्यूनर के साथ काम नहीं करता है, मैं आपको सादगी का सम्मान करते हुए वोट देगा।
यरिलबिल्बिन

13

रेक्स केर को दूसरे तरीके से जोड़ने के लिए:

  • (1 सी) आप अपने लूप में एक गार्ड का उपयोग कर सकते हैं:

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

30
मैंने इसे एक विकल्प के रूप में शामिल नहीं किया क्योंकि यह वास्तव में लूप को तोड़ता नहीं है - यह इस सब के माध्यम से चलता है, लेकिन अगर योग राशि के बाद प्रत्येक पुनरावृत्ति पर विफल रहता है तो यह पर्याप्त है, इसलिए यह केवल एक ही करता है यदि कथन हर बार काम के लायक। दुर्भाग्य से, आपने पाश कैसे लिखा है, इस पर निर्भर करता है कि बहुत काम हो सकता है।
रेक्स केर

@RexKerr: संकलक इसे वैसे भी ऑप्टिमाइज़ नहीं करेगा? यह पहले रन के दौरान नहीं तो JIT के दौरान अनुकूलित किया जाएगा।
मैकीज पीचोटका

5
@MaciejPiechotka - जेआईटी कंपाइलर में आमतौर पर यह समझने के लिए पर्याप्त परिष्कृत तर्क नहीं होता है कि एक बदलते चर पर एक बयान हमेशा (इस विशेष विशेष स्थिति में) झूठा वापस आएगा और इस तरह छोड़ा जा सकता है।
रेक्स केर

6

चूँकि breakअभी तक स्काला में कोई नहीं है, आप एक समस्या का उपयोग करके इस समस्या को हल करने का प्रयास कर सकते हैं return। इसलिए आपको अपने आंतरिक लूप को एक फ़ंक्शन में रखना होगा, अन्यथा रिटर्न पूरे लूप को छोड़ देगा।

स्काला 2.8 में हालांकि तोड़ने का एक तरीका शामिल है

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


क्षमा करें, लेकिन मैं केवल आंतरिक पाश को तोड़ना चाहता था। आप यह नहीं कह रहे हैं कि मुझे इसे एक समारोह में रखना चाहिए?
TiansHUo

क्षमा करें, यह स्पष्ट करना चाहिए था। सुनिश्चित करें कि रिटर्न का उपयोग करने का मतलब है कि आपको किसी फ़ंक्शन में लूप को एन्कोड करना होगा। मैंने अपना उत्तर संपादित कर दिया है।
हाम Vocke

1
यह बिल्कुल अच्छा नहीं है। ऐसा लगता है कि स्काला नेस्टेड छोरों को पसंद नहीं करता है।
तियांसुओ

वहाँ एक अलग तरीका नहीं लगता है। : आपको यह देखने के लिए चाहते हो सकता है scala-lang.org/node/257
हाम Vocke

4
@TiansHUo: आप यह क्यों कहते हैं कि स्काला को नेस्टेड लूप पसंद नहीं है ? आप एक ही मुद्दे हैं अगर आप एक से बाहर तोड़ने की कोशिश कर रहे हैं ही लूप से ।
रेक्स केर


5

बस थोड़ी देर के लूप का उपयोग करें:

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

5

एक दृष्टिकोण जो एक सीमा पर मूल्यों को उत्पन्न करता है जैसा कि हम पुनरावृति करते हैं, एक Iteratorटूटी हुई स्थिति तक, इसके बजाय एक पूरी श्रृंखला पहले उत्पन्न करते हैं और फिर उस पर पुनरावृत्ति करते हैं, का उपयोग करते हुए , (@RexKerr उपयोग में प्रेरित Stream)

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

हाँ मुझे यह पसंद है। कोई टूटने-बहाना नहीं, मुझे लगता है कि यह अच्छा लग रहा है।
Ses

4

यहाँ एक पूंछ पुनरावर्ती संस्करण है। की तुलना में समझने की तुलना में यह थोड़ा सा गूढ़ है, माना जाता है, लेकिन मैं कहूंगा कि इसके कार्य :)

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 है। यदि आप मेरे संस्करण को अनुकूलित करने का तरीका जानते हैं तो आपका स्वागत है।


2

आपके समाधान के करीब यह होगा:

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)

J- पुनरावृति को एक नए दायरे के बिना बनाया गया है, और उत्पाद-पीढ़ी के साथ-साथ हालत फॉर-स्टेटमेंट में किए गए हैं (एक अच्छी अभिव्यक्ति नहीं है - मुझे बेहतर नहीं मिला)। हालत उलट है जो कि समस्या के आकार के लिए बहुत तेज है - शायद आप बड़े छोरों के लिए एक ब्रेक के साथ कुछ हासिल करते हैं।

String.reverse का तात्पर्य रिचस्ट्रिंग से है, यही वजह है कि मैं 2 अतिरिक्त उलटफेर करता हूं। :) अधिक गणितीय दृष्टिकोण अधिक सुरुचिपूर्ण हो सकता है।


2

तृतीय-पक्ष breakableपैकेज एक संभव विकल्प है

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))

2
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.
   }
}

ब्रेक क्लास का उपयोग करके लूप को तोड़ने की मूल विधि। लूप को ब्रेक करने योग्य घोषित करके।


2

बस हम स्काला में कर सकते हैं

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

1

विडंबना यह है कि स्कैला ब्रेक scala.util.control.Breaksएक अपवाद है:

def break(): Nothing = { throw breakException }

सबसे अच्छी सलाह है: ब्रेक का उपयोग न करें, जारी रखें और गोटो! IMO वे एक ही, बुरे व्यवहार और सभी प्रकार की समस्याओं (और गर्म चर्चाओं) का एक बुरा स्रोत हैं और अंत में "हानिकारक माने जाते हैं"। कोड ब्लॉक संरचित, इस उदाहरण में भी विराम अतिशयोक्तिपूर्ण हैं। हमारे एद्जर डब्ल्यू। दिक्जस्त्र: ने लिखा:

प्रोग्रामर की गुणवत्ता उनके द्वारा उत्पादित कार्यक्रमों में बयानों में जाने के घनत्व का घटता कार्य है।


1

मुझे नीचे दिए गए कोड जैसी स्थिति मिली

 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}
    }
  }

मैं एक जावा लिब का उपयोग कर रहा हूं और तंत्र यह है कि ctx.read एक अपवाद को फेंक दें जब वह कुछ भी नहीं पा सकता है। मैं इस स्थिति में फंस गया था कि: एक अपवाद को फेंकने पर मुझे लूप को तोड़ना होगा, लेकिन scala.util.control.Breaks.break लूप को तोड़ने के लिए अपवाद का उपयोग कर रहा है, और यह इस तरह पकड़ा गया था कि पकड़ ब्लॉक में था।

मुझे इसे हल करने के लिए बदसूरत तरीका मिला: पहली बार लूप करें और वास्तविक लंबाई की गिनती प्राप्त करें। और इसका उपयोग दूसरे लूप के लिए करें।

Scala से विराम लेना अच्छा नहीं है, जब आप कुछ जावा लिब का उपयोग कर रहे हैं।


1

मैं स्काला के लिए नया हूं, लेकिन अपवादों और दोहराए जाने के तरीकों से बचने के लिए यह कैसे होता है:

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)
});

1

findसंग्रह के लिए विधि का चतुर उपयोग आपके लिए चाल चलेगा।

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)

1

नीचे एक सरल तरीके से एक लूप को तोड़ने के लिए कोड है

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"

        }
      }
    }
  }
}

1

मुझे नहीं पता कि पिछले 9 वर्षों में स्काला शैली में कितना बदलाव आया है, लेकिन मुझे यह दिलचस्प लगा कि अधिकांश मौजूदा उत्तर vars, या पुनरावृत्ति को पढ़ने के लिए कठिन हैं। जल्दी बाहर निकलने की कुंजी अपने संभावित उम्मीदवारों को उत्पन्न करने के लिए एक आलसी संग्रह का उपयोग करना है, फिर अलग से स्थिति की जांच करें। उत्पादों को उत्पन्न करने के लिए:

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

आपका मूल कोड वास्तव में पहले palindrome के लिए जाँच कर रहा है जो बाद के उत्पाद से बड़ा है, जो कि पहले palindrome के लिए एक अजीब सीमा स्थिति को छोड़कर जाँच के समान है जो मुझे नहीं लगता कि आपका इरादा है। उत्पाद सख्ती से नीरस रूप से कम नहीं हो रहे हैं। उदाहरण के लिए, 998*998से अधिक है 999*997, लेकिन लूप में बहुत बाद में दिखाई देता है।

वैसे भी, अलग-अलग आलसी पीढ़ी और हालत की जांच का लाभ यह है कि आप इसे बहुत पसंद करते हैं जैसे कि यह पूरी सूची का उपयोग कर रहा है, लेकिन यह केवल उतना ही उत्पन्न करता है जितनी आपकी आवश्यकता है। आप दोनों दुनियाओं में से सबसे अच्छा पाने के लिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.