Урок 6. Последовательности и перечисления в C#

Лабораторные работы си шарп и задания по теме «Язык программирования c sharp: Перечисления и последовательности»

Тренировка задания 17 ЕГЭ (17.2)

17 задание с сайта К. Полякова, № 28:

Рассматривается множество целых чисел, принадлежащих числовому отрезку [3439; 7410], которые удовлетворяют следующим условиям:

• запись в двоичной и шестеричной системах счисления заканчивается разными цифрами;
• кратны 9, 10 или 11.
• Найдите количество таких чисел и максимальное из них.

! Для выполнения этого задания можно написать программу или воспользоваться редактором электронных таблиц

Ответ: 683   7407

Тренировка задания 17 ЕГЭ (17.1)

17 задание с сайта К. Полякова, № 1:

Рассматривается множество целых чисел, принадлежащих числовому отрезку [1012; 9638], которые делятся на 3 и не делятся на 11, 13, 17, 19. Найдите количество таких чисел и максимальное из них.
В ответе запишите два целых числа: сначала количество, затем максимальное число.

! Для выполнения этого задания можно написать программу или воспользоваться редактором электронных таблиц

Ответ: 2151 | 9630

Тренировка задания 15 ЕГЭ (15.5)

Решение 15 задания (Вариант 139, К. Поляков) :

Обозначим через ДЕЛ(n, m) утверждение «натуральное число n делится без остатка на натуральное число m».

Для какого наименьшего натурального числа А формула

(ДЕЛ(x, A) ∧ ДЕЛ(x, 21)) → ДЕЛ(x, 18)

тождественно истинна (то есть принимает значение 1 при любом натуральном значении переменной х)?

Ответ: 18

Тренировка задания 15 ЕГЭ (15.7)

Решение 15 задания (Вариант 132, К. Поляков) :

Обозначим через ДЕЛ(n, m) утверждение «натуральное число n делится без остатка на натуральное число m».

Для какого наибольшего натурального числа А формула

¬ДЕЛ(x, А) → (¬ДЕЛ(x, 24)  ∧ ¬ДЕЛ(x, 36))

тождественно истинна (то есть принимает значение 1 при любом натуральном значении переменной х)?

Ответ: 12

Theory

Lection in pdf format

Standard sequence generators

Range(a,b: integer): sequence of integer

 print(Range(1,10)); // [1,2,3,4,5,6,7,8,9,10]

Range(a,b,step: integer): sequence of integer

 print(Range(1,10,2)); // [1,3,5,7,9]

Range(c1,c2: char): sequence of char

 print(Range('a','k')); // [a,b,c,d,e,f,g,h,i,j,k]

Partition(a,b: real; n: integer): sequence of real

 print(Partition(0.0, 6.0, 4)); // делим поровну на 4 части [0, 1.5, 3, 4.5, 6]

SeqRandomInteger(n: integer[; a,b: integer]): sequence of integer;

 var q:=SeqRandomInteger(5,10,20); print(q); // [12,18,16,14,16]

SeqRandomReal(n: integer[; a,b: real]): sequence of real;

 var q:=SeqRandomReal(3, 1.0, 5.0); print(q); // [4.98996168374548,2.22339218166815,2.81110574389394]

Seq(params a: array of T): sequence of T;

 foreach var x in Seq (1,3,8) do print(x*x); // 1 9 64

SeqFill(count: integer; x: T): sequence of T;

 begin var q:=SeqFill(7,5); print(q); // [5,5,5,5,5,5,5] end.

Sequence generators with lambda-expressions

The following functions are used to generate sequences using lambda expressions:

• SeqGen(count: integer; f: integer -> T): sequence of T;
•  begin var sq:=SeqGen(5,x->x+1); sq.println; // 1 2 3 4 5 end.
• SeqGen(count: integer; first: T; next: T -> T): sequence of T;
•  begin var sq:=SeqGen(5, 4, x->x+1); sq.println; // 4 5 6 7 8 end.
• SeqGen(count: integer; first,second: T; next: (T,T) -> T): sequence of T;
•  begin var sq:=SeqGen(5, 1,3, (x,y)->x+y); sq.println; // 1 3 4 7 11 end.
• SeqWhile(first: T; next: T -> T; pred: T -> boolean): sequence of T;

 begin var sq:=seqWhile(2,x->x*2,x->x<=1024); sq.println; // 2 4 8 16 32 64 128 256 512 1024 end.
• SeqWhile(first,second: T; next: (T,T) -> T; pred: T -> boolean): sequence of T;
• SeqGen(count: integer; f: integer -> T): sequence of T;

Infinite sequence generators

• Cycle()
• Repeating a sequence block

 Seq(1,2,10,5).Cycle().Take(15).Println; // 1 2 10 5 1 2 10 5 1 2 10 5 1 2 10

Take is used to restrict

• Repeat
• Infinite sequence of numbers

 var q:=55.Repeat.Take(10).Println; // 55 55 55 55 55 55 55 55 55 55
• Step
• Generating an infinite sequence with a step

 var q:=5.Step(2).Take(10).Println; // 5 7 9 11 13 15 17 19 21 23
• Iterate
• Generating an infinite sequence using a lambda-function

 var q:=10.Iterate(x->x-2).Take(10).Println; // 10 8 6 4 2 0 -2 -4 -6 -8

Lab 1.

To do: Ask user to input 10 integer elements of the sequence. Calculate a sum of the seq elements.

The result examples:

1
2
3
4
1
6
7
2
5
6
sum = 37

✍ Algorithm:

 begin var q:=ReadSeqReal(10); var s:=0.0; foreach var x in q do s+=x; print('sum = ', s) end.

To do: Create the function to calculate the product (multiplication) of 5 entered sequence elements.

Note: the signature of the function:

 function Product(q: sequence of real):real;

The resulting example:

1.2
3.1
6.7
2.8
3.4
product:  237.27648

To do: Create sequence of integers from -20 to 30 with a step of 3 (Range function).

The resulting example:

[-20,-17,-14,-11,-8,-5,-2,1,4,7,10,13,16,19,22,25,28]

To do: Create N random numbers of a sequence from -50 to 100 (SeqRandom function).

The resulting example:

enter n
>>15
[-23,13,-27,2,46,-26,10,92,60,-9,75,28,85,7,18]

Lab 2: Methods

To do: Create a function that searches in a sequence for the quantity of maximum elements.

The resulting example:

1 5 2 10 1 10
number of max elements is 2

✍ Algorithm:

 function findCountMax(a: sequence of integer):integer; begin var k:=a.Max(); foreach var i in a do if i=k then result+=1; end; begin var c:=Seq(1,5,2,10,1,10); c.Println(); println('number of max elements is ',findCountMax(c)); end.

To do: Create a function that calculates a sum of odd elements in a sequence. You should use IsOdd method within the foreach loop.

The resulting example:

1 5 2 10 1 10
sum of odd elements  7

Lab 3.

To do: Define a sequence using Seq method. Calculate a quantity of x (entered number) within the sequence. You should use count (condition) method.

The result examples:

-1 2 3 -5 2 -7 8 2 11
enter x: 2
there is 2 within the seq 3 times

✍ Algorithm:

 begin var c:=Seq(-1,2,3,-5,2,-7,8,2,11); c.Println(); var x:=readinteger('enter x:'); var n:=c.count(c->c=x); println(\$'there is {x} within the seq {n} times '); end.

To do: Define a sequence using Seq method. Calculate a number of negative elements in a sequence. You should use count (condition) method.

The resulting example:

-1 2 3 -5 6 -7 8 9 11
number of negative elements is 3

Sequence generators with lambda-expressions

To do: Using lambda expression, create a sequence of N even numbers starting at 10 (SeqGen should be used)

The resulting example:

Enter n
>> 7
10 12 14 16 18 20 22

To do: Create the following sequence: 1 3 9 27 81 243 729 2187 6561 19683 (SeqGen should be used)

The resulting example:

3 9 27 81 243 729 2187 6561 19683

To do: Create a sequence of 15 numbers: 2 1 0.5 0.25 0.125 0.0625 0.03125 0.015625 ... (specifying the first element and the function to get the next one) (SeqGen should be used)

The resulting example:

2  1  0.5  0.25  0.125  0.0625  0.03125  0.015625 0.0078125 0.00390625
0.001953125 0.0009765625 0.00048828125 0.000244140625 0.0001220703125

