معرفی کلاس‌های valarray و array و نگه‌دارنده‌ی list در ++C

Array Valarray And List in C Plus Plus

19 اردیبهشت 1401
Array-Valarray-and-List-in-C-Plus-Plus

در این قسمت از آموزش به کلاس std:: valarray، کلاس Array و نگه‌دارنده‌ی List از کتابخانه‌ی STL خواهیم پرداخت.

کلاس valarray در ++C

98++C یک نگه‌دارنده‌ی خاص به نام valarray برای نگه‌داری و فراهم کردن عملیات ریاضی روی آرایه معرفی‌ کرده است.

این کلاس از عملیا‌ت‌های ریاضی مبتنی‌بر عنصر و اشکال مختلف عمومی عملگر‌های subscrip، برش (slicing) و دسترسی غیر‌مستقیم پشتیبانی می‌کند.
در مقایسه با بردار‌ها (vectors‌)، valarray‌ها در عملیات‌های ریاضی خاص نسبت به بردار‌ها نیز کارا‌ هستند.

توابع عضو عمومی در کلاس valarray

apply: این تابع دستکار‌های داده‌شده در آرگومانت‌هایش را به همه‌ی عناصر valarray بلافاصله اعمال می‌کند و یک valarray جدید با مقادیر دستکار‌ی‌شده برمی‌گرداند.
sum: این تابع مجموع همه‌ی عناصر valarrays بلافاصله برمی‌گرداند.

قطعه‌کد زیر کار این دو تابع را به تصویر می‌کشد:

// C++ code to demonstrate the working of
// apply() and sum()
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing valarray
valarray<int> varr = { 10, 2, 20, 1, 30 };

// Declaring new valarray
valarray<int> varr1 ;

// Using apply() to increment all elements by 5
varr1 = varr.apply([](int x){return x=x+5;});

// Displaying new elements value
cout << "The new valarray with manipulated values is : ";
for (int &x: varr1) cout << x << " ";
cout << endl;

// Displaying sum of both old and new valarray
cout << "The sum of old valarray is : ";
cout << varr.sum() << endl;
cout << "The sum of new valarray is : ";
cout << varr1.sum() << endl;

return 0;

}

خروجی قطعه‌کد بالا به این صورت است:

The new valarray with manipulated values is : 15 7 25 6 35
The sum of old valarray is : 63
The sum of new valarray is : 88

3. min: این تابع کوچکترین عنصر valarray را برمی‌گرداند.

4. max: این تابع بزرگترین عنصر valarray را برمی‌گرداند.

// C++ code to demonstrate the working of
// max() and min()
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing valarray
valarray<int> varr = { 10, 2, 20, 1, 30 };

// Displaying largest element of valarray
cout << "The largest element of valarray is : ";
cout << varr.max() << endl;

// Displaying smallest element of valarray
cout << "The smallest element of valarray is : ";
cout << varr.min() << endl;

return 0;

}

خروجی قطعه‌کد بالا به این صورت است:

The largest element of valarray is : 30
The smallest element of valarray is : 1

5.  shift: این تابع بعد از تغییر‌مکان عناصر با عدد اشاره‌شده در آرگومانتش، valarray جدید برمی‌گرداند. اگر عدد مثبت باشد، تغییر‌مکان به سمت چپ اعمال می‌شود، اگر عدد منفی باشد، تغییر‌مکان به سمت راست صورت می‌گیرد.

6. cshift: این تابع بعد از تغییر‌مکان چرخشی عناصر توسط عدد اشاره‌شده در آرگومانتش، valarray جدید برمی‌گرداند. اگر عدد مثبت باشد، تغییر‌مکان چرخشی به سمت چپ اعمال می‌شود، اگر عدد منفی باشد، تغییر‌مکان چرخشی به سمت راست صورت می‌گیرد.

// C++ code to demonstrate the working of
// shift() and cshift()
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing valarray
valarray<int> varr = { 10, 2, 20, 1, 30 };

// Declaring new valarray
valarray<int> varr1;

// using shift() to shift elements to left
// shifts valarray by 2 position
varr1 = varr.shift(2);

