2011-08-07 10 views
13

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

अब, मैं अक्सर स्काला में कुछ एल्गोरिदम में sliding उपयोग करें, लेकिन मुझे लगता है कि यह आम तौर पर बहुत दूर-एक करके त्रुटियों के लिए कुछ इसी तरह का परिणाम है, क्योंकि आकार n का एक संग्रह में एक m की sliding तत्वों आकार की है n - m + 1 तत्व। या, अधिक मामूली रूप से, list sliding 2list से छोटा एक तत्व है।

मुझे लगता है कि इस पैटर्न में एक गायब अमूर्तता है, जो कुछ sliding भाग होगा, कुछ और हिस्सा - जैसे foldLeftreduceLeft है। मैं नहीं सोच सकता कि यह क्या हो सकता है। क्या कोई मुझे यहां ज्ञान प्राप्त करने में मदद कर सकता है?

अद्यतन

के बाद से लोगों को स्पष्ट एक मैं क्या बात कर रहा हूँ नहीं कर रहे हैं, चलो इस मामले पर विचार करें। मैं एक स्ट्रिंग को कैपिटल बनाना चाहता हूं। असल में, प्रत्येक पत्र जो किसी पत्र से पहले नहीं है, ऊपरी मामला होना चाहिए, और अन्य सभी अक्षरों को कम मामला होना चाहिए। sliding का उपयोग करके, मुझे विशेष मामला या तो पहला या अंतिम अक्षर होना चाहिए। उदाहरण के लिए:

def capitalize(s: String) = s(0).toUpper +: s.toSeq.sliding(2).map { 
    case Seq(c1, c2) if c2.isLetter => if (c1.isLetter) c2.toLower else c2.toUpper 
    case Seq(_, x) => x 
}.mkString 
+0

दिलचस्प ... अपने विशिष्ट उदाहरण एक राज्य मशीन की तरह मेरे लिए लग रहा है उचित होगा (आप में संक्षेप में उन कर सकते हैं स्कैला?), और यदि आप 'स्लाइडिंग' की कुछ कार्यक्षमता चाहते हैं तो आप आगे भी देखना चाहते हैं - यह एक पार्सर की तरह लगना शुरू हो जाता है। इसका मतलब यह भी है कि मुझे आपके प्रश्न का उत्तर देने के लिए पर्याप्त जानकारी नहीं है :) (मैंने जो छोटे से पढ़ा है, उसे लगता है जैसे यह एक इटारेटी-जैसी पैटर्न की मदद कर सकता है, इसलिए आप इसे देख सकते हैं, लेकिन मुझे वास्तव में कोई जानकारी नहीं है)। – Owen

+0

या शायद यह कहने का तरीका यह है कि आपको पहले एक विशेष मामला बनाना होगा क्योंकि यह * एक विशेष मामला है, यानी यह एक टोकन होना अच्छा होगा जो स्ट्रिंग की शुरुआत का प्रतिनिधित्व करता है, जो इस ध्वनि को भी बनाता है एक राज्य मशीन/पार्सर की तरह अधिक। – Owen

+0

मैं ओवेन से सहमत हूं: समस्या विशेष मामलों का पहला चरित्र वर्णन करती है, इसलिए कोड को भी आवश्यकता होती है। यहां बताया गया है कि मैंने समस्या कथन कैसे पढ़ा: "प्रत्येक चरित्र को अपरकेस करें यदि यह (ए) पहला अक्षर है, या (बी) एक अक्षर वर्ण का पालन करता है"। पहले चरित्र के लिए व्यवहार विशेष रूप से परिभाषित किया जाना चाहिए। –

उत्तर

2

मैं इस समस्या में अजगर/आर/Matlab में हर समय चलाने के तुम कहाँ diff() एक वेक्टर और फिर इसे लाइन अप नहीं कर सकते मूल एक साथ! यह बहुत निराशाजनक है।