To do: Create the following sequence: 2017 2012 2007 2002 1997 1992 1987 1982 1977 1972 (SeqGen should be used)

The resulting example:

2017 2012 2007 2002 1997 1992 1987 1982 1977 1972

Lab:

To do: Create a sequence of N Fibonacci numbers

The resulting example:

Enter n
>>8
1 1 2 3 5 8 13 21

✍ Algorithm:

 begin var n:=readInteger('Enter n'); var sq:=SeqGen(n,1,1,(x,y)->x+y); sq.println(); end.
Lab:

To do: Create a sequence of N numbers generated by the iterative process: а1=2, аk=(аk-1+1)*аk-1, k = 2,3,… (SeqGen should be used)

The resulting example:

Enter n 7
2 6 42 1806 3263442 -1461943274 -757910022

✍ Algorithm:

 begin var n:=readInteger('Enter n'); var sq:=SeqGen(n,2,x->(x+1)*x); sq.println(); end.

To do: Create a sequence of N numbers generated by the iterative process: a1 = 5, ak = ak-1 / 2-1, k = 2,3, … (SeqGen should be used)

The resulting example:

Enter n
>> 9
5  1.5  -0.25  -1.125  -1.5625 -1.78125 -1.890625 -1.9453125 -1.97265625

To do: Create a sequence of N numbers generated by the iterative process: а1=1, а2=2, аkk-1+2аk-2, k=3,… (SeqGen should be used)

The resulting example:

Enter n
>>7
1 2 4 8 16 32 64

To do: Create a sequence of N numbers generated by the iterative process: а1=1, а2=2, аk=(аk-1k-2)/2, k=3,… (SeqGen should be used)

The resulting example:

Enter n
>> 7
1 2 1.5 1.75 1.625 1.6875 1.65625

Theory: Two-dimensional arrays

Lection in pdf format

• Definition
• A matrix or two-dimensional array is a rectangular table of numbers (or other elements of the same type). Each element of the matrix has two indices (row number and column number). • Matrix declaration
•  var a2: array [,] of integer; a2 := new integer[3,4]; // or: var a := new integer[3,4];
• Loop over the elements and pronting out:
•  for var i:=0 to a2.RowCount-1 do for var j:=0 to a2.ColCount-1 do a2[i,j] := i + j;   a2.Println; Println(a2); // [[0,1,2,3],[1,2,3,4],[2,3,4,5]]

Matrix filling

 begin var a := Matr(3,4,1,2,3,4,5,6,7,8,9,10,11,12); a.Println(3);   var a1 := MatrGen(3,4,(i,j)->i+j+0.5); // using arrow operator a1.Println(5,1); end.
• Filling with random numbers
•  begin var a := MatrRandomInteger(3,4); a.Println(4);   var a1 := MatrRandomReal(3,4,1,9); a1.Println(6,2); end.

Operations by rows and columns

 begin var a := MatrRandomInteger(3,4); a.Println;   a.Row(0).Sum.Println; a.Row(1).Average.Println; a.Row(2).Product.Println;   a.Col(0).Min.Println; a.Col(1).Max.Println; end.

Lab 0. Two-dimensional array

To do: Initialize a two-dimensional array named arr2d with given integer values, they are [[1, 2], [3, 4], [5, 6]].
1) First, output all the elements of the array.
2) After, output the following elements to the Output window (the elements to output are marked in red color):

(1, 2)
(3, 4)
(5, 6)

The result examples:

The array:
1  2
3  4
5  6
1-st element = 3, 2-nd element = 5

✍ Algorithm:

 begin var a := new integer[3,2];   for var i:=0 to a.RowCount-1 do for var j:=0 to a.ColCount-1 do a[i,j]:=readinteger;   println('The array:'); a.Println(); Println(a[1,0], a[2,0]); end.

To do: The air temperature values for 4 days are given, they are taken from three weather stations located in different regions of the country:

Station number 1-st day 2-nd day 3-d day 4-th day
1 -8 -14 -19 -18
2 25 28 26 20
3 11 18 20 25

That is, in a two-dimensional array it would look like this:

 t[0,0]=-8; t[0,1]=-14; t[0,2]=-19; t[0,3]=-18; t[1,0]=25; t[1,1]=28; t[1,2]=26; t[1,3]=20; t[2,0]=11; t[2,1]=18; t[2,2]=20; t[2,3]=25;

or it is better to use matr function:

 var t := matr(3,4,-8,-14,-19,-18,25,28,26,20,11,18,20,25);

To do:

1. Output value of the temperature at the 2nd weather station during the 4th day and at the 3rd weather station during the 1st day (your result must be 20 and 11).
2. Output the values of the temperature of all weather stations during the 2nd day (for loop is needed).
3. Output the values of the temperature of all weather stations during all days.
4. Calculate the average temperature at the 3rd weather station (for loop is needed).
5. Output the days and the weather stations’ numbers where the temperature was in the range of 2426 degrees Celsius.

The resulting example:

-8  -14  -19  -18
25   28   26   20
11   18   20   25

station number 1  day 0
station number 1  day 2
station number 2  day

To do: Fill a two-dimensional array 4-by-3 ([4,3]) with random integer values. Count positive elements within the array.

The resulting example:

The array:
2   5  -1
6   7   8
1   8   6
-3  1  -6
number of positive = 9

To do: Fill a two-dimensional array 4-by-5 ([4,5]) with random integer values. Create a function to find a minimum and maximum elements of the array (FindMinMaxArr).

Note: the signature (header) of the function should be as follows:

 function FindMinMaxArr(a: array [,] of integer): (integer, integer);

The resulting example:

The array:
10   2   9  3  4
-3 -10 -14 -4  2
2  -9  11  3 -10
-1 -13  -5 -2  3
min and max:
-14  11

Lab 1

To do: Fill a two-dimensional array 3-by-4 ([3,4]) using the rule:
each element equals to i-th row * j-th column + 0.5
The result examples:

0.5  1.5  2.5  3.5
1.5  2.5  3.5  4.5
2.5  3.5  4.5  5.5

✍ Algorithm:

 begin var a1 := MatrGen(3,4,(i,j)->i+j+0.5); a1.Println(5,1); end.

To do: Fill a two-dimensional array 4-by-5 ([4,5]) using the rule: all elements of the i-th row have the value 10 ∗ i.

The resulting example:

0    0    0    0    0
10   10   10   10   10
20   20   20   20   20
30   30   30   30   30

Lab 2

To do: Calculate sum in each row.

The result examples:

15  21   9  78
54  61   2  19
19  28  50  61
123 136 158

✍ Algorithm:

 begin var a := MatrRandomInteger(3,4); a.Println;   var Sums := ArrGen(a.RowCount,r -> a.Row(r).Sum); Sums.Println; end.

To do: Fill a two-dimensional array 4-by-5 ([4,5]) with random integer values. Calculate maximum element in each row.

The resulting example:

91   9  82  71  99
59  30  36  35  26
56  66  76   7  23
25  46  92  39  77
99 59 76 92

To do: Fill a two-dimensional array 4-by-5 ([4,5]) with random integer values in the range [0,10]. Create a function to return the array of the products (multiplications) in each column.

The resulting example:

6   4   6   8   0
6   4   5   3   7
0   3   5   2   8
6   4   6   3   8
result:  [0,192,900,144,0]

Lab 3

To do: Calculate a number of evens in each row.

The result examples:

49  98  78  27
44  65  50  74
68   1  75  59
2 1 2 1

✍ Algorithm:

 begin var a := MatrRandomInteger(3,4); a.Println;   var EvensCount := ArrGen(a.ColCount,c -> a.Col(c).Count(x->x.IsEven)); EvensCount.Println; end.

To do: Fill a two-dimensional array 4-by-5 ([4,5]) with random integer values. Create a procedure to print out the array of the quantities of the matrix elements in the range [0,10] by rows.

Note: the signature of the procedure must be as follows:

 procedure arrCount(a:array[,] of integer);

The resulting example:

59   6  34  70
11  28  10  31
8   0   9  80
1 1 3

Lab 4

To do: The matrix is given. Does the matrix contain the element equaled to x? x is entered.

The result examples:

3   8   5   7
1   7   6   1
1   1   5   9
>> 6
True

