kullanarak skaler bir değerle çarpma vektör elemanları Merhaba Ica (çarpma, ekleme, vb) vektörü skaler değere göre myv1 * 3
olarak istiyorum, biliyorum bir forloop ile bir işlev yapabilirim, ancak bunu yapmanın bir yolu var mı STL işlevini kullanarak? {Algorithm.h :: transform işlevi} gibi bir şey mi?STL
STL
cevap
Evet,:
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind1st(std::multiplies<T>(),3));
vector
yerine valarray
kullanırsanız, bir skalar çarpma yapmak için yerleşik operatörler vardır.
transform(v.begin(), v.end(), v.begin(), _1 * 3);
(Eğer kolayca gibi anonim işlev nesneleri oluşturmanıza olanak sağlar Boost.Lambda benzer bir şey var varsayarak: Bir vector
kullanmak zorunda ise
v *= 3;
, gerçekten işi yapmak için transform
kullanabilirsiniz _1 * 3
:-P) std::transform
kullanılarak
Valarrays, doğru çözüm IMO'dur. Şansınızla, uygulamanız prosedürü uygulamak için SSE talimatlarını kullanır ve bu da onu çok daha hızlı hale getirir. Böyle bir valarray uygulaması için http://www.pixelglow.com/macstl/valarray/ adresine bakın. Ne yazık ki, çok yaygın değil, bu yüzden SSE komutlarının avantajlarını istiyorsanız, muhtemelen derleyici içsel kullanmanız gerekecek ... – Dragontamer5788
@Dragon: 'valarray' en iyi STL çözümü, ancak yüksek performans için çok iyi değil Bilgiyi, bellekte çok fazla veri kopyalama eğiliminde olduğundan ve zayıf bellek erişim düzenine sahip olan tekli işlemleri içeren küçük döngülerden oluşan diziler üretir. Yine de, valarray'dan uygun bir ifade şablon sistemine yükseltmek daha kolaydır. – Potatoswatter
Yalnızca: Verilerinizi sabit boyutlu bir dizide (float değerleri [N]) alabilirseniz, SSE intrinsics'i daha hızlı yapmak için kullanabilirsiniz.
Bu STL'yi istediğiniz kadar tanımadığımı biliyorum, ancak farklı ihtiyaçlara göre uyarlayabileceğiniz bir şey.
Hesaplamak için kullanabileceğiniz bir şablon aşağıdadır; 'func' yapmak istediğiniz işlev olacaktır: çarpın, ekleyin ve benzeri; 'parm', 'func' için ikinci parametredir. Farklı func'leri farklı türlerde daha fazla parkeyle çekmek için bunu kolayca genişletebilirsiniz.
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 */
Ayrıca, bu bir 'güvenli' işlev değil, yapmanız gereken tip/değer denetimi vb kullanmadan önce. Bu durumda basit bir lambda yeterli olacaktır, bazı şablona göre bir vektör çapraz ve her eleman manipüle etmek istediğimde for_each
düşünüyorum
Bu çalışır, ancak aslında 'std :: transform' zaten sizin için bunu yapar gibi, tekerleği yeniden icat ediyor. –
Evet - kabul edilen cevapta gördüm ... ama aslında işe yarayan bir tekerleği yeniden icat etmenin ne kadar mutlu olduğunu biliyor musunuz?) Her neyse kendimi bir konformist haline geldiğimde çekeceğim;) – slashmais
çok apt:
std::for_each(myv1.begin(), mtv1.end(), [](int &el){el *= 3; });
notu o yakalamak istediğiniz herhangi değişken lambda fonksiyonunun kullanılması için (örneğin önceden belirlenmiş skaler ile çarpmak istediğinizi söyleyin), referans olarak brakete girer.
Bu amaç değil. std :: for_each'. std :: for_each, bazı (muhtemelen durum bilgisi olan) işlev nesnesini bir aralığa uygular ve bu işlev nesnesini döndürür. Bir aralığı dönüştürmek istiyorsanız, amacınızı daha net hale getirmek için 'std :: dönüşümü' kullanın. – sv90
Teşekkürler çok dahidir! –