2010-10-07 23 views
33

का उपयोग कर स्केलर वैल्यू द्वारा वेक्टर तत्वों को गुणा करें हाय मैं स्केलर वैल्यू द्वारा myv1 * 3 के लिए वेक्टर (गुणा, जोड़, आदि) वेक्टर बनाना चाहता हूं, मुझे पता है कि मैं फ़ोरलोप के साथ एक फ़ंक्शन कर सकता हूं, लेकिन ऐसा करने का कोई तरीका है एसटीएल समारोह का उपयोग कर? {Algorithm.h :: ट्रांसफॉर्म फ़ंक्शन} की तरह कुछ?एसटीएल

उत्तर

73

हाँ, std::transform का उपयोग कर:

std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
       std::bind1st(std::multiplies<T>(),3)); 
+0

बहुत बहुत धन्यवाद कि प्रतिभा है !! –

21

यदि आप vector के बजाय valarray का उपयोग कर सकते हैं, तो इसमें स्केलर गुणा करने के लिए बिल्टिन ऑपरेटर हैं।

v *= 3; 

आप एक vector उपयोग करने के लिए है, तो आप वास्तव में transform उपयोग कर सकते हैं काम करने के लिए:

transform(v.begin(), v.end(), v.begin(), _1 * 3); 

(यह मानते हुए कि आप Boost.Lambda के लिए इसी तरह कुछ है कि आप आसानी से गुमनाम समारोह वस्तुओं की तरह बनाने की अनुमति देता है _1 * 3 :-P)

+1

वैलेरा सही समाधान आईएमओ हैं। भाग्य के साथ, आपका कार्यान्वयन प्रक्रिया को लागू करने के लिए एसएसई निर्देशों का उपयोग करता है, जिससे इसे काफी तेज बना दिया जाता है। Valarray के इस तरह के कार्यान्वयन के लिए http://www.pixelglow.com/macstl/valarray/ देखें। दुर्भाग्यवश, यह बहुत व्यापक नहीं है, इसलिए यदि आप एसएसई निर्देशों के फायदे चाहते हैं तो आपको शायद कंपाइलर इंट्रिनिक्स का उपयोग करना होगा ... – Dragontamer5788

+0

@ ड्रैगन: 'वालराय' सर्वश्रेष्ठ एसटीएल समाधान है, लेकिन यह उच्च प्रदर्शन के लिए बहुत अच्छा नहीं है कंप्यूटिंग क्योंकि यह स्मृति में डेटा को बहुत प्रतिलिपि बनाता है, और छोटे लूपों के अनुक्रम उत्पन्न करता है जिसमें सिंगल ऑपरेशंस होते हैं जिनमें खराब मेमोरी एक्सेस पैटर्न होते हैं। यद्यपि 'Valarray' से उचित अभिव्यक्ति टेम्पलेट सिस्टम में अपग्रेड करना आसान है। – Potatoswatter

0

बस: यदि आपके पास एक निश्चित आकार सरणी (फ्लोट वैल्यू [एन]) में आपका डेटा हो सकता है तो आप इसे तेजी से बनाने के लिए एसएसई इंट्रिनिक्स का उपयोग कर सकते हैं क्योंकि यह एक समय (4) को घुमाएगा।

0

मुझे पता है कि यह एसटीएल नहीं है जैसा आप चाहते हैं, लेकिन यह कुछ है जो आप अलग-अलग ज़रूरतों के अनुरूप अनुकूलित कर सकते हैं।

नीचे एक टेम्पलेट है जिसका उपयोग आप गणना के लिए कर सकते हैं; 'func' वह कार्य होगा जो आप करना चाहते हैं: गुणा करें, जोड़ें, और इसी तरह; 'फर्म' 'func' का दूसरा पैरामीटर है। आप अलग-अलग प्रकार के अधिक पैरा के साथ अलग-अलग func को लेने के लिए आसानी से इसका विस्तार कर सकते हैं।

template<typename _ITStart, typename _ITEnd, typename _Func , typename _Value > 
_ITStart xform(_ITStart its, _ITEnd ite, _Func func, _Value parm) 
{ 
    while (its != ite) { *its = func(*its, parm); its++; } 
    return its; 
} 
... 

int mul(int a, int b) { return a*b; } 

vector<int> v; 

xform(v.begin(), v.end(), mul, 3); /* will multiply each element of v by 3 */ 

इसके अलावा, यह 'सुरक्षित' फ़ंक्शन नहीं है, आपको इसका उपयोग करने से पहले टाइप/वैल्यू-चेकिंग आदि करना होगा।

+0

यह काम करता है, लेकिन अनिवार्य रूप से पहिया को फिर से शुरू कर रहा है, क्योंकि 'std :: transform' पहले से ही आपके लिए यह करता है। –

+0

हां - स्वीकार्य उत्तर में देखा गया ... लेकिन क्या आपको एहसास है कि वास्तव में काम करने वाले पहिये को फिर से शुरू करना कितना खुशी है;) वैसे भी मैं खुद को एक दिन के अनुरूप बना दूंगा;) – slashmais

0

मुझे लगता है कि for_each बहुत उपयुक्त है, जब आप इस मामले में एक सरल लैम्ब्डा पर्याप्त होगा एक वेक्टर पार और कुछ पैटर्न के अनुसार प्रत्येक तत्व में हेरफेर करना चाहते हैं,:

std::for_each(myv1.begin(), mtv1.end(), [](int &el){el *= 3; }); 

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

+0

यह ' std :: for_each'। 'std :: for_each' कुछ (शायद राज्यव्यापी) फ़ंक्शन ऑब्जेक्ट को किसी श्रेणी पर लागू करता है और फिर इस फ़ंक्शन ऑब्जेक्ट को देता है। यदि आप अपना इरादा अधिक स्पष्ट करने के लिए 'std :: transform' श्रेणी का उपयोग करना चाहते हैं। – sv90