मुझे लगता है कि क्या वास्तव में लापता है कि वेक्टर केवल निर्भर चर पकड़ है, और मानता है कि आप, प्रोग्रामर,, स्वतंत्र चर का ट्रैक रख रहे हैं आयाम है कि संग्रह से अधिक पर्वतमाला अर्थात्।

मुझे लगता है कि इसे हल करने का तरीका कुछ डिग्री के लिए भाषा स्वतंत्र चर का ट्रैक रखना है; शायद वेक्टर के साथ उन्हें भंडारित करके, या गतिशील रूप से प्रकार के माध्यम से स्थिर रूप से। फिर यह स्वतंत्र अक्षों की जांच कर सकता है, सुनिश्चित करें कि वे लाइन अप करें, या, मुझे नहीं पता कि यह संभव है या नहीं, पर चीजों को घुमाएं उन्हें लाइन अप करें।

यह अब तक का सबसे अच्छा विचार है।

संपादित

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

संपादित

एक और परिणाम यह होगा कि sliding तरह परिवर्तनों वास्तव में दो परिवर्तनों, आश्रित चरों के लिए, और उनके अक्ष के लिए एक प्रतिनिधित्व करते हैं।

6

मैं ओवेन की answer को इसकी प्रेरणा के रूप में ले रहा हूं।

जब आप किसी सूची में एक साधारण diff() लागू करना चाहते हैं, तो इसे निम्न मैट्रिक्स गुणा के बराबर के रूप में देखा जा सकता है।

a = (0 1 4 3).T 

M = (1 -1 0 0) 
    (0 1 -1 0) 
    (0 0 1 -1) 

diff(a) = M * a = (1 3 1).T 

अब हम सामान्य सूची के संचालन के लिए एक ही योजना का उपयोग कर सकते है अगर हम इसके अलावा और गुणा की जगह (और यदि हम अपने मैट्रिक्स एम में संख्या सामान्यीकरण)।

तो, प्लस (बाद में flatten साथ - या बस एक collect आपरेशन) किया जा रहा है एक सूची संलग्न संचालन के साथ, और गुणक बराबर किया जा रहा है या तो Some(_) या None, दो की एक खिड़की के आकार के साथ एक स्लाइड हो जाता है:

M = (Some(_) Some(_) None None) 
    (None Some(_) Some(_) None) 
    (None None Some(_) Some(_)) 

slide(a) = M “*” a = ((0 1) (1 4) (4 3)).T 

सुनिश्चित नहीं है, अगर यह उस तरह का अमूर्तता है जिसे आप ढूंढ रहे हैं, लेकिन यह संचालन की कक्षा पर एक सामान्यीकरण होगा जो वस्तुओं की संख्या को बदलता है।

diff या slide लंबाई n के इनपुट के लिए आदेश मीटर के संचालन आकार n-मीटर + 1 × n के matrixes उपयोग करने के लिए की आवश्यकता होगी।


संपादित करें: एक समाधान (slideLeft या slideRight) None के साथ इन पहले जोड़ें या संलग्न करने के लिए List[Some[A]] को List[A] को बदलने के लिए हो सकता है और उसके बाद। इस तरह आप map विधि के अंदर सभी जादू को संभाल सकते हैं।

list.slideLeft(2) { 
    case Seq(Some(c1), Some(c2)) if c2.isLetter => if (c1.isLetter) c2.toLower else c2.toUpper 
    case Seq(_, Some(x)) => x 
} 
+0

बहुत अच्छा है, हालांकि यह वही नहीं है जो मैं चाहता हूं। मैं वस्तुओं की संख्या में समस्या को बदलने के लिए विचार करता हूं - यह असाधारण मामले के रूप में पहले या अंतिम तत्व को उजागर करता है। –

1

बंद-एक करके त्रुटियों सुझाव है कि आप एक-से-एक पत्राचार में फिसलने की सूची के साथ मूल सूची डाल करने के लिए कोशिश कर रहे हैं, लेकिन कुछ अजीब, पर जा रहा है के बाद से फिसलने सूची कम तत्व है।

