Hàm std::accumulate trong C++ là gì? Muốn chuyển qua code C phải làm như thế nào?

Mọi người cho em hỏi hàm này có công dụng gì ?

accumulate(begin,last,init) ; 

em vẫn chưa hiểu lắm.
nếu muốn chuyển qua chương trình C phải làm sao ?

là hàm sum đó em :V

nó giống như là

while (begin != end)
    init = init + *begin++;
return init;

chuyển qua C thì để tính tổng 1 mảng thì cứ 1 vòng for mà táng

init = ...;
for (int i = 0; i < 10; ++i) // hoặc xài con trỏ: for (int* ptr = arr; ptr != arr + 10; ++ptr)
    init += arr[i];
6 Likes

Hàm này còn gọi là fold left :smiley:

2 Likes

C++17 có hàm mới gọi là std::reduce cũng tính tổng tương tự nhưng nó cho phép cộng song song :V lẹ hơn, nhưng khổ cái là a b c d có thể nó tính là ((a + b) + (c + d)) chứ ko tuần tự theo std::accumulate (((a + b) + c) + d)

5 Likes

Phải như vậy ko anh ?

int Sum( int a[], int n)
{
    int i,s;
    for(i=0,s=0;i<n;i++) 
	s=s+a[i];
    return s;
}
2 Likes

phải khởi tạo giá trị cho s nữa, cho nó nằm vô biến truyền vào sum luôn đi cho giống :V

int sum(int a[], int n, int s)
{
    int i;
    for(i = 0 ;i < n; i++)
        s = s + a[i];
    return s;
}

edit: ý có khởi tạo trong vòng for, ko thấy so ri em :kissing_closed_eyes:

3 Likes

Hàm này là hàm “tích lũy”, ý tưởng của nó là từ 1 giá trị khởi đầu, bạn liên tục tích lũy các giá trị khác vào nó. Ở đây giá trị khởi đầu là *begin, hàm sẽ tích lũy từ *(begin + 1) đến phần tử kế đằng trước last. Init ở đây là hàm định nghĩa cách tích lũy, có thể là tích lũy bằng phép cộng, phép trừ, nhân, chia, hoặc cách nào đó tùy bạn. Ở các ngôn ngữ khác, sdk khác, đôi khi hàm kiểu này còn được gọi là reduce - thu gọn/giảm thiểu, tức là gộp hết toàn bộ các phần tử trong tập hợp lại làm 1, thực ra cũng y như ý tưởng “tích lũy” như trên, ví dụ đọc thêm tại: http://www.cplusplus.com/reference/numeric/accumulate/ , cần có kiến thức cực vững về con trỏ hàm (function pointer), hoặc toán tử gọi hàm (function call operator), hoặc std::function, hoặc lamda expression.

3 Likes

viết dài quá chậm rồi :joy:

mà cần gì vững con trỏ hàm gì, cứ đọc ví dụ rồi phang thoi

2 Likes

Không vững thì không lợi dụng được C++ cho cá nhân đâu.

vững nghe như hù newbie, nâng bi C++ lên thành ngôn ngữ khó, ko nên hù như dzậy

ví dụ thay vì tính tổng tính tích thì viết

double tich = std::accumulate(std::begin(arr), std::end(arr), 1.0,
    [](double init, double n){ return init * n; });

dễ dàng vậy thôi cần gì biết vững về lambda là vững thế nào, cú pháp như học tiếng Anh thôi :V 1 cái ngoặc vuông [] 1 cái ngoặc tròn () 1 cái ngoặc dẹo {} là xong :relaxed:

3 Likes

Em xin cám ơn các anh rất nhiều ! :hearts::hearts::hearts:
em cũng đã hiểu chút chút và sử dụng hàm này như thế nào, :grinning:

Hi tntxtnt.
Cái đó chỉ là cài vỏ khai báo cú pháp thôi. Không hiểu kĩ thì không biết cách dùng cho từng trường hợp cho đúng. Như khi nào tham chiếu, khi nào tham trị, khi nào con trỏ raw khi nào con trỏ thông mình v.v.v… Đơn cử như khi nào while, khi nào for cũng cần phải suy nghĩ rồi. Nếu không thì cũng chỉ đi copy code các chỗ rồi vá lại với nhau thôi.

P/S C++ hay C là một ngôn ngữ mạnh và dễ dãi như chính vì thế mà lập trình viên càng phải có trách nhiêm hơn.

1 Like

đang cần làm 1 sao lại phải học 10 cho phức tạp lên? Viết 1 chương trình đơn giản tính a + b có phải học luôn đa luồng multithread gì ko đây? :V Chém gió dữ quá sợ ai còn dám học nữa :V

3 Likes

std::reduce này chắc chỉ dùng cho hàm f(x,y) nào có tính chất kết hợp (associative property)

Nếu không có kết hợp chắc chỉ dùng accumulate.

3 Likes

đúng rồi, tại vì tính song song nên nó thế. Ví dụ tính a / b / c / d thì ko xài reduce được vì a / b / c khác a / (b / c) :V

3 Likes

Hi tntxtnt.
Đó là ví dụ. Nếu code thuần C++ thì thích thế nào cũng được code của mình luật của mình thích goto nhúng as hay cái gì cũng được. Nhưng đã dùng các thư viện các đặc trưng của ngôn ngữ thì ít nhất cũng phải hiểu mình đang làm gì đã.

reduce behaves like std::accumulate except the elements of the range may be grouped and rearranged in arbitrary order

Vậy thì phải có tính giao hoán nữa vì thứ tự sẽ bị thay đổi. Tức là nhân ma trận cũng không được :smiley:

3 Likes

thế ở đây cần hiểu cái gì nữa mới xài acummulate(a, b, c, d) được? :V Biết d là hàm đc rồi, đòi nắm vững std::function như thím Mei chém thì quá đáng :V Vững như kiểu có thể viết nó ra bằng template à? Biết và vững là rất khác nhau. Nghe cứ như phải lv100 mới xài accumulate được trong khi lv2 3 thì xài vòng for mà tính tổng :V

hơn nữa lambda trong C++11 đừng sợ nó, cứ hiểu nó là viết tắt cho hàm số là được, [](){} mà táng thôi.

3 Likes

[archive only]

2 Likes

thì beginner cứ xài [] cho tiện, có thể chưa cần biết [&] hay [=]. Viết là [&] thì mới với tay ra lấy mấy biến cục bộ của hàm gọi nó được, [] đâu có gọi được, y như free function thôi.

thay vì viết

double mult(double a, double b) { return a * b; }
...
double x = accumulate(begin(a), end(a), 1.0, mult);

thì xài lambda

double x = accumulate(begin(a), end(a), 1.0,
    [](double a, double b) { return a * b; });

cho nó tiện là được :V Cần gì phải biết tường tận magic phía sau như thế nào. Như Python nhào vô khai báo mảng p = [1, 1.1, "111"] được có ai đòi phải vững cái gì đâu :V

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?