✍ Algorithm:

 function Contains(a: array [,] of T; x: T): boolean; begin Result := False; for var i:=0 to a.RowCount-1 do for var j:=0 to a.ColCount-1 do if a[i,j]=x then begin Result := True; exit; end; end;   begin var a := MatrRandomInteger(3,4,1,10); a.Println;   var x:=readinteger('enter x, please:'); var found := Contains(a,x); Println(found); end.

To do: Fill a two-dimensional array 3-by-4 ([3,4]) with random integer values. Create a function to print out the indices (row and column) of the array element equaled to entered x value. If x is not found, the function must return -1,-1.

Note: the signature of the function must be as follows:

 function indicesArr(a: array [,] of T; x: T): (integer,integer);

The resulting example:

1   2   2  10
3   4   7   5
3   5   5  10
(-1,-1)
---
3   6   7   1
7   1   8   5
10   2   4   6
(0,2)

To do: M-by-N integer matrix is given (it is filled with generated random numbers). Find the number of the first of its rows containing an equal quantity of positive and negative elements (zero matrix elements are not taken into account). If there are no such rows, then output 0.

Note: you can do the task using one of the following ways: 1) iterating over the elements of the array; 2) using mass operations by rows and columns (.Row)

The resulting example:

N:
>>3
M:
>>4
-5  -5   5  -1
1  -1   0   0
3  -3  -4   1

result: 2

Theory

• Classes are an expanded concept of data structures: like data structures, they can contain data members, but they can also contain functions as members.
• An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the variable.
• Classes are defined using either keyword class or keyword struct, with the following syntax:
• class class_name {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;

Where class_name is a valid identifier for the class, object_names is an optional list of names for objects of this class. The body of the declaration can contain members, which can either be data or function declarations, and optionally access specifiers.

• C++ classes encapsulate data and associated functionality into an object:
• // C++ class: class Cube { public: double getVolume(); // ... private: double length_; };
• Thus, Classes have the same format as plain data structures, except that they can also include functions and have these new things called access specifiers. An access specifier is one of the following three keywords: private, public or protected. These specifiers modify the access rights for the members that follow them.
• Encapsulation encloses data and functionality into a single unit (called a class)
• In C++, data and functionality are separated into two separate protections: public and private.
• The protection level determines the access that «client code» has to the member data or functionality:

• Public members can be accessed by client code. So, public members are accessible from anywhere where the object is visible. protected members are accessible from other members of the same class (or from their «friends»), but also from members of their derived classes.
• Private members cannot be accessed by client code (only used within the class itself). So, private members of a class are accessible only from within other members of the same class (or from their «friends»).
• Example of header-file code (Cube.h):

 #pragma once class Cube { public: double getVolume(); double getSurfaceArea(); void setLength(double length); private: double length_; };

Example of implementation-file code (Cube.cpp):

 #include "Cube.h" double Cube::getVolume() { return length_ * length_ * length_; } double Cube::getSurfaceArea() { return 6 * length_ * length_; } void Cube::setLength (double length) { length_ = length; }

Example of main-file code (main.cpp):

 #include "Cube.h" int main() { Cube c; c.setLength(3.48); double volume = c.getVolume(); std::cout << "Volume: " << volume << std::endl; return 0; }

Arguments passed by …

Identical to storage, arguments can be passed to functions in three different ways:

• Pass by value (default)
• Pass by pointer (modified with *)
• Pass by reference (modified with &, acts as an alias)

Values returned by …

Similarly, values can be returned all three ways as well:

• Return by value (default)
• Return by pointer (modified with *)
• Return by reference (modified with &, acts as an alias)
• Class destructor

• When an instance of a class is cleaned up, the class destructor is the last call in a class’s lifecycle.
• An automatic default destructor is added to your class if no other destructor is defined.
• The only action of the automatic default destructor is to call the default destructor of all member objects.
• An destructor should never be called directly. Instead, it is automatically called when the object’s memory is being reclaimed by the system:
• If the object is on the stack, when the function returns
• If the object is on the heap, when delete is used
• To add custom behavior to the end-of-life of the function, a custom destructor can be defined as:
• A custom destructor is a member function.
• The function’s destructor is the name of the class, preceded by a tilde ~.
• All destructors have zero arguments and no return type.
•  Cube::~Cube(); // Custom destructor

Lab 1:
To do: Create a Rectangle class and an object (i.e., a variable) of this class, called rect.
1) The class should contain four members:
— two data members of type int (member width and member height) with private access,
— and two member functions with public access: the functions set_values and area.

2) Define two member functions: set_values function should set the variables width and height to the values; are function should return width*height.

3) Create a Custom default constructor to have the initial values for width and height (set them to 5).

4) Set the width and height values for the rect object and print out the information about this object.

Expected output:

Lab 1:
>> 20
>> 2
rect area: 40

✍ Algorithm:

• To do the lab create empty console application with a name Lesson9. Add files: mainLab1.cpp, ImpLab1.cpp, HeaderLab1.h.
• Include all the needed libraries and files.
• 1.Create a Rectangle class:

• The class must be defined inside a header file. So, open the header file and add the code to define the class with two private data members, they are width and height; and two member functions with public access, they are set_values and area.
• class Rectangle {
private:
int width, height;
public:
void set_values(int, int);
int area(void);
} ;

• Here Rectangle is the class name (i.e., the type).
• The functions set_values and area have a public access, it means that they can be accessed from inside the main function by simply inserting a dot (.) between object name and member name (e.g. rect.set_values…).
• width and height members cannot be accessed from outside the class, since they have private access and they can only be referred to from within other members of that same class.
• 2. Define two member functions:

• Since members width and height have private access, access to them from outside the class is not allowed. So, we should define a member function to set values for those members within the object: the member function set_values.
• Let’s create the definition of set_values member function. We’re going to have a member of a class outside the class itself, so, we have to use scope operator (::, two colons). You should create the definition of the function inside the implementation file:
• void Rectangle::set_values(int x, int y) {
width = x;
height = y;
}

The scope operator (::) specifies the class to which the member being defined belongs, granting exactly the same scope properties as if this function definition was directly included within the class definition. For example, the function set_values has access to the variables width and height, which are private members of class Rectangle, and thus only accessible from other members of the class, such as this.
• The second member function, that is area function, we’re going to have inside the class itself, just to try different ways of definition. So, return to the header file and add the definition inside the class next to int area(void) statement:
• int area() {return width*height;}

The function is automatically considered an inline member function by the compiler.

3) Create a Custom default constructor to have the initial values for width and height (set them to 5).

• Add the declaration of a Custom default constructor inside the public access of the class (header file):
• public: // you had this code
Rectangle();
void set_values(int, int); // you had this code
//...

• Open your implementation file to add the definition of that constructor:
•  Rectangle::Rectangle() {
width = 5;
height = 5;
}

4) Set the width and height values for the rect object and print out the information about this object:

• Open a main file in the editor window. You should create an object (i.e., a variable) of the Rectangle class, called rect. And after this, ask user to input the width and height values. Call the set_values function and output the result:
• int main() {
Rectangle rect;
int w, h;
cin >> w;
cin >> h;
rect.set_values(w, h);
cout << "rect area: " << rect.area() << endl;
system("pause");
return 0;
}

• Run the program and check the output.

To do: Create a LessonDate class to output the date of a lesson.

1) The class should contain the following members:
— three data members of type int with private access, they are day, month and year;
— and two member functions with public access:
void setDate(int, int, int); to set the date for the next lesson and
void getDate(); to print out the date of the lesson.

2) Create a three argument constructor to have the initial values for date; in the constructor body call the setDate function to set the date.

3) Inside the main function create an object (i.e., a variable) of this class, called objLesson. Set the values of three parameters — day, month and year. Print out the information about this object.

Expected output:

Lesson date: 11.11.2021
Please, enter day, then month and year of the next lesson
28
12
2020
Lesson date: 28.12.2020

Lab 2:
To do: Create a Cube class.
1) The class should contain four members:
length_ data member of type double with private access,
— three member functions with public access: the functions double getVolume(); , double getSurfaceArea(); and void setLength(double length);.

2) Give the definitions (implementations) of those functions:
getVolume() function have to calculate a volume of the cube: length_ * length_ * length_;
getSurfaceArea() function have to calculate a Surface Area of the cube: 6 * length_ * length_;;
setLength(double length) function have to set the value for the cube length.

3) Create a Custom default constructor to have the initial values for length_ (set it to 1).