आपके उदाहरण के लिए समस्या विवरण को लगभग इस तरह वाक्यांशित किया जा सकता है: "प्रत्येक चरित्र को अपरकेस करें यदि यह (ए) पहला अक्षर है, या (बी) एक अक्षर वर्ण का पालन करता है"। ओवेन अंक के रूप में, पहला चरित्र एक विशेष मामला है, और किसी भी अमूर्तता का सम्मान करना चाहिए। यहाँ एक संभावना,

def slidingPairMap[A, B](s: List[A], f1: A => B, f2: (A, A) => B): List[B] = s match { 
    case Nil => Nil 
    case x :: _ => f1(x) +: s.sliding(2).toList.map { case List(x, y) => f2(x, y) } 
} 

है (नहीं सबसे अच्छा कार्यान्वयन, लेकिन आप अंदाजा हो)। यह ट्रिपल को स्लाइड करने के लिए सामान्यीकृत करता है, दो-दो त्रुटियों के साथ, और इसी तरह। slidingPairMap का प्रकार यह स्पष्ट करता है कि विशेष आवरण किया जा रहा है।

एक बराबर हस्ताक्षर हो सकता है

def slidingPairMap[A, B](s: List[A], f: Either[A, (A, A)] => B): List[B] 

फिर f अगर यह, पहला तत्व के साथ काम कर रहा है या बाद में एक एक के साथ यह पता लगाने की मिलान पैटर्न का उपयोग कर सकते हैं।


या, जैसा कि ओवेन टिप्पणी में कहते हैं, यही कारण है कि एक संशोधित sliding विधि के बारे में है कि क्या पहले तत्व है या नहीं जानकारी देता है नहीं,

def slidingPairs[A](s: List[A]): List[Either[A, (A, A)]] 

मुझे लगता है कि यह पिछले विचार करने के लिए है isomorphic क्या डेबिलस्की टिप्पणियों में सुझाव देता है: किसी भी सूची के साथ सूची की शुरुआत पैड Some के साथ सभी मौजूदा तत्वों को लपेटें, और फिर sliding पर कॉल करें।

+1

अच्छा। या शायद मूल रूप से एक ही काम करने का एक और तरीका एक प्रारंभिक परिवर्तन लागू करना होगा जो प्रत्येक तत्व को 'प्रथम चर' पर ले जाता है NotFirst Char Char', तो कॉलर उस पर पैटर्न-मिलान कर सकता था। – Owen

+0

कि 'स्लाइडिंगपेयरमैप' एक 'गुना' (एक कैटोमोर्फिज्म) जैसा दिखता है। मुझे संदेह है कि जो कुछ भी मैं चाहता हूं वह वास्तव में है। –

1

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

इन फिसलने के लिए संपर्क किया से उधार एक अमूर्त जो एक समस्या द्वारा बंद का प्रदर्शन नहीं करता करने के लिए नेतृत्व करेंगे:

(1::2::3::Nil).sliding(2) 

(1,2), (2,3), (3,1) 
परिपत्र सीमा की स्थिति के लिए

और

(1,2), (2,3), (3,2) 
प्राप्त होते हैं

रिवर्सल के साथ परिपत्र सीमा स्थितियों के लिए।

0

मैं Some(_) तत्वों के साथ मानचित्रण के बाद कोई भी प्रीपेड नहीं करूंगा; ध्यान दें कि यह ऐसा करने का स्पष्ट तरीका है (डिफ़ॉल्ट के मामले में दो Some के लिए मिलान, के रूप में Debilski द्वारा संपादित में किया) के रूप में हम भी पहले अक्षर को संशोधित करने में सक्षम होना चाहिए गलत है,। इस तरह, अमूर्तता इस तथ्य का सम्मान करती है कि कभी-कभी कोई पूर्ववर्ती नहीं होता है। getOrElse(false) का उपयोग करना सुनिश्चित करता है कि एक लापता पूर्ववर्ती को परीक्षण में असफल होने के रूप में माना जाता है।

