2010-10-07 31 views

Trả lời

73

Vâng, sử dụng std::transform:

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

Cảm ơn rất nhiều đó là thiên tài !! –

21

Nếu bạn có thể sử dụng valarray thay vì vector, nó có các toán tử dựng sẵn để thực hiện phép nhân vô hướng.

v *= 3; 

Nếu bạn phải sử dụng một vector, bạn thực sự có thể sử dụng transform để thực hiện công việc:

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

(giả sử bạn có một cái gì đó tương tự như Boost.Lambda cho phép bạn dễ dàng tạo các đối tượng chức năng ẩn danh như _1 * 3 :-P)

+1

Valaray là giải pháp đúng IMO. Với sự may mắn, việc triển khai của bạn sử dụng các hướng dẫn SSE để thực hiện quy trình, làm cho nó nhanh hơn đáng kể. Xem http://www.pixelglow.com/macstl/valarray/ để thực hiện việc khắc phục như vậy. Thật không may, nó không phải là rất phổ biến, vì vậy nếu bạn muốn những lợi thế của SSE hướng dẫn bạn có thể sẽ phải sử dụng trình biên dịch nội tại ... – Dragontamer5788

+0

@ Dragon: 'valarray' là giải pháp STL tốt nhất, nhưng nó không phải là rất tốt cho hiệu suất cao tính toán vì nó có xu hướng sao chép dữ liệu trong bộ nhớ rất nhiều và tạo ra các chuỗi các vòng nhỏ chứa các hoạt động đơn lẻ có các mẫu truy cập bộ nhớ kém. Tuy nhiên, việc nâng cấp từ 'valarray' lên hệ thống khuôn mẫu biểu thức thích hợp là dễ dàng hơn. – Potatoswatter

0

Chỉ cần: nếu bạn có thể có dữ liệu của bạn trong một mảng kích thước cố định (giá trị float [N]), bạn có thể sử dụng nội tại SSE để làm cho nó nhanh hơn vì nó sẽ nhân cực bảy lần một lần (4).

0

Tôi biết điều này không phải STL như bạn muốn, nhưng nó là một cái gì đó bạn có thể thích ứng với nhu cầu khác nhau phát sinh.

Dưới đây là mẫu bạn có thể sử dụng để tính; 'func' sẽ là hàm bạn muốn làm: nhân, thêm, v.v. 'parm' là tham số thứ hai cho 'func'. Bạn có thể dễ dàng mở rộng này để có func khác nhau với nhiều parms của các loại khác nhau.

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 */ 

Ngoài ra, đây không phải là chức năng 'an toàn', bạn phải thực hiện kiểm tra loại/giá trị, v.v. trước khi sử dụng.

+0

Công trình này, nhưng chủ yếu là phát minh lại bánh xe, như 'std :: transform' đã làm điều này cho bạn. –

+0

Có - đã nhìn thấy trong câu trả lời được chấp nhận ... nhưng bạn có nhận ra niềm vui là tái tạo lại một bánh xe thực sự hoạt động;) Dù sao tôi sẽ tự bắn mình vào ngày tôi trở thành người tuân thủ;) – slashmais

0

Tôi nghĩ for_each là rất apt khi bạn muốn đi qua một vector và thao tác từng phần tử theo một số mô hình, trong trường hợp này một lambda đơn giản sẽ đủ:

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

lưu ý rằng bất kỳ biến bạn muốn chụp để sử dụng hàm lambda (nói rằng bạn ví dụ như muốn nhân với một số vô hướng được xác định trước), đi vào khung như một tham chiếu.

+0

Đây không phải là mục đích của ' std :: for_each'. 'std :: for_each' áp dụng một đối tượng hàm (có thể trạng thái) cho một phạm vi và sau đó trả về đối tượng hàm này. Nếu bạn muốn chuyển đổi một phạm vi sử dụng 'std :: transform' để làm cho ý định của bạn rõ ràng hơn. – sv90

Các vấn đề liên quan