4) Inside the main cpp file create double cube_on_stack() function to create an object (i.e., a variable) of this class and get volume of it. This object will be in a stack memory. Also, inside the main function create a new cube of length 10 which is going to be in heap memory. Set the values. Print out the information about those objects.

5) Create a custom destructor to delete an information about the cube.

Expected output:

Lab 2:
Volume of c cube:
Destructor called for cube with length 2
Volume of c cube in the heap memory: 27
Destructor called for cube with length 3

✍ Algorithm:

• To do the lab create an empty console application with a name Lesson9Lab2. Create new files: mainLab2.cpp, ImpLab2.cpp, HeaderLab2.h.
• Include all the needed libraries and files.
• 1.The class should contain four members:

• The interface of the class must be inside a header file. So, open the header file and add the code to define the class with one private data member, it is length_ of a cube; and three member functions with public access, they are getVolume(), getSurfaceArea() and setLength(double length).
• class Cube
{
public:
double getVolume();
double getSurfaceArea();
void setLength(double length);
private:
double length_;
};

• Here Cube is the class name (i.e., the type.
• The functions getVolume(), getSurfaceArea() and setLength(double length) have a public access, it means that they can be accessed from anywhere where the object is visible.
• length_ member cannot be accessed from outside the class, since it has a private access and it can only be accesses from within the class itself.
• 2. Give the definitions (implementations) of the functions:

• Let’s create the definition of setLength member function. We’re going to have a member of a class outside the class itself, so, we have to use scope operator (::, two colons). You should create the definition of the function inside the implementation cpp file:
• void Cube::setLength(double length) {
length_ = length;
}

The scope operator (::) specifies the class to which the member being defined belongs, granting exactly the same scope properties as if this function definition was directly included within the class definition. For example, the function setLength has access to the variable length_, which is a private member of the class Cube, and thus only accessible from other members of the class, such as this.
• The second and th third member functions are getVolume and getSurfaceArea function, we’re going to have them inside the implementation file too:
• double Cube::getVolume() {
return length_ * length_ * length_;
}
double Cube::getSurfaceArea() {
return 6 * length_ * length_;
}

The getVolume function will return the volume of that cube, for which this function will be called.
The getSurfaceArea function will return the surface area of that cube, for which this function will be called.

3) Create a custom default constructor to have the initial values for length_ (set it to 1).

• Add the declaration of a custom default constructor inside the public access of the class (header file):
• public: // you had this code
Cube();
//...

• Open your implementation file to add the definition of that constructor:
•  Cube::Cube() { length_ = 1; }

4) Inside the main cpp file create double cube_on_stack() function to create an object (i.e., a variable) of this class and get volume of it:

• Open a main file in the editor window. Before the main function add the code to create cube_on_stack() which will create the object of Cube class and return the volume of this object:
• double cube_on_stack() {
Cube c;
c.setLength(2);
return c.getVolume();
}
int main() {
// ...
}

• Inside the main function ptint out the message and call that function:
• int main() {
cout << "Volume of first cube: " << endl;
cube_on_stack();
}

Also, inside the main function create a new cube of length 10 which is going to be in heap memory. Set the values. Print out the information about those objects.

• Then, inside the main function you should create a new cube of length 10 which is going to be in heap memory:
•   Cube * pcube = new Cube;
pcube->setLength(3);
cout << "Volume of c cube in the heap memory: " << pcube->getVolume() << endl;

To have an object to be stored in the heap memory you should use star (*) sign. Such objects or instances to the objects can be used together with arrow operator to access their members.

5) Create a custom destructor to delete an information about the cube.

• Open header file to declare a class destructor, which will be called to clean up the instance of the class. Add it right after the class constructor to the public protection level:
• ~Cube();

• Add the implementation for that destructor inside implementation file:
• Cube::~Cube(){
cout << "Destroyed cube with length " << length_;
}

• Return to the main file and add the delete keyword to clean up the memory of the pcube object:
• // ...
delete pcube;

If the object is on the heap, the destructor is only called when that delete keyword is used, to reclaim that memory that the object was using.
• Run the program and check the output.

To do: Create a Student class to output information about the students.

1) The class should contain the following members:
— two data members of type string with private access, they are name and surname, and one data member of type int - age;
— and two member functions with public access:
void set_info(string, string, int); to set the information about the student
and void get_info(void); to print out the information.

2) Create a three argument constructor to have the initial values for student.

3) Inside the main cpp file create void student_on_stack() function to create an object (i.e., a variable) of this class and get volume of it. This object will be in a stack memory. Also, inside the main function create a new student with some info about, which is going to be in a heap memory. Print out the information about those objects.

4) create a custom destructor to delete an information about student.

Expected output:

info about student1: name: Johnsurname: Ivanovage: 20
Destructor called for Student Ivanov
info about student2: name: Petersurname: Panage: 17
Destructor called for Student Pan

To do: Create a BookShop class to store and output an information about the selling books.

1) The class should contain the following members:
data members with private access:
title_ (a title of a book) of type string;
author_ (an author of a book) of type string;
_price (a price of a book) of type double;
_discount (a discount for a price of a book) of type int.
data members with public access:
- void getInfo() function to print out the information about the book;
- void set_info(string title, string author, double price, int discount) function to set the information about the book;
- double getTotalPrice() function calculate the price of a book considering the discount (price - (price * discount)).

2) Create a four argument constructor to have the initial values for books.

3) Create two objects and print out the information about those objects. Print out the info about the price considering the discount.

Expected output:

// book 1 info:
Dostoevsky Demons 205 roubles, discount 0.05, total price 194,75 roubles
// book 2 info:
Kuprin Duel 125 roubles, discount 0.1, total price 112,5 roubles

Lab 3:
To do:

1) Create a base class called Professor.
The class should contain the following members:
- Name_ data member of string type with protected access,
- Age_ data member of int type with private access,
- Rating_ data member of int type with protected access,
- Subjects_ data member of list type with private access,

Three member functions with public access:
- void getInfo(); (to output information about a professor),
- void checkRating(); (to check a rating and output some message).

2) Create a derived class called ItProfessors. The class should have its own methods called void MoreInfo(); (to output an addition information) and incRating(); (to increase a rating and output some info).

3) Create a derived class called MathProfessors. The class should have its own methods called void MoreInfo(); (to output an addition information) and incRating(); (to increase a rating and output some info) .

4) Create an object of the base class inside the main function. Call all existing methods of the class for that object.

5) Create object of the derived classees inside the main function. Call all existing methods of the class.

Expected output:

Lab 3:
name = Ivanov, age =56, subjects = Math
name = Johnson, age =50, subjects = Basics_of_programming
name = Peterson, age =50, subjects = geometry
Ivanov is good in programming
name = Petrov, age =45, subjects =
IT area professor Johnson's rating was increased and now it is 4
IT area professor Johnson's rating was increased and now it is 5
IT area professor Johnson's rating was increased and now it is 6
Johnson has good rating
Ivanov has no enouph good rating

✍ Algorithm:

• To complete the task you should create a L10lab3.cpp file only. All code should be inside one file.
• Include all the needed libraries:
• #include
#include<string>
#include<list>
#include <assert.h>
using namespace std;

Create a base class:

class Professor {
private:
// ...
protected:
// ...
public:
// ...
};

• Data members should be declared inside the private area:
•         int Age_;
list Subjects_;

• Since the Name_ and Rating_ members must be accessible from the derived class, we should declare them inside the protected area:
•
string Name_;
int Rating_;

• Now we're going to create a constructor with three arguments. It should be placed inside the public area. Check the values of passed parameters using assert statements:
• Professor(string name, int age, int count) :
Name_(name), Age_(age), Rating_(count)
{
assert(name != "");
assert(age >= 20);
assert(age >=0);
}

• Let's create a getInfo() method to output all the information. To output the list we're going to use a for : loop, iterating over the elements of the list. The method should be inside the public area:
• void getInfo() {
cout << "name = " << Name_;
cout << ", age =" << Age_;
cout << ", subjects = ";
for (string subj : Subjects_) {
cout << subj << " ";
}
cout << endl;
}

• We're going to create a member function to add a new value to the list of subjects. In order to do it we need to use push_back() method:
Subjects_.push_back(subject);
}

Create a derived class:

• After the closing curly brace of the base class, we're going to add the code of a derived class to store information about IT professors. Let's declare the class:
• class ItProfessor:public Professor {
public:
// ...
};