((None +: "foo1bar".toSeq.map(Some(_))) sliding 2).map { 
    case Seq(c1Opt, Some(c2)) if c2.isLetter => if (c1Opt.map(_.isLetter).getOrElse(false)) c2.toLower else c2.toUpper 
    case Seq(_, Some(x)) => x 
}.mkString 
res13: String = "Foo1Bar" 

स्वीकृतियाँ: Some(_) साथ तत्वों मानचित्रण के विचार Debilski पद के माध्यम से मेरे लिए आया था।

2

आपके उदाहरण में, मुझे लगता है कि कोड अधिक जटिल बना दिया गया है, क्योंकि आप मूल रूप से map करना चाहते हैं लेकिन sliding के साथ काम करना चाहते हैं जो किनारे की स्थिति को अच्छी तरह से काम नहीं करता है। मुझे लगता है कि एक गुना एक संचायक के साथ छोड़ दिया है कि प्रासंगिक राज्य याद है आसान धारणात्मक हो सकता है:

def capitalize2(s: String) = (("", true) /: s){ case ((res, notLetter), c) => 
    (res + (if (notLetter) c.toUpper else c.toLower), !c.isLetter) 
}._1 

मुझे लगता है कि इस सामान्यीकृत किया जा सकता है, ताकि notLettern तत्वों जहां n फिसलने विंडो के आकार है याद कर सकते हैं।

2

परिवर्तन आप स्वाभाविक के लिए पूछ रहे हैं डेटा का आकार कम कर देता है। क्षमा करें - इसे देखने का कोई और तरीका नहीं है। tail आपको एक-एक-एक त्रुटियां भी देता है।

अब, आप कह सकते हैं - ठीक है, ठीक है, लेकिन मैं मूल आकार को बनाए रखने के लिए एक सुविधाजनक तरीका चाहता हूं।

उस मामले में, आप List पर इन तरीकों चाहते हो सकता है:

initializedSliding(init: List[A]) = (init ::: this).sliding(1 + init.length) 
finalizedSliding(tail: List[A]) = (this ::: tail).sliding(1 + tail.length) 

जो अपनी सूची की लंबाई को बनाए रखेगा। (आप कल्पना कर सकते हैं कि गैर-सूचियों को सामान्यीकृत करने के लिए, मुझे यकीन है।)

यह बाएं/दाएं को गुना करने के लिए एनालॉग है जिसमें आप एक जोड़ी (या अधिक) ऑपरेशन करने के लिए अनुपलब्ध डेटा की आपूर्ति करते हैं सूची के हर तत्व।

0

मुझे यकीन नहीं है कि यह आपकी ठोस समस्या हल करता है, लेकिन हम आसानी से तरीकों की एक जोड़ी की कल्पना कर सकते हैं उदा।slidingFromLeft(z: A, size: Int) और slidingToRight(z: A, size: Int) (जहां ए संग्रह का तत्व प्रकार है), जिसे, उदा।

List(1, 2, 3, 4, 5) 

तर्कों के साथ उदा। (0, 3), प्रस्तुत करना चाहिए क्रमशः

List(0, 0, 1), List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5) 

और

List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 0), List(5, 0, 0) 
0

यह समस्या मूल रूप से जे की तरह एक सरणी उन्मुख कार्यात्मक भाषा के लिए अच्छी तरह से अनुकूल की तरह है, हम साथ एक बूलियन उत्पन्न प्रत्येक शब्द के पहले अक्षर से संबंधित एक। ऐसा करने के लिए, हम एक स्ट्रिंग में रिक्त स्थान चिह्नित करने वाले बुलियन के साथ शुरू करते हैं। उदाहरण के लिए (लाइनों दांतेदार तीन रिक्त स्थान आदानों कर रहे हैं; परिणाम बाईं मार्जिन के साथ बहा रहे हैं, "NB." एक टिप्पणी शुरू होता है):

str=. 'now is the time' NB. Example w/extra spaces for interest 
    ]whspc=. ' '=str    NB. Mark where spaces are=1 
0 0 0 1 1 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 