// Displaying elements of valarray after shifting
cout << "The new valarray after shifting is : ";
for ( int&x : varr1) cout << x << " ";
cout << endl;

// using cshift() to circulary shift elements to right
// rotates valarray by 3 position
varr1 = varr.cshift(-3);

// Displaying elements of valarray after circular shifting
cout << "The new valarray after circular shifting is : ";
for ( int&x : varr1) cout << x << " ";
cout << endl;

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

The new valarray after shifting is : 20 1 30 0 0
The new valarray after circular shifting is : 20 1 30 10 2

7. ()swap: این تابع یک valarray را با valarray دیگر تعویض می‌کند.

// C++ code to demonstrate the working of
// swap()
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing 1st valarray
valarray<int> varr1 = {1, 2, 3, 4};

// Initializing 2nd valarray
valarray<int> varr2 = {2, 4, 6, 8};

// Displaying valarrays before swapping
cout << "The contents of 1st valarray "
"before swapping are : ";
for (int &x : varr1)
cout << x << " ";
cout << endl;
cout << "The contents of 2nd valarray "
"before swapping are : ";
for (int &x : varr2)
cout << x << " ";
cout << endl;

// Use of swap() to swap the valarrays
varr1.swap(varr2);

// Displaying valarrays after swapping
cout << "The contents of 1st valarray "
"after swapping are : ";
for (int &x : varr1)
cout << x << " ";
cout << endl;

cout << "The contents of 2nd valarray "
"after swapping are : ";
for (int &x : varr2)
cout << x << " ";
cout << endl;

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

The contents of 1st valarray before swapping are : 1 2 3 4
The contents of 2nd valarray before swapping are : 2 4 6 8
The contents of 1st valarray after swapping are : 2 4 6 8
The contents of 2nd valarray after swapping are : 1 2 3 4

نگه‌دارنده‌ی List در کتابخانه‌ی الگو استاندارد یا STL

لیست‌ها نگه‌دارند‌ه‌ی ترتیبی هستند که امکان تخصیص‌حافظه به صورت غیر‌پیوسته (non-contiguous). در مقایسه با بردار‌، لیست پیمایش ضعیفی دارد، اما زمانی که یک موقعیت یافت‌شده باشد، درج‌کردن و حذف‌کردن سریع است. به‌طور طبیعی، زمانی که درمورد یک لیست صحبت می‌شود، درمورد یک لیست‌پیوندی دوطرفه صحبت می‌کنیم. برای پیاده‌سازی یک لیست‌پیوندی یک‌طرفه، از لیست به جلو (forward list) استفاده می‌کنیم. قطعه‌کُد زیر کارکرد برخی از توابع لیست را به تصویر می‌کشد:

// CPP program to show the implementation of List
#include <iostream>
#include <iterator>
#include <list>
using namespace std;

// function for printing the elements in a list
void showlist(list<int> g)
{
list<int>::iterator it;
for (it = g.begin(); it != g.end(); ++it)
cout << '\t' << *it;
cout << '\n';
}

// Driver Code
int main()
{

list<int> gqlist1, gqlist2;

for (int i = 0; i < 10; ++i) {
gqlist1.push_back(i * 2);
gqlist2.push_front(i * 3);
}
cout << "\nList 1 (gqlist1) is : ";
showlist(gqlist1);

cout << "\nList 2 (gqlist2) is : ";
showlist(gqlist2);

cout << "\ngqlist1.front() : " << gqlist1.front();
cout << "\ngqlist1.back() : " << gqlist1.back();

cout << "\ngqlist1.pop_front() : ";
gqlist1.pop_front();
showlist(gqlist1);

cout << "\ngqlist2.pop_back() : ";
gqlist2.pop_back();
showlist(gqlist2);

cout << "\ngqlist1.reverse() : ";
gqlist1.reverse();
showlist(gqlist1);

cout << "\ngqlist2.sort(): ";
gqlist2.sort();
showlist(gqlist2);

return 0;
}

خروجی قطعه‌کُد بالا به این صورت است:

List 1 (gqlist1) is : 0 2 4 6 8 10 12 14 16 18

List 2 (gqlist2) is : 27 24 21 18 15 12 9 6 3 0




gqlist1.front() : 0
gqlist1.back() : 18
gqlist1.pop_front() : 2 4 6 8 10 12 14 16 18

gqlist2.pop_back() : 27 24 21 18 15 12 9 6 3

gqlist1.reverse() : 18 16 14 12 10 8 6 4 2

gqlist2.sort(): 3 6 9 12 15 18 21 24 27
List 1 (gqlist1) is : 0 2 4 6 8 10 12 14 16 18

List 2 (gqlist2) is : 27 24 21 18 15 12 9 6 3 0

gqlist1.front() : 0
gqlist1.back() : 18
gqlist1.pop_front() : 2 4 6 8 10 12 14 16 18

gqlist2.pop_back() : 27 24 21 18 15 12 9 6 3

gqlist1.reverse() : 18 16 14 12 10 8 6 4 2

gqlist2.sort(): 3 6 9 12 15 18 21 24 27

توابع استفاده‌شده با لیست

front: مقدار اولین عنصر در لیست را برگشت می‌دهد.
back: مقدار اخرین عنصر در لیست را برگشت می‌دهد.
push_front: یک عنصر g  جدید را در ابتدای لیست اضافه می‌کند.
push_back: یک عنصر g در انتهای لیست اضافه می‌کند.
pop_front: اولین عنصر لیست را حذف می‌کند و اندازه‌ی لیست را یکی کاهش می‌دهد.
pop_back: آخرین عنصر لیست را حذف می‌کند و اندازه‌ی لیست را یکی کاهش می‌دهد.
list::begin: این تابع یک پیمایشگر که به اولین عنصر در لیست اشاره می‌کند، برگشت می‌دهد.
list::end: این تابع یک پیمایشگر که به صورت تئوری به آخرین عنصر اشاره می‌کند برمی‌گرداند که درواقع آخرین عنصر را دنبال می‌کند.
list rbegin و rend: تابع rbegin یک پیمایشگر معکوس که به آخرین عنصر لیست اشاره می‌کند، برگشت می‌دهد. تابع rend یک پیمایشگر معکوس که به موقعیت  قبل از ابتدای  لیست اشاره می‌کند، برگشت می‌دهد.
list cbegin و cend: تابع cbegin یک پیمایشگر با دسترسی تصادفی ثابت که به ابتدای لیست اشاره می‌کند، برمی‌گرداند. تابع cend یک پیمایشگر با دسترسی تصادفی ثابت که به انتهای لیست اشاره می‌کند، برمی‌گرداند.
list crbegin و crend: تابع crbegin یک پیمایشگر ثابت معکوس که به آخرین عنصر لیست اشاره می‌کند، برمی‌گرداند. به عنوان مثال، ابتدای معکوس‌شده نگه‌دارنده. تابع crend یک پیمایشگر معکوس ثابت که به عنصری تئوری پیش از اولین عنصر در لیست اشاره می‌کند، برمی‌گرداند. به عنوان مثال انهای معکوس‌شده لیست.
empty: بررسی این‌ه آیا لیست خالی است یا نه که 0 خالی نبودن و 1 خالی بودن لیست را نشان می‌دهد.
insert: درج عناصر جدید در لیست قبل از عنصر در موقعیت مشخص‌شده.
erase: حذف یک عنصر یا طیفی از عناصر در لیست.
assign: اختصاص عناصر جدید به لیست با جایگزین عناصر فعلی و تغییر‌اندازه‌ی لیست.
remove: حذف همه‌ی عناصر از لیست، که با عنصر‌ داد‌شده برابر هستند.
list::remove_if: برای حذف همه‌ی مقادیر از لیست که شرط فراهم‌شده به عنوان پارامتر برای تابع با true مطابقت دارد، استفاده شده‌ است.
reverse: معکوس‌ کردن لیست.
size: تعداد عناصر در لیست را برمی‌گرداند.
list resize: برای تغییر‌اندازه‌ی نگه‌دارنده‌ی استفاده شده است.
sort:‌ لیست را در ترتیب صعودی مرتب می‌کند.
list max_size: حداکثر تعداد عناصر نگه‌دارنده‌ی لیست که می‌تواند نگه‌ دارد را برمی‌گرداند.
list unique: حذف همه‌ی عناصر متوالی تکراری از لیست.
list::emplace_front و list::emplace_back: تابع emplace_front برای درج یک عنصر جدید در نگه‌دارنده‌ی لیست استفاده‌شده است که به ابتدای لیست اضافه می‌شود. تابع emplace_back برای درج یک عنصر جدید در نگه‌دارنده‌ی لیست استفاده‌شده است که به انتهای لیست اضافه می‌شود.
list::clear: این تابع برای حذف همه‌ی عناصر نگه‌دارنده‌ی لیست استفاده شده است، بنابراین اندازه‌اش 0 خواهد شد.
= list::operator: این عملگر برای اختصاص محتوای جدید به نگه‌دارنده توسط جایگزین کردن محتوای موجود. استفاده شده است.
list::swap: این تابع برای تعویض محتوای یک لیست با لیست دیگر از همان نوع و اندازه استفاده شده است.
list splice: برای انتقال عناصر از یک لیست به لیست دیگر استفاده شده است.
list merge: دو لیست مرتب‌شده را در یک لیست ادغام می‌کند.
list emplace: گسترش لیست با درج عنصر جدید در موقعیت داده‌شده.