• This class inherits all the members of the base Professor class. But we need to have public default constructor to have those members accessible outside of this class. Let's add the code of constructor in the public area:
• ItProfessor(string name, int age, int count):Professor (name, age, count){
}

• The derived class can have its own specific member. Let's add it in the public area as well:
• void moreInfo(){
cout <" is good in programming" << endl;;
}

• We're going to create one more derived class with a name MathProfessor:
• class MathProfessor:public Professor {
public:
// ...
};

• We need to have public default constructor to have the members from the base class accessible outside of this class:
• MathProfessor(string name, int age, int count):Professor (name, age, count){
}

• Let's create the objects of these classes inside the main function:
• ItProfessor IvProfessor("Ivanov", 56,5);
ItProfessor JohnProfessor("Johnson", 50, 5);
MathProfessor PeterProfessor("Peterson", 50, 5);

• We are able to evoke all of those methods which were implemented within the base class:
IvProfessor.getInfo();
JohnProfessor.getInfo();
PeterProfessor.getInfo();
IvProfessor.moreInfo();

• Now, let's create an object of the base class:
•          Professor pr("Petrov", 45, 6);
pr.getInfo();
// pr.moreInfo(); error! is not available for the base class

• Both of the derived classes should have a method to increase a rating. The names of the methods should be the same, but their implementations must be different. We can call it Polymorphism. Let's add the following method to ItProfessor class:
• void incRating() {
cout << "IT area professor ";
Rating_++;
cout << Name_ << "'s rating was increased and now it is " << Rating_ << endl;
}

• The same method for MathProfessor class will be a bit different:
• void incRating() {
cout << " Math area professor ";
Rating_++;
cout << Name_ << "' rating is " << Rating_ << endl;
}

• Now, let's add a method to check the rating. Since the method must be accessible in the derived classes, it should be defined inside the base class - Professor:
• void checkRating() {
if (Rating_ < 3) {
cout << Name_<< " has no enouph good rating" << endl;
}
else {
cout << Name_ << " has good rating" << endl;
}
}

• Now, let's increase the rating of the object by calling the incRating() method:
• JohnProfessor.incRating();
JohnProfessor.incRating();
JohnProfessor.incRating();

• In order to call the checkRating() method we should use the pointers. Inside the main function we're going to assign address of the object of the derived class to a pointer of the base class:
• Professor *p1 = &JohnProfessor;
Professor *p2 = &IvProfessor;

• Now, we can call the method to check the rating:
• p1->checkRating();
p2->checkRating();

• Run the program.
1) Create a base class called Animals.
The class should contain the following data members:
- Name_ data member of string type with protected access,
- Class_ data member of int type with private access (class of vertebrate animal),
- Countries_ data member of List type with private access (countries of residence),
- Population_ data member of int type with private access;
The class should contain the following member functions with public access:
- void getInfo(); (to output information about an animal),
- void addCountry(); (to add a new country to the list and output new list),
- list getAnimalsCountry(); (to return the list of animals by the specified country) .
2) Create a derived class called AfricanAnimals. Class inherits all the members of Animals class. The class should have its own method called void MoreInfo(); (to output an addition information about African animals).

3) Create an object of the base class inside the main function. Call all existing methods of the class for that object.

4) Create an object of the derived class inside the main function. Call all existing methods of the class.

Note: Create a header file for classes.

Expected output:

name = polar_bear
сlass = mammal
population =  20000
name = elephant
сlass = mammal
population =  20000
countries = Africa India

the animals from which country? USA
polar_bear

Theory

Sequence

• Elements in sequence containers are ordered in a strict linear sequence. Individual elements are accessed by their position in this sequence.

• Each element keeps information on how to locate the next element, allowing constant time insert and erase operations after a specific element (even of entire ranges), but no direct random access.
• How to create? List node class:

 template struct node { T data; node* next; node(T data, node* next) { this->data = data; this->next = next; } };

Пустой список:

 node* p = null;

Adding an item to the top of the list:

 p = new node(5,p);