कि (*.-.) सत्यापित करें ("और नहीं") केवल "1 0" के लिए एक रिटर्न:

]tt=. #:i.4      NB. Truth table 
0 0 
0 1 
1 0 
1 1 
    (*.-.)/"1 tt     NB. Apply to 1-D sub-arrays (rows) 
0 0 1 0       NB. As hoped. 

स्लाइड बूलियन में जोड़े भर में हमारे मौन समारोह:

2(*.-.)/\whspc     NB. Apply to 2-ples 
0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 

लेकिन इस प्रारंभिक पत्र के किनारे हालत प्रबंधन नहीं करती है, तो एक एक पूर्णांक के लिए मजबूर ओ पहली स्थिति। यह वास्तव में मदद करता है क्योंकि 2-प्लेस की कमी ने हमें एक छोटा छोड़ दिया।

#whspc 
20 
    #1,2(*.-.)/\whspc 
20 
    1,2(*.-.)/\whspc 
1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 

हम अपरकेस लोअरकेस वेक्टर में सूचकांक का उपयोग करके अपरकेस वेक्टर से चयन करने के लिए (इन दोनों वैक्टर को परिभाषित करने के बाद) मिलता है:

'lc uc'=. 'abcdefghijklmnopqrstuvwxyz';'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 
    (uc,' '){~lc i. str 
NOW IS THE TIME 
यहाँ हम मूल बूलियन की लंबाई और लक्ष्य बूलियन तुलना

 (1,2(*.-.)/\whspc) } str,:(uc,' '){~lc i. str 
Now Is The Time 

अब समय एक बयान में यह सब गठबंधन करने के लिए है:

बूलियन द्वारा कि प्रविष्टि की जाँच सही परिणाम देता है

(1,2(*.-.)/\' '=str) } str,:(uc,' '){~lc i. str 
Now Is The Time 
1

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

def slidingFoldLeft[A, B] (seq: Seq[A], window: Int)(acc: B)(
    f: (B, Seq[A]) => B): B = { 
    if (window > 0) { 
    val iter = seq.sliding(window) 
    iter.foldLeft(acc){ 
     // Operate normally 
     case (acc, next) if iter.hasNext => f(acc, next) 
     // It's at the last <window> elements of the seq, handle current case and 
     // call recursively with smaller window 
     case (acc, next) => 
     slidingFoldLeft(next.tail, window - 1)(f(acc, next))(f) 
    } 
    } else acc 
} 

def capitalizeAndQuestionIncredulously(s: String) = 
    slidingFoldLeft(s.toSeq, 2)("" + s(0).toUpper) { 
    // Normal iteration 
    case (acc, Seq(c1, c2)) if c1.isLetter && c2.isLetter => acc + c2.toLower 
    case (acc, Seq(_, c2)) if c2.isLetter    => acc + c2.toUpper 
    case (acc, Seq(_, c2))        => acc + c2 
    // Last element of string 
    case (acc, Seq(c)) => acc + "?!" 
    } 

def capitalizeAndInterruptAndQuestionIncredulously(s: String) = 
    slidingFoldLeft(s.toSeq, 3)("" + s(0).toUpper) { 
    // Normal iteration 
    case (acc, Seq(c1, c2, _)) if c1.isLetter && c2.isLetter => acc + c2.toLower 
    case (acc, Seq(_, c2, _)) if c2.isLetter    => acc + c2.toUpper 
    case (acc, Seq(_, c2, _))        => acc + c2 
    // Last two elements of string 
    case (acc, Seq(c1, c2)) => acc + " (commercial break) " + c2 
    // Last element of string 
    case (acc, Seq(c)) => acc + "?!" 
    } 

println(capitalizeAndQuestionIncredulously("hello my name is mAtthew")) 
println(capitalizeAndInterruptAndQuestionIncredulously("hello my name is mAtthew")) 

और उत्पादन:: यहाँ कार्यान्वयन और कुछ मूर्ख उदाहरण है

Hello My Name Is Matthew?! 
Hello My Name Is Matthe (commercial break) w?! 
संबंधित मुद्दे