2012-11-16 29 views
10

वहाँ एल्गोरिथ्म का एक अच्छा कार्यान्वयन सी ++ एसटीएल में घुमाव के दो श्रृंखलाओं में से गणना (या यहाँ तक को बढ़ावा देने) के लिए है? यानी प्रोटोटाइप के साथ कुछ (दो पर्वतमाला a..b और c..d के घुमाव के):C++ एसटीएल घुमाव के

template< class Iterator > 
void convolution(Iterator a, Iterator b, Iterator c, Iterator d); 

जो संशोधित करता a..b रेंज

+0

यह एक लिखने के लिए मुश्किल नहीं है:

#include <tuple> namespace algo { template <typename... T> void dummy(T...) { } template <typename To, typename InIt, typename... It> To zip(To to, InIt it, InIt end, It... its) { for (; it != end; ++it, ++to) { *to = std::make_tuple(*it, *its...); algo::dummy(++its...); } return to; } } 

नीचे एक साधारण परीक्षण कार्यक्रम मुझे लगता है कि इसके बाद के संस्करण की पुष्टि करने के लिए प्रयोग किया जाता है मुझे क्या करना यह इरादा है: यहाँ एक इसी zip() एल्गोरिदम के एक कार्यान्वयन है जो शुरू में शून्य से भरा तीसरी रेंज में जोड़ता है। जगह में, मुझे नहीं पता। – aschepler

+0

मान लीजिए कि यह एक अलग संकल्प होगा जहां श्रेणियां एक ही लंबाई लिख रही हैं, यह बहुत कठिन नहीं है - यह काफी बदलाव के समान होगा। असल में, आप रिवर्स इटरेटर के तीसरे पैरामीटर के साथ ऐसा करने के लिए ट्रांसफॉर्म का उपयोग करने में भी सक्षम हो सकते हैं। – Yuushi

उत्तर

1

हाँ std :: बदलने

std::transform(a, b, c, a, Op); 

// a b is the the first input range 
// c is the start of the second range (which must be at least as large as (b-a) 
// 
// We then use a as the output iterator as well. 

// Op is a BinaryFunction 

कैसे प्रदर्शन करने के लिए पर टिप्पणी का उत्तर देने के टिप्पणियों में राज्य का संचय:

struct Operator 
{ 
    State& state; 
    Operator(Sate& state) : state(state) {} 
    Type operator()(TypeR1 const& r1Value, TypeR2 const& r2Value) const 
    { 
     Plop(state, r1Value, r2Value); 
     return Convolute(state, r2Value, r2Value); 
    } 
}; 
State theState = 0; 
Operator Op(theState); 
+3

ऐसा लगता है कि प्रत्येक एसटीएल एल्गोरिदम में किसी प्रकार का एक लूप होता है। इसलिए, सबसे अधिक संभावना है कि न केवल एक एसटीएल एल्गोरिदम समस्या का समाधान व्यक्त करता है लेकिन संयोजन (यानी 'std :: inner_product' और' std :: transform') कर सकते हैं। – Orient

+0

मुझे नहीं लगता कि 'ओप' आंतरिक रूप से एक बड़े अस्थायी कंटेनर के निर्माण के बिना सभी ओ (एन^2) उत्पाद शर्तों को कैसे जमा कर सकता है। –

+0

@j_random_hacker: यह आसान है ओप एक मजेदार है। –

2

मुझे पूरा यकीन नहीं है कि दो अनुक्रमों में से एक "संकल्प" इन दो अनुक्रमों में से एक है: यह मेरी समझ से अलग समझ प्रतीत होता है। नीचे इटरेटर की एक चर संख्या का उपयोग कर convolution का एक संस्करण है। क्योंकि मैं वास्तव में अभी बहुत आलसी हूं, मैं गंतव्य पुनरावर्तक को अंतिम तर्क के बजाए पहले तर्क के रूप में पारित करने की कुछ असामान्य धारणा का उपयोग करूंगा।

#include <deque> 
#include <iostream> 
#include <iterator> 
#include <list> 
#include <vector> 

enum class e { a = 'a', b = 'b', c = 'c' }; 

std::ostream& operator<< (std::ostream& out, 
          std::tuple<int, double, e> const& v) 
{ 
    return out << "[" 
       << std::get<0>(v) << ", " 
       << std::get<1>(v) << ", " 
       << char(std::get<2>(v)) << "]"; 
} 

int main() 
{ 
    typedef std::tuple<int, double, e> tuple; 
    std::vector<int> v{ 1, 2, 3 }; 
    std::deque<double> d{ 1.1, 2.2, 3.3 }; 
    std::list<e>  l{ e::a, e::b, e::c }; 
    std::vector<tuple> r; 

    algo::zip(std::back_inserter(r), v.begin(), v.end(), d.begin(), l.begin()); 

    std::copy(r.begin(), r.end(), 
       std::ostream_iterator<tuple>(std::cout, "\n")); 
}           
+0

थोड़ा और टेम्पलेट कोड के साथ, आप यह भी सुनिश्चित कर सकते हैं कि विविध रूप से उत्तीर्ण इटरेटर मिलान की लंबाई, बशर्ते आप ज़िप ज़िप (आउटआईटी, इनआईटी, इनआईटपैक ...) और इनआईटपैक में तर्क जोड़े (* नहीं * std: : जोड़ी )। हालांकि, यह कोड की लगभग 150 लाइनें है, मुख्य रूप से सहायक कार्यों के लिए रिकर्सिव टेम्पलेट्स के अनावश्यक उपयोग के कारण। – moshbear