• the new operation allocates dynamic memory to a single node
• after allocating dynamic memory, the constructor is called with the specified parameters
• Example:

 p = new node(3,p); Function templates with lists

 template void add_first(T data, node*& p) { p = new node(data,p); } int main() { node* p = nullptr; add_first(5,p); // two stages of compiling a function template add_first(3,p); }

Creating and Printing a singly-linked (forward) list:

 template void print(node* p) { while (p) { cout << p-> data; p = p->next; } } int main() { node* p = nullptr; add_first(5,p); add_first(3,p); print(p); }

Freeing the memory occupied by a singly linked list

 template void free(node* p) { while (p) { auto p1 = p; p = p->next; delete p1; } } int main() { node* p = nullptr; add_first(5,p); add_first(3,p); print(p); //free(p); //p = nullptr; }

Complicated:

Construct forward_list object
 // forward_list constructors #include #include   int main () {   std::forward_list first; // (1) default: empty std::forward_list second (3,77); // (2) fill: 3 seventy-sevens std::forward_list third (second.begin(), second.end()); // (3) range initialization std::forward_list fourth (third); // (4) copy constructor std::forward_list fifth (std::move(fourth)); // (5) move ctor. (fourth wasted) std::forward_list sixth = {3, 52, 25, 90}; // (6) initializer_list constructor   std::cout << "first:" ; for (int& x: first) std::cout << " " << x; std::cout << '\n'; std::cout << "second:"; for (int& x: second) std::cout << " " << x; std::cout << '\n'; std::cout << "third:"; for (int& x: third) std::cout << " " << x; std::cout << '\n'; std::cout << "fourth:"; for (int& x: fourth) std::cout << " " << x; std::cout << '\n'; std::cout << "fifth:"; for (int& x: fifth) std::cout << " " << x; std::cout << '\n'; std::cout << "sixth:"; for (int& x: sixth) std::cout << " " << x; std::cout << '\n';   return 0; }

Expected output:

first:
second: 77 77 77
third: 77 77 77
fourth:
fifth: 77 77 77
sixth: 3 52 25 90

(1) — default — Constructs an empty container, with no elements.
(2) — fill constructor — Constructs a container with n elements. Each element is a copy of val (if provided).
(3) — range constructor — Constructs a container with as many elements as the range [first,last), with each element emplace-constructed from its corresponding element in that range, in the same order.
(4) — copy constructor (and copying with allocator) — Constructs a container with a copy of each of the elements in fwdlst, in the same order.
(5) — move constructor (and moving with allocator) — Constructs a container that acquires the elements of fwdlst. If alloc is specified and is different from fwdlst‘s allocator, the elements are moved. Otherwise, no elements are constructed (their ownership is directly transferred). fwdlst is left in an unspecified but valid state.
(6) — initializer list constructor — Constructs a container with a copy of each of the elements in il, in the same order.

Forward_list::assign

Syntax:
range (1)

template
void assign (InputIterator first, InputIterator last);

fill (2)

void assign (size_type n, const value_type& val);

initializer list (3)

void assign (initializer_list il);
• In the range version (1), the new contents are elements constructed from each of the elements in the range between first and last, in the same order.
• In the fill version (2), the new contents are n elements, each initialized to a copy of val.
• In the initializer list version (3), the new contents are copies of the values passed as initializer list, in the same order.
• Any elements held in the container before the call are destroyed and replaced by newly constructed elements (no assignments of elements take place).
Parameters:
first, last
Input iterators to the initial and final positions in a sequence. The range used is [first,last), which includes all the elements between first and last, including the element pointed by first but not the element pointed by last.
The function template argument InputIterator shall be an input iterator type that points to elements of a type from which value_type objects can be constructed.
n
New size for the container.
Member type size_type is an unsigned integral type.
val
Value to fill the container with. Each of the n elements in the container will be initialized to a copy of this value.
Member type value_type is the type of the elements in the container, defined in forward_list as an alias of its first template parameter (T).
il
An initializer_list object. The compiler will automatically construct such objects from initializer list declarators. Member type value_type is the type of the elements in the container, defined in forward_list as an alias of its first template parameter (T).
Example:

 #include #include   int main () { std::forward_list first; std::forward_list second;   first.assign (4,15); // 15 15 15 15   second.assign (first.begin(),first.end()); // 15 15 15 15   first.assign ( {77, 2, 16} ); // 77 2 16   std::cout << "first contains: "; for (int& x : first) std::cout << ' ' << x; std::cout << '\n';   std::cout << "second contains: "; for (int& x : second) std::cout << ' ' << x; std::cout << '\n';   return 0; }

Output:

first contains: 77 2 16
second contains: 15 15 15 15
Assignment operator = with forward_list

Syntax:
copy (1)

forward_list& operator= (const forward_list& fwdlst);

move (2)

forward_list& operator= (forward_list&& fwdlst);

initializer list(3)

forward_list& operator= (initializer_list il);

Assigns new contents to the container, replacing its current contents.

• The copy assignment (1) copies all the elements from fwdlst into the container (with fwdlst preserving its contents).
• The move assignment (2) moves the elements of fwdlst into the container (x is left in an unspecified but valid state).
• The initializer list assignment (3) copies the elements of il into the container.
• The container preserves its current allocator, except if the allocator traits indicate fwdlst’s allocator should propagate. This allocator is used (through its traits) to allocate or deallocate if there are changes in storage requirements, and to construct or destroy elements, if needed.
Parameters:
fwdlst
A forward_list object of the same type (i.e., with the same template parameters, T and Alloc).
il
An initializer_list object. The compiler will automatically construct such objects from initializer list declarators. Member type value_type is the type of the elements in the container, defined in forward_list as an alias of its first template parameter (T).
Example:

 #include #include   template Container by_two (const Container& x) { Container temp(x); for (auto& x:temp) x*=2; return temp; }   int main () { std::forward_list first (4); // 4 ints std::forward_list second (3,5); // 3 ints with value 5   first = second; // copy assignment second = by_two(first); // move assignment   std::cout << "first: "; for (int& x : first) std::cout << ' ' << x; std::cout << '\n';   std::cout << "second: "; for (int& x : second) std::cout << ' ' << x; std::cout << '\n';   return 0; }

In the first assignment, second is an lvalue: the copy assignment function is called.
In the second assignment, the value returned by by_two(first) is an rvalue: the move assignment function is called.
Output:

first: 5 5 5
second: 10 10 10
resize () function
void resize (size_type n);
void resize (size_type n, const value_type& val);

Resizes the container to contain n elements.
If n is smaller than the current number of elements in the container, the content is trimmed to contain only its first n elements, removing those beyonf (and destroying them).
If n is greater than the current number of elements in the container, the content is expanded by inserting at the end as many elements as needed to reach a size of n elements. If val is specified, the new elements are initialized as copies of val, otherwise, they are value-initialized.
Example

 // resizing forward_list #include #include   int main () { std::forward_list mylist = {10, 20, 30, 40, 50}; // 10 20 30 40 50 mylist.resize(3); // 10 20 30 mylist.resize(5,100); // 10 20 30 100 100   std::cout << "mylist contains:"; for (int& x: mylist) std::cout << ' ' << x; std::cout << '\n';   return 0; }
mylist contains: 10 20 30 100 100
insert_after function

Example

 // forward_list::insert_after #include #include #include   int main () { std::array myarray = { 11, 22, 33 }; std::forward_list mylist; std::forward_list::iterator it;   it = mylist.insert_after ( mylist.before_begin(), 10 ); // 10 // ^ <- it it = mylist.insert_after ( it, 2, 20 ); // 10 20 20 // ^ it = mylist.insert_after ( it, myarray.begin(), myarray.end() ); // 10 20 20 11 22 33 // ^ it = mylist.begin(); // ^ it = mylist.insert_after ( it, {1,2,3} ); // 10 1 2 3 20 20 11 22 33 // ^   std::cout << "mylist contains:"; for (int& x: mylist) std::cout << ' ' << x; std::cout << '\n'; return 0; }

Output:

mylist contains: 10 1 2 3 20 20 11 22 33

• Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions.
• template < class T, class Alloc = allocator > class list;
• List containers are implemented as doubly-linked lists.
• Doubly linked lists can store each of the elements they contain in different and unrelated storage locations. The ordering is kept internally by the association to each element of a link to the element preceding it and a link to the element following it.
• Doubly linked list keeps two links per element: one pointing to the next element and one to the preceding one, allowing efficient iteration in both directions, but consuming additional storage per element and with a slight higher time overhead inserting and removing elements.
• Compared to other base standard sequence containers (array, vector and deque), forward_list perform generally better in inserting, extracting and moving elements in any position within the container, and therefore also in algorithms that make intensive use of these, like sorting algorithms.

* Information has taken from: http://www.cplusplus.com/reference/forward_list/forward_list/.

To do: Create a linked lists with three elements (nodes) named root, first and second. Create a function to print the elements of the list.

Expected output:

Lab 0
1 2 3

✍ How to do:

1. Create an empty console application. Add the source file and open its code. Include all the necessary libraries and main function.
2. First of all, let’s create a linkled list. It can be done as a structure above the main function:
int data;
};

data is to store a value of the element, and *next is a pointer to point at the memory address of the next list element.
4. In the main function, three linked lists must be declared:

6. After we’ve declared lists, let’s assign the values:
7. root->data = 1;
root->next = second;

second->data = 2;
second->next = third;

third->data = 3;
third ->next = NULL;

data is a value of the element, while next is a stored address to the next element. 8. Now, let’s create a function to print out the values of the list. It will have an argument — a pointer to the root element. Add the following code above the main function:
while (root)
{
printf("%d ", root->data);
root = root->next;
}
}

We use the while loop to iterate over the list’s nodes. Each iteration we assign the address of the next element to the root. The value of the next of the last element equals to 0 (NULL), thus the while loop will stop.
10. Call this function inside the main function:

12. Run the application and check the output.
Lab 2: Circular lists:
To do: Create a circular list with three nodes. Assign values for nodes and print them out.

Expected output:

List contains the following nodes:
1 2 3

✍ How to do:

1. Create an empty console application. Add the source file and open its code. Include all the necessary libraries and main function.
2. First of all, let’s create a structure which represents a node. It can be done above the main function:
3. struct Node
{
int data;
struct Node *next;
};

4. Now, we’re going to сreate a function to add the first node to the list. This means the list is empty. The function will take two arguments: an address of node to create and the data to store it in node being created. Add the signature of the function above the main:
5. struct Node *addToEmpty(struct Node *last, int data)
{
// ...
};

6. Inside this function it is better to check if the list is really empty. If it is not, we should return the address of the created node to work them inside another function.
7. if (last != NULL) return last;

8. Then, we need to allocate a dynamic memory for a new node. Let’s call this node temp:
9. struct Node * temp = new Node;

10. Now, we must assign data value and address value to the node. We have to do it to make the list circular:
11. temp->data = data; // we assign passed data to the node
last = temp; // since we have no anything inside list, so last node will be the only one
last->next = last; // this line makes link circular; the node actually points to itself (because the only one)
return last;

12. Now, we’re going to сreate a function to add the node to the list, which is not empty. The function will take two arguments: an address of node to create and the data to store it in node being created. Add the signature of the function above the main:
13. struct Node *addEnd(struct Node *last, int data)
{
// ...
}

14. Inside this function it is better to check if the list is empty. If it is, we should return the calling of addToEmpty function:
15. if (last == NULL)

16. If the function is not empty, we need to allocate a dynamic memory for a new node:
17. struct Node * temp = new Node;

18. After, we must assign data value and address value to the node. We have to do it to make the list circular:
19. temp->data = data;
temp->next = last->next; // the address of the previous node is assigned
last->next = temp; // assign the address of the current node to the previous node
last = temp;
return last;

20. Now we’re going to create a function to traverse the list. It will have single argument — a pointer to the list to be traversed. Add the signeture begore main:
21. void traverse(struct Node *first)
{
//...
}

22. Inside the function we should create a pointer to the list:
23. struct Node *tmp = first;

24. After, we’re going to loop over the list nodes and print them out:
25. if (first != NULL) {
do
{
cout << tmp->data << " ";
tmp = tmp->next; // move to the next node
} while (tmp != first);
}

26. Now, we can turn to the main function and create the future list. The NULL must be assigned to it (it is empty).
27. struct Node *last = NULL;

28. To add the first node we should call the addToEmpty() function, since it is empty. To create the second and third nodes we should call the addEnd() function. The values must be 1, 2 and 3:
29. last = addToEmpty(last, 1); // data = 1