کلاس آرایه در ++C

کلاس آرایه از 11++C به عنوان یک گزینه‌ی بهتر برای آرایه‌های سبک C یا C-style پیشنهاد داده‌ شده‌است. مزایای کلاس آرایه بیش از آرایه‌های سبک C هستند:

کلاس‌های آرایه اندازه‌ی خودشان را می‌دانند، درحالی که آرایه‌های سبک C فاقد چنین ویژگی هستند. بنابراین زمانی که به توابع ارسال می‌شوند، دیگر نیازی به ارسال اندازه‌ی آرایه به عنوان یک پارامتر جدا نیست.
با آرایه‌های سبک C خطر بیشتری از آرایه تجزیه‌شده درون یک اشاره‌گر وجود دارد. کلاس‌های آرایه درون اشاره‌گر‌های تجزیه نمی‌شوند.
کلاس‌های آرایه معمولا کارا، سبک‌وزن و قابل‌اعتماد‌تر نسبت به آرایه‌های سبک C  هستند.

عملیات‌ها بر روی آرایه

at: این تابع برای دسترسی عناصر آرایه مورد استفاده قرار می‌گیرد.

get: این تابع نیز برای دسترسی عناصر آرایه مورد استفاده قرار می‌گیرد. این تابع عضوی از کلاس آرایه نیست، اما تابع سربارگذاری‌شده از کلاس tuple است.
[]operator: این شبیه به آرایه‌های سبک C است. این روش نیز برای دستری به عناصر آرایه استفاده شده است.

// C++ code to demonstrate working of array,
// at() and get()
#include<iostream>
#include<array> // for array, at()
#include<tuple> // for get()
using namespace std;
int main()
{
// Initializing the array elements
array<int,6> ar = {1, 2, 3, 4, 5, 6};

// Printing array elements using at()
cout << "The array elements are (using at()) : ";
for ( int i=0; i<6; i++)
cout << ar.at(i) << " ";
cout << endl;

// Printing array elements using get()
cout << "The array elements are (using get()) : ";
cout << get<0>(ar) << " " << get<1>(ar) << " ";
cout << get<2>(ar) << " " << get<3>(ar) << " ";
cout << get<4>(ar) << " " << get<5>(ar) << " ";
cout << endl;

// Printing array elements using operator[]
cout << "The array elements are (using operator[]) : ";
for ( int i=0; i<6; i++)
cout << ar[i] << " ";
cout << endl;

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

The array elements are (using at()) : 1 2 3 4 5 6
The array elements are (using get()) : 1 2 3 4 5 6
The array elements are (using operator[]) : 1 2 3 4 5 6

4. front: این تابع اولین عنصر از آرایه را برگشت می‌دهد.

5.back: این تابع آخرین عنصر از آرایه را برگشت می‌دهد.

// C++ code to demonstrate working of
// front() and back()
#include<iostream>
#include<array> // for front() and back()
using namespace std;
int main()
{
// Initializing the array elements
array<int,6> ar = {1, 2, 3, 4, 5, 6};

// Printing first element of array
cout << "First element of array is : ";
cout << ar.front() << endl;

// Printing last element of array
cout << "Last element of array is : ";
cout << ar.back() << endl;

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

First element of array is : 1
Last element of array is : 6

6. size: این تابع تعداد عناصر در آرایه برگشت می‌دهد. این ویژگی است که آرایه‌های سبک C فاقد آن هستند.

7. max_size: این تابع حداکثر تعداد عناصری که آرایه ‌می‌تواند نگه‌دارد را برمی‌گرداند. به عنوان مثال، اندازه‌ که با آن آرایه اعلام‌شده است. () size() ، max_size مقدار یکسانی را برمی‌گرداند.

// C++ code to demonstrate working of
// size() and max_size()
#include<iostream>
#include<array> // for size() and max_size()
using namespace std;
int main()
{
// Initializing the array elements
array<int,6> ar = {1, 2, 3, 4, 5, 6};

// Printing number of array elements
cout << "The number of array elements is : ";
cout << ar.size() << endl;

// Printing maximum elements array can hold
cout << "Maximum elements array can hold is : ";
cout << ar.max_size() << endl;

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

The number of array elements is : 6
Maximum elements array can hold is : 6

8. swap: تابع () swap همه‌ی عناصر یک آرایه را با آرایه‌ دیگر تعویض می‌کند.

// C++ code to demonstrate working of swap()
#include<iostream>
#include<array> // for swap() and array
using namespace std;
int main()
{

// Initializing 1st array
array<int,6> ar = {1, 2, 3, 4, 5, 6};

// Initializing 2nd array
array<int,6> ar1 = {7, 8, 9, 10, 11, 12};

// Printing 1st and 2nd array before swapping
cout << "The first array elements before swapping are : ";
for (int i=0; i<6; i++)
cout << ar[i] << " ";
cout << endl;
cout << "The second array elements before swapping are : ";
for (int i=0; i<6; i++)
cout << ar1[i] << " ";
cout << endl;

// Swapping ar1 values with ar
ar.swap(ar1);

// Printing 1st and 2nd array after swapping
cout << "The first array elements after swapping are : ";
for (int i=0; i<6; i++)
cout << ar[i] << " ";
cout << endl;
cout << "The second array elements after swapping are : ";
for (int i=0; i<6; i++)
cout << ar1[i] << " ";
cout << endl;

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

The first array elements before swapping are : 1 2 3 4 5 6
The second array elements before swapping are : 7 8 9 10 11 12
The first array elements after swapping are : 7 8 9 10 11 12
The second array elements after swapping are : 1 2 3 4 5 6

9. empty: این تابع زمانی که اندازه‌ی آرایه 0 باشد، true را برگشت می‌دهد. جز این false را برگشت می‌دهد.

10. fill: این تابع برای پر کردن کامل آرایه با یک مقدار خاص مورد استفاده قرار می‌گیرد.

// C++ code to demonstrate working of empty()
// and fill()
#include<iostream>
#include<array> // for fill() and empty()
using namespace std;
int main()
{

// Declaring 1st array
array<int,6> ar;

// Declaring 2nd array
array<int,0> ar1;

// Checking size of array if it is empty
ar1.empty()? cout << "Array empty":
cout << "Array not empty";
cout << endl;

// Filling array with 0
ar.fill(0);

// Displaying array after filling
cout << "Array after filling operation is : ";
for ( int i=0; i<6; i++)
cout << ar[i] << " ";

return 0;

}

خروجی قطعه‌کُد بالا به این صورت است:

Array empty
Array after filling operation is : 0 0 0 0 0 0

منابع: Array، valarray، list

نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.