30. At last, we must call the function to print the nodes out:
31. cout << "List contains the following nodes:" << endl;
traverse(last->next);

32. Run the application and check the output.
Lab 3: Forward lists: Using list methods
To do: Create a solution to test the methods of a list type. Create three lists and use the following methods with them:

1. insert_after
2. emplace_after
3. reverse
4. splice
5. sort
6. merge
7. remove
8. remove_if

Expected output:

Lab 3
list 1: 5 4 3 2
list 2: 1 4 7 6
list 3: 9 8 7
1. insert_after method, list1 (insert 8 number in the position 2):
5 8 4 3 2
2. emplace_after method, list3 (add 5 to list3 in the position 2):
9 5 8 7
3. reversed method(list1):
2 3 4 8 5
4. splice method (list1 with list3):
after splice, list1:
2 9 5 8 7 3 4 8 5
after splice, list 3:

5. sort method, list 1:
2 3 4 5 5 7 8 8 9
sort method, list 2:
1 4 6 7
6. merged method (list1 and list2):
1 2 3 4 4 5 5 6 7 7 8 8 9
7. remove method, list1 (2 is removed):
1 3 4 4 5 5 6 7 7 8 8 9
8. remove_if method, list1 (numbers>4 are removed):
1 3 4 4

✍ How to do:

• To perform the lab, create an empty console application with a name Lesson12. Add file: L12Lab3main.cpp.
• Include all the necessary libraries.
• Create int main function that returns 0.
• In the main function declare three lists, initialize them with values and print them out to the console:
• #include <forward_list>
//...
forward_list<int> list1 = { 5,4,3,2 };
forward_list<int> list2 = { 1,4,7,6 };
forward_list<int> list3 = { 9,8,7 };
cout << "\n list 1: ";
for (auto &elem : list1)
cout << elem << " ";
cout << "\n list 2: ";
for (auto &elem : list2)
cout << elem << " ";
cout << "\n list 3: ";
for (auto &elem : list3)
cout << elem << " ";

Test the following functions and consider results:

1. insert_after method
2. Insert 8 into 2 position of list1:

cout << "\n 1. insert_after function, list1 (insert 8 number in the position 2):" << endl;
list1.insert_after(list1.begin(), 8);
for (auto &elem : list1)
cout << elem << " ";

3. emplace_after
4. Insert 5 into 2 position of list3:

cout << "\n 2. emplace_after function, list3 (add 5 to list3 in the position 2):" << endl;
list3.emplace_after(list3.begin(), 5);
for (auto &elem : list3)
cout << elem << " ";

5. reverse
6. Reverse list1 by yourself and output the result.

7. splice_after:
8. You should splice list3 from the position 2 of list2

list1.splice_after(list1.begin(), list3);
cout << "\n 4. splice function (list1 with list3):" << endl;
cout << "\n after splice, list1:" << endl;
for (auto &elem : list1)
cout << elem << " ";
cout << "\n after splice, list 3:" << endl;
for (auto &elem : list3)
cout  << elem << " "; //must become empty

9. sort
10. Sort list1 and list2 by yourself and output the results.

11. merge:
12. Merge list1 and list2. Note that lists must be sorted:

list1.merge(list2);
cout << "\n 6. merged function (list1 and list2):" << endl;
for (auto &elem : list1)
cout << elem << " ";

13. remove
14. Remove 2 from the list1:

list1.remove(2);
cout << "\n 7. remove function, list1 (2 is removed):" << endl;
for (auto &elem : list1)
cout << elem << " ";

15. remove_if
16. Remove all the elements which are greater than 4 from the list1:

list1.remove_if([](int n) {
return n > 4;
});
cout << "\n 8. remove_if function, list1 (numbers>4 are removed):" << endl;
for (auto &elem : list1)
cout << elem << " ";

• Run the program.

Theory: slices, Sorting algorithms

Lection in pdf format

+ and * operations for arrays
• a + b – concatenation of two arrays into result array
• a * N – concatenation of N copies of a into result array
• Slices

• Array slice is a subarray of original array
• Slices are read-only and cannot be assigned values.
• The slice type is the same as the array.
• Slices work with arrays, strings, and lists.
• It has one of two forms: a[x:y] or a[x:y:step]. Expressions x and y can be omitted.
• Examples:

 begin var a := Arr(0,1,2,3,4,5,6,7,8,9); println(a[:4]); // 0 1 2 3 println(a[4:]); // 4 5 6 7 8 9 println(a[:a.Length-1]); // 0 1 2 3 4 5 6 7 8 println(a[:]); // 0 1 2 3 4 5 6 7 8 9 (copy of a) println(a[::2]); // 0 2 4 6 8 println(a[1::2]); // 1 3 5 7 9 println(a[4:1:-1]); // 4 3 2 println(a[::-1]); // 9 8 7 6 5 4 3 2 1 0 (reverse of a) end.

Array sorting algorithms

Selection sort
• this algorithm iterates over the array over and over, moving one value to the correct position
• it selects the smallest unsorted value
• so, at the next iteration, we will find the minimum in the array after the current element and change it with it, if necessary. Thus, after the i-th iteration, the first i elements will stay in their places.
• the sorted portion of the array is at the beginning
•  1 2 3 4 5 6 7 8 9 10 11 procedure SelectionSort(a: array of integer); begin for var i := 0 to a.High-1 do begin var (min,imin) := (a[i],i); for var j := i + 1 to a.High do if a[j] < min then (min,imin) := (a[j],j); Swap(a[imin],a[i]); end; end; Bubble sort
• Let’s iterate over the array from left to right.
• If the current element is greater than the next one, we swap them.
• We do this until the array is sorted.
• Note that after the first iteration, the largest element will be at the end of the array, in the correct place.
• After two iterations, the two largest items will be in the correct place, and so on.
•  1 2 3 4 5 6 7 procedure BubbleSort(a: array of integer); begin for var i := 0 to a.High-1 do for var j := a.High downto i+1 do if a[j] < a[j-1] then Swap(a[j], a[j-1]); end;
Insertion sort

The Insertion sort algorithm iterates through the elements of the array one at a time, and places each new taken element in a suitable place among the previously ordered elements.

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 procedure SortByInsert(a: array of integer); begin for var i:=1 to a.High do begin var x := a[i]; var j := i - 1; while (j >= 0) and (x < a[j]) do begin a[j+1] := a[j]; j -= 1; end; a[j+1] := x; end; end;
Standard sort
 Sort(a); SortByDescending(a);

Slices

Lab 1:
To do: an array A of size N and an integer K (1 <= K <= N) are given. Print its elements with ordinal numbers (i.e. indexes) that are multiples of K (i.e. devisable by K):

Ak, A2 * k, A3 * k ...

Do not use the if statement.

✍ Algorithm:

To do: An array of size N is given. Print its elements in reverse order.

The resulting example:

how many elements
>> 10
array:
25 5 68 42 48 32 100 77 50 47
result:
47 50 77 100 32 48 42 68 5 25

To do: An array A of size N is given (N is an even number). Display its elements with even ordinal numbers in ascending order of ordinal numbers:

а2, а4, а6, ... аn

Do not use the conditional operator.

The resulting example:

>>10
64 64 21 72 22 82 62 50 30 25
64 72 82 50 25

To do: An array A of size N is given (N is an odd number). Display its elements with odd ordinal numbers, i.e. in descending order of ordinal numbers:

аn, аn-2, аn-4, ... а1

Do not use the conditional operator.

The resulting example:

>>9
array: 89 67 32 43 49 67 93 75 31
result: 31 93 49 32 89

Lab 2:

To do: An array A of size N is given. First, output its elements with even ordinal numbers (in ascending order of ordinal numbers), and then — elements with odd ordinal numbers (also in ascending order of ordinal numbers):

a2, a4, a6, ... a1, a3, a5 ...

Do not use conditional operator.

The resulting example:

how many elements
>> 9
4 96 8 94 14 80 93 49 6
96 94 80 49 4 8 14 93 6

✍ Algorithm:

 begin var n:=ReadInteger('how many elements'); var a:=arrRandomInteger(n); a.Println; var slice:=a[1::2]+a[::2]; slice.Print end.

To do: An array A of size N is given (N is odd number). First, output its elements with odd indexes (in ascending order of their ordinal numbers), and then — elements with even indexes (in descending order of ordinal numbers). Create a slice to store a concatenation of those two slices:

a2, a4, a6, ..., a7, a5, a3, a1

Do not use conditional operator.

The resulting example:

>>9
array: 80 81 71 37 55 78 26 33 53
result: 81 37 78 33 53 26 55 71 80

Lab 3:

To do: An array of size N and integers K and L (1 <= K <= L <= N) are given. Find the arithmetic mean (average) of the elements of an array with numbers from K to L inclusive.

The resulting example:

>> 10
59 87 0 37 57 69 79 19 100 5
K=  >> 2
L=  >> 4
41.3333333333333

✍ Algorithm:

Lab 4:

To do: An array of size N is given. Find the minimum element of its even-numbered elements:

a2, a4, a6, .....

The resulting example:

>> 10
96 79 71 87 61 21 51 74 67 89
slice: [79,87,21,74,89]
21

✍ Algorithm:

 begin var n:=ReadInteger; var a:=arrRandomInteger(n); a.Println; println('slice: ',a[1::2]); print(a[1::2].min); end.

To do: An array of size N and integers K and L (1 <= K <= L <= N) are given. Calculate the sum of array elements except for elements with indexes from K to L inclusive.

Note: you should use here the sum method:

 print(a[?:?:?].sum); // or print(slice.sum);

The resulting example:

>> 10
35 26 82 63 54 47 37 95 26 88
K =  >> 4
L =  >> 8
257

To do: An array of size N (N is even) is given. Change the first half in it with the second (assume that the length of the array is an even number). Do not change the order of the elements in the halves.

The resulting example:

>> 10
68 57 63 91 52 56 78 51 33 83
result: [56,78,51,33,83,68,57,63,91,52]

Lab 5: Insertion and deletion in an array

To do 1: An array of N integers is given. It’s necessary to insert an element x on k-th index, k<=N.

To do 2: An array of N integers is given. It’s necessary to delete an element with index k, k<N.

The resulting example:

// to do 1:
array: [5, 12, 1, 3, 11, 19]
enter a number to insert 2
enter an order number 3
result:  [5,12,1,2,3,11,19]

// to do 2:
array: [5, 12, 1, 3, 11, 19]
enter an order number
>> 2
result: [5,12,3,11,19]

✍ Algorithm:

 // to do 1: begin var a := arr(5, 12, 1, 3, 11, 19); var x := ReadInteger ('enter a number to insert'); var k := ReadInteger ('enter an order number'); a := a[:k] + Arr(x) + a[k:]; print('result: ', a) end.
 // to do 2: begin var a := arr(5, 12, 1, 3, 11, 19); var k := ReadInteger ('enter an order number'); a := a[:k] + a[k+1:]; print('result: ', a) end.

To do: An array of integers is given. Find maximum element of the array and delete it. You should use slice to implement the task.

Note: To find an index of the maximum element it is better to use a.IndexMax method.

The resulting example:

array:  [66,46,26,64,73,62,37,57,46,9]
result:  [66,46,26,64,62,37,57,46,9]

To do: An array of integers and N number are given (N is entered). Find minimum element of the array and insert N number before this element. You should use slice to implement the task.

Note: To find an index of the maximum element it is better to use a.IndexMin method.

The resulting example:

array:  [20,3,18,33,93,58,30,56,15,3]
>> 20
result:  [20,20,3,18,33,93,58,30,56,15,3]

Array sorting algorithms

Lab 6:

To do: calculate a time to execute the algorithm of Bubble sort

✍ Algorithm:

 procedure MySort(a: array of integer); begin // bubble sort for var i := 1 to arr.High - 1 do for var j := 0 to arr.High - i do if arr[j] > arr[j + 1] then Swap(arr[j], arr[j + 1]); end; begin var a:=arrRandomInteger(20000); // note the time var t:=System.DateTime.Now; // run the algorithm MySort(a); // note the time of algorithm end var t1:=System.DateTime.Now; println('The time to execute the algorithm: ',t1-t); //t:=System.DateTime.Now; end.

To do: Calculate a time to execute the algorithm of Selection sort and Insertion sort. Compare the time and output the result

Note: You should create two procedures with sorting algorithms (copy those algorithms from the Theory materials). And you’ll need to note a current time four times (before starting each algorithm and before finishing it).

The resulting example:

The time to execute the Insertion algorithm:  00:00:00.5804751
The time to execute the selection algorithm:  00:00:00.9035547

Merging of two sorted arrays

Lab 7:

To do: Two sorted arrays a and b are given. Merge them into third sorted array.

Resulting example:

array 1: [1,3,11,19]
array 2: [1,13,21]
result: [1,1,3,11,13,19,21]

✍ Algorithm:

 function Merge(a, b: array of integer; n, m: integer): array of real; begin Assert((0 < n) and (n < a.Length)); Assert((0 < m) and (m < b.Length)); a[n] := integer.MaxValue; // barrier b[m] := integer.MaxValue; // barrier SetLength(Result, m + n); var (ia, ib) := (0, 0); for var iс := 0 to n + m - 1 do if a[ia] < b[ib] then begin Result[iс] := a[ia]; ia += 1; end else begin Result[iс] := b[ib]; ib += 1; end; end; begin var a := arr(1, 3, 11, 19); var b := arr(1, 13, 21); println('array 1:',a); println('array 2:',b); setLength(a, 5); // for extra element setLength(b, 4); // for extra element print('result: ', Merge(a, b, 4, 3)) // [1,1,3,11,13,19,21] end.

To do: Calculate a time to execute the algorithm of the lab before this task (with the function to Merge two arrays). Compare the time with a time, needed to complete the merging using standard sort algorithm:

 var c:=a+b; sort(c);

The resulting example:

array 1: [1,3,11,19]
array 2: [1,13,21]
result array c: [1,1,3,11,13,19,21]
the time with standard sort method 00:00:00.0009962
result:  [1,1,3,11,13,19,21]
the time with function to merge 00:00:00.0009984

Lab 8:

To do: An array of integers and n number is given (n is entered). You should output the index of the n number in the array, or ‘there is no n’ message if n is not in the array.

The resulting example:

array:  [3,3,24,41,57,59,84,88,89,95]
enter n to find it:
>> 41
index of n is:  3

✍ Algorithm:

 begin var a := arrrandominteger(10); sort(a); println('array: ', a); var n := readinteger('enter n to find it: '); var index := a.BinarySearch(n); if (n > 0) then print('index of n is: ', index) else print('there is no n ') end.

To do: An array of integers and n number are given (n is entered). You should use a.BinarySearch(n) standard method to delete that n from the array. Also, you should use slices to do it.

Note: to use BinarySearch() method you need the array to be sorted first. So, use Sort() method before searching.

The resulting example:

array:  [6,71,85,33,41,75,75,84,38,57]
sorted array:  [6,33,38,41,57,71,75,75,84,85]
enter n to delete it:
>> 38
result:  [6,33,41,57,71,75,75,84,85]

Lists

Lab 9:

To do: An array of N integers is given. Insert all even elements of the array into L1, and all odd elements into L2.

The resulting example:

array: [17,25,8,17,21,9,19,22,19,24]
L1: 8 22 24
L2: 17 25 17 21 9 19 19

✍ Algorithm:

 begin var a := arrrandominteger(10, 5, 25); println(a); var L1 := new List; var L2 := new List;   foreach var x in a do if x.IsEven then L1 += x else L2 += x; L1.println; L2.println; end.

To do: An array of integers is given (fill it with random generated numbers in the range [-5,20]). Insert all positive elements of the array into L1 list, and all negative elements into L2 list.

The resulting example:

array:  [17,16,15,5,-2,2,-3,-5,16,-5]
L1: 17 16 15 5 2 16
L2: -2 -3 -5 -5

To do: A list of integers is given. Find maximum element of the list and delete it. You should use L.RemoveAt(k); standard list method.

Note: To find an index of the maximum element it is better to use L.IndexMax method.

The resulting example:

List: 0 93 71 88 99 44 50 36 72 1
result:  [0,93,71,88,44,50,36,72,1]

To do: A list of integers and N number are given (N is entered). Find minimum element of the list and insert N number before this element. You should use L.Insert(ind,n); standard method.

Note: To find an index of the minimum element it is better to use L.IndexMin method.

The resulting example:

76 45 84 47 85 27 12 74 21 47
enter n:
>> 20
result:  [76,45,84,47,85,27,20,12,74,21,47]

$${}$$ 