Урок 7. Основы работы с указателями
Теория
1. Основы работы с указателями
- Указатели — это способ указать местоположение переменной. Вместо хранения значения (
5
или символ ‘c
’), значением указателя является адрес другой переменной. - Переменные-указатели имеют размер (количество байт в памяти), имя и значение. Они должны быть объявлены и инициализированы.
- «Указатель» (сам по себе) — это не тип. Это конструктор типов — языковая конструкция, которая при применении к другому типу дает нам новый тип. В частности, добавление звездочки (
*
) после любого типа задает название типу, который является указателем на этот тип. - Объявление указателя сообщает нам имя переменной и тип переменной, на которую будет указывать этот указатель.
- Можно выполнять присваивание указателям, изменяя их значения. Изменение значения указателя означает изменение того, куда он указывает.
- Прежде чем использовать указатель, необходимо инициализировать его (дать ему что-то, на что можно указывать).
- Если мы не инициализируем указатель перед его использованием, то он будет указывать на какое-то случайное место в программе (это может привести к сбою программы).
- Чтобы получить указатель, указывающий на некоторый адрес, нужно назначить имя полю памяти, а затем нам нужно использовать оператор
&
. x
инициализируется значением 5 в той же строке, в которой оно объявлено;- значение
xptr
инициализируется местоположениемx
; - после того, как он инициализирован,
xPtr
указывает на переменнуюx
. - Код
&x = 5;
не будет скомпилирован. Программист может получить доступ к местоположению переменной, но изменить местоположение переменной невозможно. - Как только у нас появятся указатель на адреса переменных, мы хотим использовать их, «следуя за стрелкой» и изменить ячейку, на которую ссылается указатель.
- Символ звездочка
*
— унарный оператор, который разыменовывает указатель. - Обратите внимание, что зеленая стрелка указывает на то, что эта строка еще не была извлечена, следовательно, x все еще имеет значение 5 в концептуальном представлении. Однако, как только строка 7 будет выполнена, значение будет равно 6.
- Обратите внимание, что зеленая стрелка указывает на то, что эта строка еще не была выполнена, следовательно,
x
все еще имеет значение 5 в концептуальном представлении. Однако, как только строка 7 будет выполнена, значение будет равно 6. - При работе с указателями, вы будете использовать звездочку сначала для объявления переменной, а затем для ее разыменования. Только переменные, имеющие тип указателя, могут быть разыменованы.
- Существует только три основных действия с указателем: объявление, присваивание (включая инициализацию) и разыменование.
/* объявляет переменную с именем my_char_pointer с указателем типа на char (переменная, указывающая на символ) */ char * my_char_pointer; |
/* код, который объявляет целое число x и указатель на целое число xPtr */ int x = 5; int *xPtr; xPtr = &x; // устанавливает значение переменной xPtr на адрес x |
6 7 | // Пример использования оператора разыменования: *xPtr = 6; // изменяет значение, которое хptr указывает на 6 |
Два контекста в которых используется (*
), не путайте их:
1. В объявлении переменной, такой как int *p;
, звездочка является частью имени типа и сообщает нам, что нам нужен указатель на какой-либо другой тип (в нашем примере int *
— это тип p
).
2. Когда звездочка является оператором разыменования. Например, код r = *p;
присваивает переменной r
новое значение, а именно значение внутри ячейки памяти, на которую указывает p
. Код *p = r;
изменяет значение внутри ячейки памяти, на которую указывает p
, на новое значение, а именно на значение переменной r
.
int * q = &y; // совпадает с двумя утверждениями: int *q; q = &y; |
обмен значениями
Выполнение: Необходимо передавать указатели a
и b
через аргументы функции, как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> using namespace std; void swap(int *x, int *y) { int temp = *x; // temp временно сохраняет значение, на которое указывает x, =3 *x = *y; // берем значение, на которое указывает y, которое является значением b (=4) //и сохраняем это в значении, на которое указывает x, а именно в переменной a *y = temp; // берем значение temp = 3 и сохраняем его в виде целого числа, //на которое указывает y, т.е. в переменной b } int main() { int a = 3; int b = 4; swap(&a, &b); cout<<"a = "<< a<< ", b = "<< b << endl; system("pause"); return 0; } |
swap
принимает два аргумента, x
и y
, которые являются указателями на целые числа;— поскольку мы получаем доступ к значениям целых чисел, на которые указывают
x
и y
в коде внутри swap, нам придется отменить ссылки на x и y. Итак, вот почему мы будем видеть эти звездочки (*
) перед x и y по всему коду;— внутри
main
, вместо передачи в a
и b
, мы теперь должны передать в адрес a
и адрес b
.
Работа с памятью
- На 32-разрядной машине, где размер адресов составляет 32 бита, все пространство памяти начинается с
0x000000000
(в шестнадцатеричном формате каждый 0 представляет 4 бита 0) и заканчивается на0xFFFFFFFF
(напомним, что 0x обозначает шестнадцатеричный, и что каждоеF
представляет четыре двоичных 1). Каждая программа имеет в своем распоряжении все это адресное пространство, и существует соглашение о том, как программа использует этот диапазон адресов. Давайте посмотрим на рисунок, чтобы понять, где в памяти хранятся различные компоненты программы. - Если используется значение NULL, мы собираемся указать, что указатель ни на что не указывает. Всякий раз, когда у нас есть NULL.
- Нулевой указатель имеет особый тип — void *. Указатель void указывает на на любой тип — мы можем присвоить ему значение int *, double* или любой другой тип указателя, который мы хотим.
Давайте посмотрим на рисунок, чтобы понять, где в памяти хранятся различные компоненты программы.
2. Указатели и массив
- Массив представляет собой константный указатель на свой первый элемент.
- Доступ к элементу массива с помощью арифметики указателей работает нормально и иногда является естественным способом доступа к элементам. Но в случае, когда нам нужен просто n-й элемент массива, было бы громоздко объявлять указатель, добавлять к нему, а затем разыменовывать его.
- Пример:
- Можно достичь этой цели, проиндексировав массив. Когда мы индексируем массив, мы записываем имя массива, за которым следуют квадратные скобки, содержащие номер элемента, на который мы хотим сослаться. Важно отметить, что в C++ индексы массивов начинаются с нуля — первым элементом массива является
myArray[0]
.
// * array : имя массива является указателем на его первый элемент, то есть на 3 void printArr(int *array, int n) { int *ptr = array; // *ptr - это указатель, который указывает на то, куда указывает *array for (int i = 0; i < n; i++) { cout << *ptr; // вывод 1-й итерации - 3, вывод 2-й итерации - 1, // вывод 3-й итерации - 7, //чтобы указатель указывал на ячейку памяти следующего элемента в массиве: // пример адреса ptr = 0x00b5f9a0 ptr++; // 1st 0x00b5f9a4, 2nd 0x00b5f9a8, 0x00b5f9ac, // в массиве нет элемента, но ошибки быть не может // это вызвало бы проблему, если бы мы разыменовали указатель } } int main(){ int arr[4] = { 3,1,7,2 }; printArr(arr, 4); } |
// * array : имя массива является указателем на его первый элемент, то есть на 3 void printArr(int *array, int n) { for (int i = 0; i < n; i++) { cout << array[i]; // 1-я итерация выводит 3, 2-я итерация - 1, 3-я итерация - 7, а затем 2 } } int main(){ int arr[4] = { 3,1,7,2 }; printArr(arr, 4); } |
int a[] {1,3,5,7,9}; int* p = a; // переместите указатель на второй элемент: p++; p++; |
int a[] {1,3,5,7,9}; int* p = a; cout << *(p + 1) << endl; // = a[1]=3 cout << *(p + 2) << endl; // = a[2]=5 |
Лабораторные работы
1. Основы работы с указателями
Выполнить: Создайте функцию для вычисления суммы указателя и переменной целочисленного типа. То есть функция должна возвращать сумму указателя и значения переменной.
Указание: Объявление функции должно быть таким:
int addP(int var1, int var2); |
Примерный вывод:
введите первое число (указатель): >>>2 введите второе число (которое прибавить): >>>500 результат: указатель + 500 = 502
✍ Алгоритм:
- Создайте проект
Lesson7
. Добавьте в соответствующие папки проекта файлы:main7lab0.cpp
,L7lab0.cpp
,L7lab0.h
. - Откройте
main7.cpp
и подключите все необходимые директивы и файлы. Выведите сообщение пользователю для ввода двух значений. Первое значение — указатель, второе — для добавления: - Переключитесь на код файла
string7.h
и подключите необходимые файлы и директивы: - Зда добавим объявление функции, как это было рекомендовано в тексте задания:
- Теперь добавим реализацию функции. Откройте файл
string7.cpp
, подключите все необходимые директивы и добавьте код: - Теперь можно вызвать созданную нами функцию и вывести результаты. Это необходимо сделать в файле
main7.cpp
: - Добавьте инструкцию, возвращающую значение 0 внутри основной функции. Запустите программу и проверьте выходные данные.
cout << "Lab 0:" << endl; cout << "пожалуйста, введите первое число (для указателя): "<< endl; int var1; cin >> var1; cout << "пожалуйста, введите второе число (для добавления): " << endl; int var2; cin >> var2;
#pragma once
#ifndef STRING7_H
#define STRING7_H
#include
// здесь ваш код
#endif
//lab 0: Создайте функцию для вычисления суммы указателя и переменной целочисленного типа int addP(int var1, int var2);
//lab 0: для вычисления суммы указателя и переменной целочисленного типа int addP(int var1, int var2) { int* p_var = &var1; return *p_var + var2; }
p_var
инициализируется адресом переменной var1
. Функция возвращает *p_var
— что означает, что мы берем значение, на которое указывает p_var
(то есть значение var1
), и добавляем к нему значение var2
.
cout << "Результат:" << endl; cout << "указатель + " << var2 << " = " << addP(var1,var2) << endl;
Выполнить: Создайте приложение с функцией, которая принимает два аргумента - целые числа (var1
и var2
), и выполняет следующие вычисления со своими аргументами, используя при этом указатели (p1
и p2
):
1) произведение указателя и переменной:p1 * var1
2) сумма указателей:p1 + p2
3) изменение значенияvar1 = 5
, используя при этом указательp1
4) изменение адреса указателя:p1
(address) =p2
(address)
Указание 1: Чтобы изменить значение переменной:
int* p1 = &var1; // если p1 является указателем *p1 = 1; // 1 - это новое значение переменной |
Указание 2: Объявление функции должно быть следующим:
void task1(int var1, int var2); |
Примерный вывод:
Задание 1: Введите первое значение: >>5 Введите второе значение: >>10 произведение указателя и переменной: 25 сумма указателей: 15 результат смены значения var1, var1 = 5 результат ДО смены адреса, p1 = 0098F7E8 результат смены адреса, p1 = 0116FC90
[Solution and Project name: Lesson_7task1
, file name L7Task1main.cpp
, L7Task1imp.cpp
, L7Task1.h
]
2. Указатель на массив
Выполнить: Создайте функцию для вычисления суммы элементов массива. Задача должна быть выполнена с использованием двух функций. Первая функция не использует указатель, вторая функция должна использовать указатель, обращающийся к элементу массива по индексу.
Указание 1: Объявление функции:
int sumArray1(int * array, int n); int sumArray2(int * array, int n); |
Примерный вывод:
array: 1 2 3 4 5 результат выполнения первой функции: sum = 15 результат выполнения второй функции: sum = 15
✍ Алгоритм:
- Сначала давайте создадим функцию, которая выполняет итерацию по элементам массива без использования указателя:
- Рассмотрим работу с памятью:
- Теперь давайте создадим функцию, которая выполняет итерацию по элементам массива, используя указатель, обращающийся к элементу массива по индексу:
- Вызовите функцию в функции
main
и запустите программу.
int sumArray1(int * array, int n) // массив указывает на значение 1 { // начинаем с суммы, равной 0 int AnswerSum = 0; // count from 0 to n for (int i = 0; i < n; i++) { // добавляем в сумму array[i] AnswerSum += array[i]; } // возвращаем сумму в качестве результата return AnswerSum; } int main() { int data[] = { 1,2,3,4,5 }; cout << "array: " << endl; for (auto x : data) { cout << x << " "; } cout << endl; int sum= sumArray1(data, 5); cout << "результат с первой функцией: sum = " << sum<< endl;
1. Первая итерация цикла:![]() |
2. Вторая итерация цикла:![]() |
3.Третья итерация цикла:![]() |
4.Последняя итерация цикла:![]() |
Возвращаемся к функции main и уничтожение области sumArray1:![]() |
int sumArray2(int * array, int n) // массив указывает на значение 1 { // начинаем с суммы, равной 0 int AnswerSum = 0; // счетчик цикла - это указатель, указывающий на адрес 1-го элемента массива for (int *p = array; p < array + n; p++) { // добавим в сумму ссылку на p AnswerSum += *p; } // возвращаем сумму return AnswerSum; }
Выполнить: An array of integers is given (
1, 2, 3, 4, 5, 6, 7, 8, 9
).Каждый второй элемент массива установить в 0 (то есть четные по порядку элементы должны быть = 0). Необходимо использовать индексацию массива.
Указание 1: Объявление функции должно быть следующим:
void DelEveryEven(int* array, int n); |
Примерный вывод:
Лабораторная работа 2, Массивы: Исходный массив: 1 2 3 4 5 6 7 8 9 Результат: 1 0 3 0 5 0 7 0 9
✍ Алгоритм:
- Откройте приложение, которое вы создали для лабораторной 1, или, если вы ее не сделали, сделайте следующее: создайте пустое консольное приложение с именем Lesson7. Добавьте файлы:
main7.cpp
,string7.cpp
,string7.h
. - Подключите все необходимые библиотеки и файлы (если вы не делали этого раньше).
- Откройте файл
main7.cpp
. Выведите сообщение для пользователя, объявите массив и инициализируйте его значениями: - Распечатайте элементы исходного массива:
- После этого откройте файл
string7.h
и подключим все необходимые директивы (если это не было сделано ранее): - Объявление функции должно быть таким, как рекомендовано в задании:
- Теперь необходимо написать саму функцию, т.е. ее реализацию. Откройте файл
string7.cpp
, подключите все необходимые директивы и добавьте код: array
возвращает ячейку памяти первого элемента. Но нам необходимо установить в 0 второй элемент. Поэтому имеемarray + 1
.- В строке
*p = 0
мы разыменовываем указатель, а второй элемент устанавливаем = 0. - Чтобы проделать те же манипуляции с четвертым элементом (четным), мы можем увеличить указатель на 2 (
p = p + 2
). array + n
- ячейка памяти первого элемента +n
, это 9. Затем происходит выход их цикла.- Теперь можно вызвать функцию и вывести результаты. Это необходимо сделать в
main7.cpp
: - Добавьте код, чтобы функция
main
возвращала0
. Запустите программу и проверьте выходные данные.
cout << "Лабораторная работа 2, Массивы:\n"; int my_arr[] = { 1,2,3,4,5,6,7,8,9 };
cout << "Исходный массив: " << endl; for (auto x : my_arr) { cout << x << " "; }
#pragma once
#ifndef STRING7_H
#define STRING7_H
#include
#endif
// Лабораторная работа 2, Массивы: Дан массив (1, 2, 3, 4, 5, 6, 7, 8, 9). // каждый второй элемент установите в 0 void DelEveryEven(int* , int);
//Лабораторная работа 2, массивы void DelEveryEven(int* array, int n) { for (int* p = array + 1; p < array + n; p = p + 2) { *p = 0; } }
*array
инициализируется адресом массива.Рассмотрим строку
int* p = array + 1;
.
DelEveryEven(my_arr, 9); cout << "Результат: " << endl; for (auto x : my_arr) { cout << x << " "; } cout << endl;
Выполнить: Задан массив целых чисел. Создайте две функции, которые возвращают значение максимального элемента массива. Первая функция не использует указатель, вторая функция должна использовать указатель, обращающийся к элементу массива по индексу.
Указание: The signature of the functions should be the same:
int maxArray1(int * array, int n); int maxArray2(int * array, int n); |
Примерный вывод:
array: 1 2 3 4 5 the result of the first function: max = 5 the result of the second function: max = 5
[Solution and Project name: Lesson_7task2_0
, file name L7Task2_0main.cpp
, L7Task2_0imp.cpp
, L7Task2_0.h
]
Выполнить: An array of positive and negative integers is given. Create an application with a function that sets its negative elements to positive values.
Указание: The signature of the function should be as follows:
void SetNegToPos(int* array, int n); |
Примерный вывод:
Task 2: The array before lab is done: 1 -2 3 4 5 -6 7 8 -9 Result: 1 2 3 4 5 6 7 8 9
[Solution and Project name: Lesson_7task2
, file name L7Task2main.cpp
, L7Task2imp.cpp
, L7Task2.h
]
Выполнить: An array of integers is given. Create a function that returns an index of the largest element of the array.
Указание 1: The signature of the function should be as follows:
int findLargestInd(int * array, int n); |
Указание 2: Withitn the function you should make the comparison:
if (array[i] > array[largestIndex]) { ... } |
Примерный вывод:
Task 3: array: 1 5 3 2 1 index of the largest element = 1
[Solution and Project name: Lesson_7task3
, file name L7Task3main.cpp
, L7Task3imp.cpp
, L7Task3.h
]
3. String characters access with pointer indexing
Выполнить: Two strings are given. Create the function which returns
1
if the strings are equal, and returns 0
otherwise.
Указание 1: To access the characters of a string with pointer indexing you should use char
type for that string:
char str1[] = "Apple"; |
Указание 2: The signature of the function should be as follows:
int stringEqual(const char * str1, const char * str2); |
Примерный вывод:
// lab 3: the result for 'apple' and 'apple' is: 1 ++++ // lab 3: the result for 'apple' and 'apples' is: 0
✍ Алгоритм:
- Let's declare a function with two arguments, they are constant char pointers to the strings:
- Then, we're going to declare the pointers pointing at the first letter of
str1
and the first letter ofstr2
. Add the code into the function: - Then, we're going to create a loop to be repeated as long as what
p1
points at is the same as whatp2
point at. We should use dereference operator to take the values, that is to take the characters of the strings: - Then, we need to check if
p1
is equaled to\0
, that is the last character which means a termination of a string. In this case the function must return1
(that is answer "yes"): - After, we advance
p1
andp2
to the next letter: - After the loop we need to return answer "no", that is in our function means
0
: - Now, we're going to return to the
main
function and create two c-string. And then to call the function: - Run the program and check the output.
int stringEqual(const char * str1, const char * str2){ ... }
const char* p1 = str1; const char* p2 = str2;
while (*p1 == *p2) {
}
if (*p1 == '\0') { return 1; }
p1++; p2++;
return 0;
char str1[] = "apple"; char str2[] = "apples"; cout << "the result for \'"<< str1 <<"\' and \'"<< str2 <<"\' is: " << stringEqual (str1,str2) << endl;
Выполнить: Create a function to check if c-string contains a combination of letters
'mo'
. Return 1
(if found) or 0
(if not found). It is not allowed to use any standard functions. You should use pointer.
Указание 1: The signature of the function must be as following:
bool findMo(const char * str); |
Указание 2: To check if this is not an end of the string, you can use the following loop condition:
while (*str != '\0') |
Примерный вывод:
Task 4:
the result for 'the movie was nice' is: 1
[Solution and Project name: Lesson_7task4
, file name L7Task4main.cpp
, L7Task4imp.cpp
, L7Task4.h
]
Выполнить: Reverse the order of characters in the string. To do this, define a pointer to the last character and, moving two pointers from the beginning and end of the line to the middle, swap the corresponding characters.
Указание 1: To access the characters of a string with pointer indexing you should use char
type for that string:
char str[] = "Hello world"; |
Указание 2: The signature of the function should be as follows:
void reverseString (char * str); |
Примерный вывод:
// lab 4: The string before lab is done: Hello world The string after lab is done: dlrow olleH
✍ Алгоритм:
- To do the lab open the application you've created for lab1 or, if you haven't done it, so make the next: Create empty console application with a name
Lesson7
. Add files:main7.cpp
,string7.cpp
,string7.h
. - Include all necessary libraries and files (if you didn't do it before).
- Open the
main7.cpp
file in the code editor. Type the code to output a message to the user, and to initialize an array of char type (the string will be treated as an array of chars): - After that, let's turn to
string7.h
file and include all the needed directives (if you didn't do it before for the lab1): - The signature of the function was recommended in the task text, let's add that code with a comments of the task text:
- Now, let's create the implementation of the function. To do this open the
string7.cpp
file, include all the directives you need, and add the code: - Then we're going to assign the value of the characters to the
*str
variable, moving the pointer from the last character to the middle. To do it, we use the temporary variablet
. And at the same time we're going to substitute the values of the array elements, beginning from the last element, and assigning the value of the first element to it. We should do the dereferencing for this purpose: - Now you can call the function we've created and print the results. You must do it inside the
main7.cpp
file: - Add the code to return a
0
value inside the main function. Run the program and check the output.
cout << "Lab 4:" << endl; char str[] = "Hello world"; cout << "The string before lab is done: " << str << endl;
#pragma once
#ifndef STRING7_H
#define STRING7_H
#include
#endif
// Lab 4: Reverse the order of characters in the string. void reverseString(char* str);
str
is initialized to the location of str
.// Lab 4: Reverse the order of characters in the string. void reverseString(char* str) { char* str1 = str; char* res = nullptr; while (*str1) { res = str1; *(str1++); } // end of while // ... } // end of function
char* res = nullptr;
) returns a "null pointer", that is 0x00000000
address. Then, we use the while
loop to iterate over the array's elements addresses. After the loop, the variable res
will get the value of the address of the last character of the string, that is can be 0x00cffae6
, for example, for "d
" character). auto l = res; while ((l) > (str)) { auto t = *l; // temporary variable to store the values, moving from the last, 'd' *l = *str; // dereferencing, we take the value that *str points to, which is the value of str //and store that in the value that *l points to *str = t; // changes the value that *str points to l--; // moving from the last address to the middle str++; // moving from the first address to the middle }
reverseString(str); cout << "The string after lab is done: " << str << endl;
Выполнить: There is a string that contains the positive integer ('
Happy 2021 year to u!
'). Create a function to display a substring containing this number.
Указание 1: Use the following function signature. It returns integer (you should make a number using the digits):
void numbFromStr(char* str); |
To understand where the end of the string is, you can use the following loop:
while (*str1) { pLast = str1; // the address of the last character *(str1++); } |
Указание 2: The result must be of string type, so you should include the string library:
#include <string> |
Указание 3: to check if the character is a digit, you should create a function:
bool isdigit(char c) { if ((c <= '9') && (c >= '0')) { return true; } else return false; } |
Примерный вывод:
Task 5: The string for the task is: Happy 2021 year to u! the substring of numbers: 2021
[Solution and Project name: Lesson_7task5
, file name L7Task5main.cpp
, L7Task5imp.cpp
, L7Task5.h
]
Выполнить: A string of characters is given. Convert all uppercase Latin letters to lowercase in it. The function should return the number of substitutions performed.
Указание 0: You should use the character string type:
char s[] ="..."; |
Указание 1: Use the following function signature. It returns an integer (the number of substitutions):
int to_lower(char * str); |
Указание 2: To check if this is not an end of the string, you can use the following loop condition:
while (*str != '\0') |
Указание 3: To check if a letter is uppercase letter, you should use the following function:
bool isCappital(char ch) { return (ch >= 'A' && ch <= 'Z'); } |
Указание 4: To convert a letter to lowercase, you should use the standard tolower(ch)
function.
Примерный вывод:
Task 6: The string for the task is: HelLo wOrLD The result is: hello world
[Solution and Project name: Lesson_7task6
, file name L7Task6main.cpp
, L7Task6imp.cpp
, L7Task6.h
]
Выполнить: A string of characters is given representing an arithmetic expression of the form "<digit>±<digit>±...±<digit>"
, where the arithmetic operator "+
" (plus) or "−
" (minus) is located in place of the operation sign "±
" (for example, "4+7-2-8
"). Calculate the result of this expression (an integer).
Указание 1: Use the following function signature. It returns an integer (the number of substitutions):
int eval(char * expr); |
Указание 2: To find the first operand (digit) you can use the following code:
int res = *expr++ - '0'; // here *expr++ is the first character in the string |
or a function:
char r = *expr; //*expr is a code in ascii-table int res = atoi(&r); // converts code to digit |
Указание 3: To store the operation or a digit you can use the following concept:
char ch1 = *expr++; //arithmetic operator or digit |
ch1
will be set to 53'9'
- 53 is an address and 9 is a digit stored.
// to take the digit only insted of ch1 you must use : ch1-'0'; |
Примерный вывод:
Task 7: The string for the task is: 9+4-2-0 The result is: 11
[Solution and Project name: Lesson_7task7
, file name L7Task7main.cpp
, L7Task7imp.cpp
, L7Task76.h
]
Урок 6. C++ работа со строками
Теория
Строки в C++
- Для работы со строкой должна быть включена библиотека
string
: - Переменные строкового типа можно понимать как массив символов.
- К определенному символу в строке можно получить доступ как в обычном массиве, то есть по его индексу:
#include <string> |
string str="it's possible to understand it"; cout << str[2] << endl; // вывод: ' for (int i = 0; i <= str.size(); i++) { // для перебора символов строки if (str[i] == ' ') //что-то делаем } |
Строковые функции
size_t find
(const string& str, size_t pos = 0) const;
pos
, поиск включает только символы в позиции pos
или после нее, игнорируя любые возможные вхождения, которые включают символы перед позицией pos
.size_t
— это целочисленный тип без знака, размер любого объекта в байтах.npos
— максимальное значение size_t
(обычно = 4294967295)len
(или sublen)
в функциях-членах string, означает «до конца строки».-1
, которое, поскольку size_t
является целым типом без знака, является максимально возможным представимым значением для этого типа.string str="it's possible to understand it"; string substr="it"; size_t f = -1; int counter = 0; while (true) // infinite loop { // f = str.find(substr); //значение f будет равно 0 // 'f+1' требуется для перехода на следующую позицию после найденного совпадения f = str.find(substr, f+1); // на 2-й итерации f = 28 // на 3-й итерации f = 4294967295 это означает, что совпадений больше нет // string::npos = 4294967295 if (f == string::npos) break; counter++; } cout << counter; |
Управляющие (специальные) символы используются для представления определенных специальных символов в строковых литералах и символьных литералах: \‘
— одинарная кавычка
char c = '\'' |
Символьная строка и указатели
char s[6] = "Hello"; // в конце автоматически добавляется \0 char s[] = "Hello"; // тот же самый результат char* p = s; // H |
Для перебора символьной строки:
char* p = s; while (*p != 0) cout << *p++; |
или
char* p = s; while (*p) cout << *p++; |
Лабораторные работы
Правила оформления работ:
- Для выполнения заданий необходимо использовать перечисления и оператор switch.
- Все задания должны выполняться с помощью функций, результаты должны проверяться оператором
assert
в заголовочном файле. - Все функции и файлы должны сопровождаться комментариями с постановкой задания.
Тип String
Выполнить: Дана переменная строкового типа (s="Hello world"
) и дан символ (переменная c
) (пользователь его вводит). Проверьте, есть ли символ c
среди символов строки. Создайте функцию с именем checkIfChar
. Функция должна возвращать 1, если введенный символ найден, или 0 в противном случае..
Указание 1: Сигнатура функции должна быть следующей:
bool checkIfChar(string s, char c) |
Примерный вывод:
lab 1 "Hello world" введите символ: >>> o результат: 1
✍ Алгоритм:
- Откройте visual studio и создайте консольное приложение с Lesson6.
- Добавьте два файла
.cpp
в папку исходных файлов проекта (basicStrings.cpp
иmain.cpp
) и один файл заголовка должен быть добавлен в папку заголовочные файлы. - Откройте код
main.cpp
и добавьте все библиотеки, которые нам нужны для выполнения лабораторной работы: - В функции
main()
добавьте код с просьбой пользователя ввести предложение и присвойте входное значение переменнойstr
. Не забудьте объявить переменную:: - Затем попросите пользователя ввести символ. Присвойте значение переменной
c
: - Теперь необходимо создать функцию для проверки, находится ли символ в предложении. Функция должна быть с двумя аргументами — предложением (
str
) и символом (c
). Добавьте заголовок объявления функции перед функциейmain()
: - Добавьте код прохода по символам строки, используя цикл
for
. Внутри тела цикла мы должны проверить, соответствует ли текущий символ строки символуc
. Если это так, функция должна возвращать 1, в случае, когда это не так, функция возвращает 0. - Вернитесь к функции
main()
и вызовите созданную функцию. Результаты функции должны быть выведены, поэтому вызов должен быть внутри инструкцииcout<<
: - Не забудьте добавить инструкцию, чтобы окно консоли оставалось открытым:
- Запустите программу и проверьте выходные данные.
#include#include using namespace std;// #include // необходим для работы со строковым типом
int main() { cout << "lab 1:" << endl; string str="Hello world"; // .. }
cout << "Enter character :" << endl; char c; cin >> c;
//lab 1: bool checkIfChar(string s, char c) { // выполнение }
for (int i=0;i<= s.size();i++){ if (s[i]==c){ return 1; break; } } return 0;
cout << "result :" << checkIfChar(str, c) << endl;
//... system("pause"); return 0; //...
Выполнить: Создайте функцию для проверки того, содержит ли вводимый текст комбинацию букв "mo
". Функция должна возвращать 1 (если содержит) или 0 (если не содержит). Не допускается использование каких-либо стандартных функций.
Указание 1: Сигнатура функции должна быть следующей:
bool findMo(string s) |
Указание 2: Чтобы проверить два или более условия в операторе if
, вы должны использовать &&
(логическое И):
if (condition_1 && condition_2){ } |
Примерный вывод:
Задание 1 результат для 'Hello world': 0 --- Задание 1 результат для 'My mom': 1
Выполнить: Создайте функцию для проверки, содержит ли строковая переменная слово "собака
". Функция возвращает 1 или 0. Необходимо использовать символьную строку c
и указатель. Не допускается использование каких-либо стандартных функций.
Указание 1: Сигнатура функции должна быть следующей:
bool findMo(char* p) |
Примерный вывод:
задание 2 строка: Hello world результат: 0 --- задание 2 строка: my dog is nice результат: 1
Выполнить: Дано предложение: str = "слово1 слово2 слово3 слово4"
. Подсчитайте количество слов в нем. Не допускается использование каких-либо стандартных функций.
Указание 1: Вы должны подсчитать количество слов по количеству пробелов между словами.
Указание 2: Не забудьте проверить, не содержит ли предложение дополнительных пробелов в начале и конце предложения.
Указание 3: Сигнатура созданной функции должна быть следующей:
void countWords(string s, int& counter) |
Примерный вывод:
задание 3 Введите предложение: >>> word1 word2 word3 word4 результат: 4
Выполнить: Дана строка. Проверьте, совпадают ли ее первый и последний символы. Создайте функцию с идентификаторами LastAndFirst()
. Не допускается использование каких-либо стандартных функций (кроме функции size()
).
Указание 1: Заголовок функции:
bool LastAndFirst(string s) |
Указание 2: Метод size()
может быть полезен для поиска последнего символа (s.size()
).
Примерный вывод:
задание 4 Для предложения Hello world результат: false --- задание 4 Для предложения lucky ball результат: true
String functions
Выполнить: Создайте функцию для проверки, содержит ли текст слово cat. Выведите позицию (индекс) слова в тексте. Необходимо использовать стандартную функцию поиска (find).
Указание 1: Заголовок функции:
void findCatFunction(string s, string s0) |
Указание 2: Функция find()
:
s.find(s0) // возвращает -1, если в тексте s нет совпадений с s0 |
Примерный вывод:
задание 5 для текста: cat word1 word3 word4 результат: 0 --- задание 5 для текста: word1 word3 word4 результат: cat не найдено --- задание 5 для текста: word1 cat word3 word4 результат: cat найдено в позиции 6
Выполнить: Даны две строки S
и S0
(вводятся). Найдите количество вхождений строки S0
в строку S
.
Указание 1: В задании удобно использовать функцию find
класса string, которая возвращает позицию вхождения типа size_t
(целое число без знака) или значение string :: npos в случае, если вхождение не было найдено. Посмотрите на пример, чтобы понять, как их использовать.
Указание 2: Заголовок функции:
int countOccurrence(string s, string s0) |
Примерный вывод:
Lab 2 строка 1: it's possible to understand it строка 2: it результат: 2
✍ Алгоритм:
- Открытый файл
main.cpp
и в коде основной функции, под предыдущим кодом задания, добавьте комментария с номером задания. После этого объявите переменные строкового типа и инициализируйте их значениями: - Откройте файл
basicStrings.cpp
и добавьте код заголовка функции: - Функция должна возвращать целочисленный тип.
- Функция имеет два параметра строкового типа:
s
- строка, содержащая предложение, иs0
- подстрока, которую мы должны найти в строкеs
. - Чтобы найти подстроку, мы собираемся использовать стандартный метод
find()
и переменнуюf
типаsize_t
(целочисленный тип без знака). Переменнаяf
хранит положение подстроки внутри строкиs
. И если нет искомой подстроки, тоf
сохранит число 0, так как оно будет увеличено на 1 (f+1). Когда функцияfind()
достигнет конца строки, значениеnpos
(npos
— это константа - максимальное значение дляsize_t
(обычно = 4294967295)) будет присвоено переменнойf
: - Вернитесь к
main.cpp
файлу и внутри основной функции добавьте вызов нашей функции. Поскольку функция вернет целочисленное значение, то есть количество вхождений, мы должны сохранить результат функции в переменной: - Запустите программу и посмотрите выходные данные.
//lab 2 cout << "lab 2:" << endl; string str1, str2; str1 = "it's possible to understand it"; str2 = "it"; cout << "string 1: " << str1 << "\n string 2: "<< str2 << endl;
\n
используется для перехода на новую строку.// lab 2: int countOccurrence(string s, string s0) { // to do: }
size_t f = -1; int res = 0; // counter of the numbers of occurrences while (true) // infinite loop { f = s.find(s0,f+1); if (f == string::npos) // if the end of the string is reached break; // exit loop ++res; } return res;
break
будет выполнен только в том случае, если при поиске подстрок мы дойдем до конца строки.int counter = countOccurrence(str1, str2); cout << "result :" << counter << endl;
Выполнить: Даны строки S
и S0
. Создайте функцию для удаления последней подстроки, соответствующей S0
, из строки S
. Если совпадающих подстрок нет, то верните неизмененную строку S
.
Указание 1: Вы можете использовать функцию rfind класса string, чтобы найти последнее вхождение подстроки, или можете использовать функцию erase для удаления.
Указание 2: Заголовок функции:
string eraseLast(string s, string s0) { // to do: // // return s; } |
Примерный вывод:
задание 6: строка 1: it's possible to understand it строка 2: it результат: it's possible to understand
Выполнить: Дана строка, содержащая по крайней мере один символ пробела. Необходимо возвратить подстроку между первым и последним пробелами строки. Если строка содержит один пробел, должна быть возвращена пустая строка.
Указание 1: Можно использовать функцию substr member function of the string.
Указание 2: Заголовок функции:
string betweenSpaces(string s) { size_t f1, f2; f1 = s.find(" "); // индекс первого пробела f2 = s.rfind(" "); // индекс последнего пробела // ...; // ...; return // ...; } |
Примерный вывод:
задание 7: строка: it's possible to understand it результат: possible to understand
Указания: задания следует сохранить в файле с именем задания, и обязательно в коде вставить комментарий с постановкой задачи.
STRING:
String13. Дана строка. Подсчитать количество содержащихся в ней цифр.
String28. Дан символ C и строка S. Удвоить каждое вхождение символа C в строку S.
String35. Даны строки
S
и S0
. Удалить из строки S
все подстроки, совпадающие с S0
. Если совпадающих подстрок нет, то вывести строку S
без изменений.String43. Дана строка, состоящая из русских слов, набранных заглавными буквами и разделенных пробелами (одним или несколькими). Найти количество слов, которые содержат хотя бы одну букву «А».
String61. Дана строка, содержащая полное имя файла. Выделить из этой строки название последнего каталога (без символов «
\
»). Если файл содержится в корневом каталоге, то вывести символ «\
».
Демоверсия егэ информатика 2024 решение
*** ПЛЕЙЛИСТ КАНАЛА ЮТЬЮБ ***
ЕГЭ по информатике -> демоверсия ЕГЭ 2024
Скачать pdf демоверсии варианта ->
На рисунке изображена схема дорог Н-ского района. В таблице звёздочкой обозначено наличие дороги из одного населённого пункта в другой. Отсутствие звёздочки означает, что такой дороги нет.
1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|
1 | — | * | * | * | * | * | * |
2 | * | — | * | ||||
3 | * | — | * | * | |||
4 | * | — | * | * | |||
5 | * | * | * | — | |||
6 | * | * | — | ||||
7 | * | * | * | — |
Каждому населённому пункту на схеме соответствует номер в таблице, но неизвестно, какой именно номер. Определите, какие номера в таблице могут соответствовать населённым пунктам E и F на схеме. В ответе запишите эти два номера в возрастающем порядке без пробелов и знаков препинания.
Ответ: 35
✍ Решение:
- Рядом с каждой вершиной проставим количество ребер вершины (степень вершины). Кроме того, граф симметричен:
- Поскольку уникальная вершина здесь только одна, и она находится в центре, то рассмотрим остальные вершины. Все остальные вершины и имеют степень 3, кроме вершин
А
иB
, которые имеют степень 2:
B = 2(D3,C6) A = 2(G3,C6)
D3
и G3
.C
соответствует единственный уникальный пункт 1, то в таблице остаются только пункт 3 и 5, которые и соответствуют вершинам E
и F
.Ответ: 35
Миша заполнял таблицу истинности логической функции F
(x ∧ ¬y) ∨ (y ≡ z) ∨ ¬w
но успел заполнить лишь фрагмент из трёх различных её строк, даже не указав, какому столбцу таблицы соответствует каждая из переменных w, x, y, z.
Определите, какому столбцу таблицы истинности функции F соответствует каждая из переменных w, x, y, z.
Перем.1 | Перем.2 | Перем.3 | Перем.4 | Функция |
??? | ??? | ??? | ??? | F |
0 | 0 | 0 | ||
1 | 0 | 0 | 0 | |
1 | 0 | 1 | 0 |
В ответе запишите буквы в том порядке, в котором идут соответствующие им столбцы (сначала буква, соответствующая первому столбцу; затем буква, соответствующая второму столбцу, и т.д.).
Ответ: wzyx
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
🎦 Теоретическое решение подобного задания: RuTube
✍ Решение:
-
✎ Теоретическое решение:
✎ Программное решение:
Язык pascalABC.NET (классический):
begin writeln('x y z w'); for var x := false to true do for var y := false to true do for var z := false to true do for var w := false to true do begin var f := not ((x and not y) or (y = z) or not w); if f then println(Ord(x), Ord(y), ord(z), ord(w)) end; end. |
Язык pascalABC.NET (LINQ):
## uses school; var t:=TrueTable((x,y,z,w)->(x and not y)or(y = z)or not w); TrueTablePrint(t,0,'xyzw'); // 0 так как для лжи |
Python:
# создадим функцию для вычисления значения логического выражения def f(x, y, z, w): return (x and not y) or (y == z) or not w from itertools import * # перебор всех пробелов for a1, a2, a3, a4 in product([0, 1], repeat=4): # все наборы t = [(a1,a2,0,0),(1,0,a3,0),(1,0,1,a4)] # проверяем все ли наборы уникальны if len(set(t)) != len(t): continue # перебор всех перестановок имен столбцов for p in permutations('xyzw'): # проверка на совпадение результата if [f(**dict(zip(p,r))) for r in t]==[0,0,0]: print(*p, sep='') |
В файле приведён фрагмент базы данных «Кондитерские изделия» о поставках конфет и печенья в магазины районов города. База данных состоит из трёх таблиц.
Таблица «Движение товаров» содержит записи о поставках товаров в магазины в течение первой половины июня 2023 г., а также информацию о проданных товарах. Поле Тип операции содержит значение Поступление или Продажа, а в соответствующее поле Количество упаковок, шт. внесена информация о том, сколько упаковок товара поступило в магазин или было продано в течение дня. Заголовок таблицы имеет следующий вид.
ID операции | Дата | ID магазина | Артикул | Количество упаковок | Тип операции |
Таблица «Товар» содержит информацию об основных характеристиках каждого товара. Заголовок таблицы имеет следующий вид.
Артикул | Отдел | Наименование товара | Ед_изм | Количество в упаковке | Цена за упаковку |
Таблица «Магазин» содержит информацию о местонахождении магазинов. Заголовок таблицы имеет следующий вид.
ID магазина | Район | Адрес |
На рисунке приведена схема указанной базы данных.
Используя информацию из приведённой базы данных, определите общую массу (в кг) всех видов зефира, полученных магазинами на улице Металлургов за период с 4 по 13 июня включительно.
В ответе запишите только число.
Ответ: 3570
✍ Решение:
- Задание можно выполнить использую опцию Фильтр в Excel.
- Перейдем в лист Товары. Выделим полностью первую строку и применим к ней фильтр (меню Данные — Фильтр).
- В фильтре для столбца
С
с товарами выбираем сначала Выделить всё (чтобы отменить все выделения), а затем — только значения, связанные с зефиром: - Получаем в результате записи, запоминаем артикулы (4,5,6,7):
- Переходим на лист с Магазинами и отфильтровываем точно так же записи для улицы Металлургов, запоминаем ID магазинов (М2, М16):
- Переходим на лист Движение товаров. Ставим фильтр полностью на первую строку. Наложим фильтр на поле ID магазина — выбираем М2 и М16, и Артикул — 4, 5, 6, 7. Затем используем фильтр для поля «тип операции» (выбираем значение «поступление») и для поля «дата» (выбираем значения от 3 до 14 июня):
- Для подсчета общей массы:
- отсортируем полученные данные по значению артикула;
- подсчитаем сумму упаковок каждого артикула: выделяем соответствующие ячейки и смотрим в строку состояния;
- переходим на лист Товар и копируем данные о кол-ве в упаковке;
- В полученной таблицы проводим расчёт (Кол-во упаковок * кол-во в упаковке / 1000):
Ответ: 3570
По каналу связи передаются сообщения, содержащие только восемь букв:
А, Б, В, Г, Д, Е, Ж и З.
Для передачи используется двоичный код, удовлетворяющий условию Фано.
Кодовые слова для некоторых букв известны:
А – 000 Б – 001 В - 0101 Г - 0100 Д - 011 Е - 101
Какое наименьшее количество двоичных знаков потребуется для кодирования двух оставшихся букв?
В ответе запишите суммарную длину кодовых слов для букв: Ж, З
Ответ: 5
✍ Решение:
-
Для решения используем дерево. Влево откладываем 0, вправо — 1:

Для букв Ж и З имеем кодовые слова:
100
и 11
. Суммарная длина = 5.
Ответ:
5
На вход алгоритма подаётся натуральное число N
. Алгоритм строит по нему новое число R
следующим образом.
1. Строится двоичная запись числа N
.
2. Далее эта запись обрабатывается по следующему правилу:
а) если число N
делится на 3, то к этой записи дописываются три последние двоичные цифры;
б) если число N
на 3 не делится, то остаток от деления умножается на 3, переводится в двоичную запись и дописывается в конец числа.
Полученная таким образом запись является двоичной записью искомого числа R.
3. Результат переводится в десятичную систему и выводится на экран.
Укажите минимальное число R
, большее 151, которое может быть получено с помощью описанного алгоритма В ответе это число запишите в десятичной системе счисления.
Ответ: 163
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
✎ Программное решение:
Язык pascalABC.NET (классический):
|
|
Python:
|
Ответ: 163
Исполнитель Черепаха действует на плоскости с декартовой системой координат. В начальный момент Черепаха находится в начале координат, её голова направлена вдоль положительного направления оси ординат, хвост
опущен. При опущенном хвосте Черепаха оставляет на поле след в виде линии. В каждый конкретный момент известно положение исполнителя и направление его движения. У исполнителя существует две команды:
Вперёд n (где n – целое число), вызывающая передвижение Черепахи на n
единиц в том направлении, куда указывает её голова,
и Направо m (где m – целое число), вызывающая изменение направления движения на m
градусов по часовой стрелке.
Запись Повтори k [Команда1 Команда2 … КомандаS] означает, что последовательность из S
команд повторится k
раз.
1. Черепахе был дан для исполнения следующий алгоритм:
Повтори 7 [Вперёд 10 Направо 120].
Определите, сколько точек с целочисленными координатами будут находиться внутри области, ограниченной линией, заданной данным алгоритмом. Точки на линии учитывать не следует.
ИЛИ:
2. Исполнитель Черепаха действует на плоскости с декартовой системой координат. В начальный момент Черепаха находится в начале координат, её голова направлена вдоль положительного направления оси ординат, хвост опущен. При опущенном хвосте Черепаха оставляет на поле след в виде линии. В каждый конкретный момент известно положение исполнителя и направление его движения. У исполнителя существует 6 команд:
Поднять хвост, означающая переход к перемещению без рисования;
Опустить хвост, означающая переход в режим рисования;
Вперёд n (где n – целое число), вызывающая передвижение Черепахи на n единиц в том направлении, куда указывает её голова;
Назад n (где n – целое число), вызывающая передвижение в противоположном голове направлении;
Направо m (где m – целое число), вызывающая изменение направления движения на m градусов по часовой стрелке,
Налево m (где m – целое число), вызывающая изменение направления движения на m градусов против часовой стрелки.
Запись Повтори k [Команда1 Команда2 … КомандаS] означает, что последовательность из S команд повторится k раз.
Черепахе был дан для исполнения следующий алгоритм:
Повтори 2 [Вперёд 8 Направо 90 Вперёд 18 Направо 90] Поднять хвост Вперёд 4 Направо 90 Вперёд 10 Налево 90 Опустить хвост Повтори 2 [Вперёд 17 Направо 90 Вперёд 7 Направо 90]
Определите, сколько точек с целочисленными координатами будут находиться внутри объединения фигур, ограниченного заданными алгоритмом линиями, включая точки на линиях.
Ответ: Пример 1: 38, Пример 2: 275
✍ Решение:
-
Задание 1:
- Запустите программу Кумир.
- В окне редактора введите код для Черепахи:
использовать Черепаха алг нач цел а опустить хвост нц для а от 1 до 7 вперед(10) вправо(120) кц кон
✎ Программное решение:
Python:
from turtle import * # увеличиваем масштаб в 20 tracer(0) lt(90) pd() for _ in range(7): fd(10*20) rt(120) up() # рисуем точки с учетом масштаба (_* 20) for x in range(20): for y in range(20): goto(x*20, y*20) dot(5) update() |
Ответ: 38
Задание 2:
✎ Программное решение:
Python:
from turtle import * screensize(1200, 1200) tracer(0) lt(90) pd() for _ in range(2): fd(8*20) rt(90) fd(18*20) rt(90) up() fd(4*20); rt(90) fd(10*20); lt(90) down() for _ in range(2): fd(17*20) rt(90) fd(7*20) rt(90) up() for x in range(30): for y in range(30): goto(x*20, y*20) dot(5) update() |
Ответ: 275
Прибор автоматической фиксации нарушений правил дорожного движения делает цветные фотографии размером 1024×768 пикселей, используя палитру из 4096 цветов. Для передачи снимки группируются в пакеты по 256 штук. Определите максимальный размер одного пакета фотографий в Мбайт.
В ответе запишите только число.
Ответ: 288
✍ Решение:
- По формуле объема файла изображения имеем:
- Глубину цвета можно найти из формулы:
- Из формулы имеем
i = 12
. - Посчитаем объем, необходимый для передачи одной фотографии:
где N — общее количество пикселей или разрешение,
а i — глубина цвета (количество бит, выделенное на 1 пиксель)
I = 1024*768*12 бит = 1024*768*12 / (8 * 1024 * 1024) Мбайт = 1.125 Мбайт
Теперь вычислим объем, необходимый для передачи пакета:
1.125 * 256 = 288 Мбайт
Ответ: 288
Ответ: 180
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
-
✎ Теоретическое решение:
✎ Программное решение:
Язык pascalABC.NET (классический):
## var count:=0; foreach var a1 in '1234567' do foreach var a2 in '01234567' do foreach var a3 in '01234567' do foreach var a4 in '01234567' do foreach var a5 in '01234567' do begin var number:=a1+a2+a3+a4+a5; if number.Count = number.Distinct.Count then if (number.countOf('1')=0) then if ((integer(a1)+integer(a2)).NotDivs(2)) and ((integer(a2)+integer(a3)).NotDivs(2)) and ((integer(a3)+integer(a4)).NotDivs(2)) and ((integer(a4)+integer(a5)).NotDivs(2)) then begin count+=1; //print(number); end; end; print(count) |
Язык pascalABC.NET (LINQ):
## uses school; var numb:='01234567'.cartesian(5)// т.к. цифр 5 штук .where(w->w.First<>'0') // первая цифра не может быть 0 .where(w->w.count=w.distinct.count) .where(w->w.CountOf('1')=0) .where(w->w.Pairwise.All(\(a,b)-> ((integer(a)+integer(b))mod 2 <>0)))// проверка пар 6 и нечетное .count.print |
Откройте файл электронной таблицы, содержащей в каждой строке семь натуральных чисел. Определите количество строк таблицы, для чисел которых выполнены оба условия:
В ответе запишите только число.
Ответ: 83
✍ Решение:
- Откроем файл электронной таблицы. Будем считать, сколько встречается каждый ячейка первой строки в диапазоне всех ячеек первой строки. Для этого создадим формулы и расположим их также в первой строке:
H1 = СЧЁТЕСЛИ($A1:$G1;A1)
т.е. в диапазоне A1:G1
ищем А1
. Знак доллара используется для фиксации буквы при копировании.
Скопируйте формулу на 6 ячеек вправо:
I1 = СЧЁТЕСЛИ($A1:$G1;B1) J1 = СЧЁТЕСЛИ($A1:$G1;C1) K1 = СЧЁТЕСЛИ($A1:$G1;D1) L1 = СЧЁТЕСЛИ($A1:$G1;E1) M1 = СЧЁТЕСЛИ($A1:$G1;F1) N1 = СЧЁТЕСЛИ($A1:$G1;G1)
0
или 1
. Будем использовать отдельно две формулы:O1 = ЕСЛИ((СЧЁТЕСЛИ(H1:N1; 2) = 4);1;0) P1 = ЕСЛИ((СЧЁТЕСЛИ(H1:N1; 1) = 3);1;0)
СУММЕСЛИ
для поиска двоек в диапазоне H:N
, и последующего сложения соответствующих им ячеек диапазона A:G
. Результат разделим на 4:Q1 = СУММЕСЛИ(H1:N1; 2; A1:G1)/4
R1 = СУММЕСЛИ(H1:N1; 1; A1:G1)/3
O1
и P1
. Таким образом, получим единицу, в случае выполнения всех условий и 0 — в обратном случае:S = O1*P1*(Q1<R1)
T = СУММ(S:S)
Ответ: 83
Определите, сколько раз в тексте главы II повести А.И. Куприна «Поединок» встречается сочетание букв «все» или «Все» только в составе других слов, но не как отдельное слово. В ответе укажите только число.
Ответ: 9
При регистрации в компьютерной системе каждому объекту присваивается идентификатор, состоящий из 60 символов и содержащий только десятичные цифры и символы из 250-символьного специального алфавита.
В базе данных для хранения каждого идентификатора отведено одинаковое и минимально возможное целое число байт. При этом используется посимвольное кодирование идентификаторов, все символы кодируются одинаковым и минимально возможным количеством бит.
Определите объём памяти (в Кбайт), необходимый для хранения 65 536 идентификаторов.
В ответе запишите только целое число – количество Кбайт.
Ответ: 4352
Исполнитель Редактор получает на вход строку символов и преобразовывает её. Редактор может выполнять две команды, в обеих командах v и w обозначают цепочки символов.
А) заменить (v, w).
заменить (111, 27)
преобразует строку 05111150 в строку 0527150.Если в строке нет вхождений цепочки v, то выполнение команды заменить (v, w)
не меняет эту строку.Б) нашлось (v).
Дана программа для Редактора:
НАЧАЛО ПОКА нашлось (52) ИЛИ нашлось (2222) ИЛИ нашлось (1122) ЕСЛИ нашлось (52) ТО заменить (52, 11) КОНЕЦ ЕСЛИ ЕСЛИ нашлось (2222) ТО заменить (2222, 5) КОНЕЦ ЕСЛИ ЕСЛИ нашлось (1122) ТО заменить (1122, 25) КОНЕЦ ЕСЛИ КОНЕЦ ПОКА КОНЕЦ
На вход приведённой выше программе поступает строка, начинающаяся с цифры «5», а затем содержащая n цифр «2» (3 < n < 10 000).
Определите наибольшее значение n
, при котором сумма цифр в строке, получившейся в результате выполнения программы, равна 64.
Ответ: 56
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
-
✎ Решение с использованием программирования:
✎ Программное решение:
Язык pascalABC.NET (классический):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | begin var sum: biginteger; sum := 0; for var n := 4 to 9999 do begin var s := '5' + '2' * n; while ('52' in s) or ('2222' in s) or ('1122' in s) do begin if '52' in s then s := s.Replace('52', '11', 1); if '2222' in s then s := s.Replace('2222', '5', 1); if '1122' in s then s := s.Replace('1122', '25', 1); end; var numb := s.ToBigInteger; while numb > 0 do begin sum += numb mod 10; numb := numb div 10; end; if sum = 64 then print(n); sum := 0; end; end. |
Язык Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 | res = set() for n in range(10, 1000): s = '5' + '2'*n while '52' in s or '2222' in s or '1122' in s: if '52' in s: s = s.replace('52', '11', 1) if '2222' in s: s = s.replace('2222', '5', 1) if '1122' in s: s = s.replace('1122', '25', 1) if sum(map(int, s)) == 64 : res.add(n) print(max(res)) |
В терминологии сетей TCP/IP маской сети называют двоичное число, которое показывает, какая часть IP-адреса узла сети относится к адресу сети, а какая – к адресу узла в этой сети. Адрес сети получается в результате
применения поразрядной конъюнкции к заданному адресу узла и маске сети.
Сеть задана IP-адресом 192.168.32.160 и маской сети 255.255.255.240.
Сколько в этой сети IP-адресов, для которых сумма единиц в двоичной записи IP-адреса чётна?
В ответе укажите только число.
Ответ: 8
Пример 1:
Операнды арифметического выражения записаны в системе счисления с основанием 19.
98897x2119 + 2x92319
В записи чисел переменной x
обозначена неизвестная цифра из алфавита 19-ричной системы счисления.
Определите наибольшее значение x
, при котором значение данного арифметического выражения кратно 18.
Для найденного x
вычислите частное от деления значения арифметического выражения на 18 и укажите его в ответе в десятичной системе счисления.
Основание системы счисления указывать не нужно.
ИЛИ
Пример 2:
Значение арифметического выражения
3 ∙ 31258 + 2 ∙6257 – 4 ∙6256 + 3 ∙1255 – 2 ∙254 – 2024
записали в системе счисления с основанием 25. Сколько значащих нулей
содержится в этой записи?
Ответ: Пример1: 469034148 Пример2:9
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
-
✎ Программное решение:
Язык pascalABC.NET (классический):
uses school; begin foreach var x in '0123456789abcdefghi'do begin var a:=('98897'+x+'21'); // строковое значение var b:=('2'+x+'923');// строковое значение var a1:= dec(a,19); // перевод в десятичную сс var b1:=dec(b,19); var s:=a1 + b1; if s mod 18 =0 then begin //print(x,s); print((s/18)); end; end; end. |
Для какого наименьшего целого неотрицательного числа A
выражение
(x + 2y < A) ∨ (y > x) ∨ (x > 60)
тождественно истинно, т.е. принимает значение 1 при любых целых неотрицательных x
и y
?
Ответ: 181
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
-
✎ Теоретическое решение:
✎ Программное решение:
Язык pascalABC.NET (классический):
begin for var A := 1 to 200 do begin var ok := 1; for var x := 1 to 500 do for var y := 1 to 500 do begin if (x + 2 * y < A) or (y > x) or (x > 60)=false then begin ok:=0; end; end; if ok=1 then print(a); end; end. |
Алгоритм вычисления значения функции F(n), где n
– натуральное число, задан следующими соотношениями:
F(n) = n при n > 2024; F(n) = n × F(n + 1), если n ≤ 2024
Чему равно значение выражения F(2022) / F(2024)
?
Ответ: 4090506
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
✎ Программное решение:
PascalABC.NET:
Решается только с типом данных BigInteger!
1 2 3 4 5 6 7 8 9 | function f(n: integer): biginteger; begin if n > 2024 then result := n else result := n * f(n + 1); end; begin print(f(2022) / f(2024)); end. |
Питон:
1 2 3 4 5 6 | def f(n): if n>2024: return n else: return n*f(n+1) print(f(2022)/f(2024)) |
C++:
1 |
Ответ: 4090506
В файле содержится последовательность натуральных чисел, каждое из которых не превышает 100 000. Определите количество троек элементов последовательности, в которых ровно два из трёх элементов являются трёхзначными числами, а сумма элементов тройки не больше максимального элемента последовательности, оканчивающегося на 13.
Гарантируется, что в последовательности есть хотя бы одно число, оканчивающееся на 13. В ответе запишите количество найденных троек чисел, затем максимальную из сумм элементов таких троек.
В данной задаче под тройкой подразумевается три идущих подряд элемента последовательности.
Ответ: 959 | 97471
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
-
✎ Программное решение:
Язык pascalABC.NET (классический):
## var a := ReadLines('17_2024.txt').Select(t -> t.ToInteger).ToArray; var counter := 0; var maxSum := 0; var m := 0; for var i := 0 to a.High do begin if a[i] mod 100 = 13 then m := max(a[i], m); end; for var i := 0 to a.High - 2 do begin if((a[i] in 100..999) and (a[i + 1] in 100..999) and (not (a[i + 2] in 100..999))) or ((a[i + 1] in 100..999) and (a[i + 2] in 100..999) and (not (a[i] in 100..999))) or ((a[i] in 100..999) and (a[i + 2] in 100..999) and (not (a[i + 1] in 100..999))) then if (a[i] + a[i + 1] + a[i + 2]) <= m then begin counter += 1; maxSum := max(maxSum, (a[i] + a[i + 1] + a[i + 2])); end; end; println(counter, maxSum) |
Язык pascalABC.NET (классический):
## uses school; var a := ReadLines('17_2024.txt').Select(t -> t.ToInteger); var m:=a.where(x->x mod 100 = 13).max; var triples := a.NWise(3) .Where(\(a,b,c)->((a in 100..999) and (b in 100..999) and (not (c in 100..999 ))) or ((b in 100..999) and (c in 100..999) and (not (a in 100..999 ))) or ((a in 100..999) and (c in 100..999) and (not (b in 100..999 )))) .Where (\(a,b,c)-> a+b+c<=m); triples.Count.Print; var maxSum:=triples.Select(t->(t[0]+t[1]+t[2])).max.print; |
Квадрат разлинован на N × N клеток (1 < N < 30). Исполнитель Робот может перемещаться по клеткам, выполняя за одно перемещение одну из двух команд: вправо или вниз. По команде вправо Робот перемещается в соседнюю правую клетку, по команде вниз – в соседнюю нижнюю.
Квадрат ограничен внешними стенами. Между соседними клетками квадрата также могут быть внутренние стены. Сквозь стену Робот пройти не может.
Перед каждым запуском Робота в каждой клетке квадрата лежит монета достоинством от 1 до 100. Посетив клетку, Робот забирает монету с собой; это также относится к начальной и конечной клеткам маршрута Робота.
В «угловых» клетках поля – тех, которые справа и снизу ограничены стенами, Робот не может продолжать движение, поэтому накопленная сумма считается итоговой. Таких конечных клеток на поле может быть несколько, включая правую нижнюю клетку поля. При разных запусках итоговые накопленные суммы могут различаться.
Определите максимальную и минимальную денежные суммы, среди всех возможных итоговых сумм, которые может собрать Робот, пройдя из левой верхней клетки в конечную клетку маршрута. В ответе укажите два числа –
сначала максимальную сумму, затем минимальную.
Исходные данные представляют собой электронную таблицу размером N×N, каждая ячейка которой соответствует клетке квадрата. Внутренние и внешние стены обозначены утолщёнными линиями.
Ответ: 2167 | 718
Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в кучу один камень или увеличить количество камней в куче в два раза. Для того чтобы делать ходы, у каждого игрока есть неограниченное количество камней.
Игра завершается в тот момент, когда количество камней в куче становится не менее 129. Победителем считается игрок, сделавший последний ход, т.е. первым получивший кучу из 129 или больше камней.
В начальный момент в куче было S
камней, 1 ≤ S ≤ 128
.
Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.
Укажите минимальное значение S, при котором Петя не может выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим первым ходом.
Ответ: 64
Для игры, описанной в задании 19, найдите два наименьших значения S
, при которых у Пети есть выигрышная стратегия, причём одновременно выполняются два условия:
Найденные значения запишите в ответе в порядке возрастания.
Ответ: 32 | 63
Для игры, описанной в задании 19, найдите минимальное значение S
, при котором одновременно выполняются два условия:
Если найдено несколько значений S
, в ответе запишите минимальное из них.
Ответ: 62

В файле содержится информация о совокупности N
вычислительных процессов, которые могут выполняться параллельно или последовательно. Будем говорить, что процесс B зависит от процесса A, если для выполнения процесса B необходимы результаты выполнения процесса A. В этом случае процессы A и B могут выполняться только последовательно.
Информация о процессах представлена в файле в виде таблицы. В первой строке таблицы указан идентификатор процесса (ID
), во второй строке таблицы – время его выполнения в миллисекундах, в третьей строке перечислены с разделителем «;
» ID процессов, от которых зависит данный процесс. Если процесс независимый, то в таблице указано значение 0
.
Время выполнения процесса B (мс) | ID процесса(-ов) A | |
1 | 4 | 0 |
2 | 3 | 0 |
3 | 1 | 1;2 |
4 | 7 | 3 |
Определите максимальную продолжительность отрезка времени (в мс), в течение которого возможно одновременное выполнение четырёх процессов, при условии, что все независимые друг от друга процессы могут
выполняться параллельно.
Типовой пример имеет иллюстративный характер. Для выполнения задания используйте данные из прилагаемого файла.
Ответ: 7
Исполнитель преобразует число на экране.
У исполнителя есть две команды, которые обозначены латинскими буквами:
А. Прибавить 1
B. Умножить на 2
C. Возвести в квадрат
Программа для исполнителя – это последовательность команд.
Сколько существует программ, для которых при исходном числе 2 результатом является число 20, при этом траектория вычислений не содержит числа 11?
Траектория вычислений программы – это последовательность результатов выполнения всех команд программы.
Ответ: 37

Текстовый файл состоит из символов T, U, V, W, X, Y и Z.
Определите в прилагаемом файле максимальное количество идущих подряд символов (длину непрерывной подпоследовательности), среди которых символ T
встречается ровно 100 раз.
Для выполнения этого задания следует написать программу.
Ответ: 133
Назовём маской числа последовательность цифр, в которой также могут встречаться следующие символы:
?
» означает ровно одну произвольную цифру;*
» означает любую последовательность цифр произвольной длины; в том числе «*» может задавать и пустую последовательность.Среди натуральных чисел, не превышающих 1010, найдите все числа, соответствующие маске 1?2157*4
, делящиеся на 2024 без остатка.
В ответе запишите в первом столбце таблицы все найденные числа в порядке возрастания, а во втором столбце – соответствующие им результаты деления этих чисел на 2024.
Количество строк в таблице для ответа избыточно.
... ... ... ... ... ...
Ответ:
142157664 70236 1021575544 504731 1121571264 554136 1221577104 603546 1321572824 652951 1421578664 702361 1521574384 751766 1621570104 801171 1721575944 850581 1821571664 899986 1921577504 949396
🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
✍ Решение:
Язык pascalABC.NET (классический):
|
||
Python:
|
||
С++:
|

Входной файл содержит сведения о заявках на проведение мероприятий в конференц-зале. В каждой заявке указаны время начала и время окончания мероприятия (в минутах от начала суток). Если время начала одного
мероприятия меньше времени окончания другого, то провести можно только одно из них. Если время окончания одного мероприятия совпадает со временем начала другого, то провести можно оба. Определите, какое
максимальное количество мероприятий можно провести в конференц-зале и каков при этом максимально возможный перерыв между двумя последними мероприятиями.
Входные данные
В первой строке входного файла находится натуральное число N
(N ≤ 1000) – количество заявок на проведение мероприятий. Следующие N строк содержат пары чисел, обозначающих время начала и время окончания мероприятий. Каждое из чисел натуральное, не превосходящее 1440.
Запишите в ответе два числа: максимальное количество мероприятий и самый длинный перерыв между двумя последними мероприятиями (в минутах).
5 10 150 100 120 131 170 150 180 120 130
При таких исходных данных можно провести максимум три мероприятия, например, мероприятия по заявкам 2, 3 и 5. Максимальный перерыв между двумя последними мероприятиями составит 20 мин., если состоятся мероприятия по заявкам 2, 4 и 5.
Типовой пример имеет иллюстративный характер. Для выполнения задания используйте данные из прилагаемых файлов.
Ответ: 32 | 15
По каналу связи передаётся последовательность целых чисел – показания прибора. В течение N мин. (N – натуральное число) прибор ежеминутно регистрирует значение напряжения (в условных единицах) в электрической сети и передаёт его на сервер.
Определите три таких переданных числа, чтобы между моментами передачи любых двух из них прошло не менее K
мин., а сумма этих трёх чисел была максимально возможной. Запишите в ответе найденную сумму.
Входные данные
Даны два входных файла (файл A и файл B), каждый из которых в первой строке содержит натуральное число K
– минимальное количество минут, которое должно пройти между моментами передачи показаний, а во второй – количество переданных показаний N
(1 ≤ N ≤ 10 000 000, N > K).
В каждой из следующих N
строк находится одно целое число, по модулю не превышающее 10 000 000, которое обозначает значение напряжения в соответствующую минуту.
Запишите в ответе два числа: сначала значение искомой величины для файла А, затем – для файла B.
2 6 150 –150 20 –200 –300 0
При таких исходных данных искомая величина равна 170 – это сумма значений, зафиксированных на первой, третьей и шестой минутах измерений (150 + 20 + 0).
Типовой пример имеет иллюстративный характер. Для выполнения задания используйте данные из прилагаемых файлов.
Предупреждение: для обработки файла B не следует использовать переборный алгоритм, вычисляющий сумму для всех возможных вариантов, поскольку написанная по такому алгоритму программа будет выполняться слишком долго.
Ответ: 189536 | 17210
ЕГЭ по информатике -> демоверсия ЕГЭ 2024
Python video
Урок 1
MOSH:
Python Tutorial — Python Full Course for Beginners here
00:13:03 Variables
00:18:21 Receiving Input
MOSH:
Python Tutorials for Beginners — Learn Python Online here
Learn Python Programming — Python Course here
Lesson #18. String type and regular expressions
Theory
Lecture in pdf format
Char type
c: char; ... c:='a'; |
begin var c: char; c:='a'; Println(c.IsDigit); // False Println(c.IsLetter); // True Println(c.IsLower); // True Println(c.IsUpper); // False Println(c.IsPunctuation); // знак препинания, boolean с := char.ToLower(с) ; с := char.ToUpper(с); end. |
c1 < c2;// сравнение по коду c1 > c2; с in ['a','e','i','o','u',’y’]; // c принадлежит гласным с in ['a'..'z','A'..'Z’]; // c принадлежит английским буквам |
Запросите ввести два символа. Определите, принадлежат ли символы английским буквам, и если да, то гласные ли это буквы. Преобразуйте в верхний регистр ту букву, код которой меньше.
Пример вывода:
Введите два символа: u z u - английская буква, гласная z - английская буква, не гласная Буква u в верхнем регистре U
String type
s: string; ... s:='abc'; |
begin var s: string; s:='Abc'; Println(s.ToLower); // abc Println(s.ToUpper); // ABC end. |
Slices of the strings:
begin var s: string; s:='12345678'; Println(s[3:6]); // 345 Println(s[::-1]); // 87654321 end. |
String methods:
Сonversion string <-> number
:
begin var s: string; s:='12345678'; var i:=1; Println(i.ToString); // string '1' Println(s.ToInteger); // number 12345678 Println(s.ToReal); // number 12345678 end. |
or
begin var s: string; s:='12345678'; var i:=1; Println(integer.TryParse(s,i)); // is it possible to convert s to a number - True end. |
Сonversion of a string to an array of words:
begin var s:='it is a piece of cake'; var ss:=s.ToWords.Println('_'); // it_is_a_piece_of_cake ss.Sorted.Println // a cake of piece is it end. |
Sample: remove all «i» letters:
begin var s:='it is a piece of cake'; s:=s.Where(c -> c<>'i').JoinIntoString; print(s); // t s a pece of cake end. |
While working with strings we can use any sequence method
Reguglar expressions
Язык регулярных выражений — это язык шаблонов, расширенные операции поиска и замены для строк.
Основной цикл:
s := 'red green gray blue'; foreach var m in s.Matches('\w+') do Print(m.Value, m.Index); |
Т.е. m: Match
включает m.Value
, m.Index
Опции регулярных выражений:
s := 'AБракадабРА'; s.Matches('бра', RegexOptions.IgnoreCase) |
Примеры регулярных выражений:
‘кот|кит’ ‘к[ио]т’ ‘к[а-я]т’ ‘ко+т’ ‘кор?т’ ‘к.т’ ‘к\.т’ ‘к.*т’
‘ко{3}т’ ‘ко{2,4}т’ ‘ко[^ъыь]т’ ‘\b кот\b’
Управляющие символы и их запись в регулярных выражениях:
\ * + ? | { [ ( ) ^ $ . #
Они экранируются дополнительным \
Квантификаторы:
*
— 0 или более повторений
+
— 1 или более повторений
?
— 0 или 1 повторение
{N}
— ровно N повторений
{N,}
— не менее N повторений
{N,M}
— от N до M повторений
Директивы нулевой длины:
^
— начало строки
$
— конец строки
\b
— позиция на границе слова
Классы символов:
[abcd]
— один из символов, указанных в списке
[^abcd]
— любой из символов, кроме тех, которые указаны в списке
[a-d]
— один из символов, лежащих в указанном диапазоне
[^a-d]
— любой из символов, кроме тех, которые лежат в указанном диапазоне
\d
— десятичная цифра: [0-9]
\D
— любой символ, кроме десятичной цифры
\w
— буква, цифра или символ подчеркивания
\W
— любой символ, не являющийся словообразующим;
\s
— пробельный символ, т. е. [ \t\r\n];
\S
— любой непробельный символ;
.
— любой символ
Группы:
s := ' prepod@sfedu.ru prepod2@sfedu.ru '; foreach var m in s.Matches('(\w+)@(\w+).(\w+)') do Println(m.Groups[0], m.Groups[1], m.Groups[2], m.Groups[3]); s.Matches('(т[оае])\1*') |
Замена с помощью регулярного выражения:
s.Replace('\b\w+\b', '<$0>') s := s.Replace('\w+',m->m.Value.ToUpper); s := s.Replace('\w+',m->m.Value+'('+m.Length+')') s := '10+2=12'; s.Replace('\d+', '<$0>') // <10>+<2>=<12> s.Replace('\d+', m -> (m.Value.ToInteger*2).ToString) // 20+4=24 s := ' prepod@sfedu.ru prepod2@sfedu.ru '; s.Replace('(\w+)@(\w+).(\w+)', '$1-$2-$3') |
Урок 17 windows forms. Создание пользовательского элемента управления
Дальше — больше… Урок 17 windows forms. Создание пользовательского элемента управления
Урок 16 windows forms. Работа с мышью
Lesson #14. Lambda expressions
lambda expression Theory
x
. begin var x: integer-> integer; x:= t -> t * t; Print(x(7)); // 49 x := t -> t * t * t; Print(x(7)); // 343 end. |
2. Declaring and initialization of a procedural variable at the same time:
begin var x: integer-> integer:= t -> t * t; Print(x(7)); // 49 x := t -> t * t * t; Print(x(7)); // 343 end. |
→
instead of ->
(on the keyboard: with the Alt
key pressed, we type 26
on the small numeric keypad).begin var f: (integer,integer) → integer :=(x, y) -> if x > y then result:=x else result:=y; print(f(5,13)) end. |
()
.begin var f: (integer,integer) → () :=(x, y) -> if x > y then print(x) else print(y); f(5,13) end. |
begin var x: integer-> () := t -> (t * t).Print(); x(5) // 25 end. |
procedure Pr(a,b:integer; var sum,mult:integer); begin sum:=a+b; mult:=(a*b); end; begin var sum,mult:integer; Pr(2,4,sum,mult); print(sum,mult) // (6,8) end. |
2. Solution using a procedural variable with tuple assignment and a lambda expression:
begin var f: (integer,integer) -> (integer, integer); f := (a, b) -> (a + b, a * b); print(f(2, 4)) // (6,8) end. |
The results when a=-5, b=-1 and function x -> x * x
:
-5 25 -4 16 -3 9 -2 4 -1 1
✍ Solution:
procedure Lamb(a, b: integer; f: real-> real); begin for var x := a to b do begin Println(x, f(x)); end end; begin Lamb(-5, 3, x -> x * x); Writeln; end. |
Labs and tasks
{0.5 points}
Task 1:
To do: Create a procedural variable with one parameter — a two-digit number that returns a number in which the digits are swapped. Associate the variable with a lambda expression to perform the task. Do the task twice: the procedural variable returns the value and the procedural variable outputs the value. (see samples 2, 3, 4)
expected output:
enter two-digit number please: >> 72 27
[Program name: 14task-01.pas
]
{0.5 points}
Task 2:
To do: Calculate the value of the variable y by one of the two branches:
To solve this, create a procedural variable with two parameters — a
and b
, and associate it with a lambda expression. Complete the task twice: the procedural variable returns the value and the procedural variable outputs the value. (see samples 2, 3, 4)
expected output:
enter two numbers >>2 >>5 result: 3
[Program name: 14task-02.pas
]
{0.5 points}
Task 3:
To do: Create a Triangle(a,h)
function that calculates the perimeter of an isosceles triangle using its base a
and the height h
drawn to the base. (see sample 5 solution 2)
1. Declare the procedural variable TriangleP
, defining its type as a function that takes two real parameters and returns a real result:
var TriangleP: (real, real) -> real; |
2. Then, assign a lambda expression to this variable, which, using two parameters a
and h
— the base and height of an isosceles triangle — calculates the perimeter of this triangle (P = 2b+a
; the side formula: b2 = (a/2)2 + h2
)
expected output:
enter two numbers >>4 >>6 result: 16.6491106406735
[Program name: 14task-03.pas
]
{0.5 points}
Task 4:
To do: Declase a TrianglePS(a, P, S)
procedure that calculates an equilateral triangle’s perimeter P = 3·a
and area S = a2·(3)1/2/4
(a
— input triangle side, P
and S
— output parameters; all parameters are real). Using this procedure, output the perimeters and areas of three equilateral triangles with these sides. Solve this problem twice: a classical procedure and a procedural variable associated with a lambda expression. (see sample 5 solutions 1 and 2)
expected output:
>>2 61.73205080756888 >>5 1510.8253175473055 >>6 1815.5884572681199
[Program name: 14task-04.pas
]
Standard functions and procedures and Transformation of an array elements
To do: Create the function to search x in the array. The function returns -1 if it is not found and index of the element otherwise.
✍ Algorithm:
function IndexOfW<T>(a: array of T; x: T): integer; begin var n := a.Length; var i := 0; while (i < n) and (a[i] <> x) do i += 1; Result := i = n ? -1 : i; end; begin var a := new integer[10]; a := arrRandomInteger(10, 0, 10); print(a); print(indexOfW(a, 2)) end. |
To do: Print out how many odd elements are in the array.
Expected output:
[18,10,91,47,35] 3
✍ Algorithm:
begin var a := new integer[5]; a := arrRandomInteger(5); // [18,10,91,47,35] print(a); print(a.Count(a->odd(a))) // 3 end. |
To do: Transform the array elements using the rule: if element is even then substruct it by 1, if it is odd then add 1 to it.
✍ Algorithm:
begin var a := new integer[5]; a := arrRandomInteger(5); // [4,36,93,36,29] a.Transform(a,a -> a mod 2 = 0 ? a-1 : a + 1); print(a) // [3,35,94,35,30] end. |
{0.5 points}
Task 5:
To do: Create a randomly generated array. Use the standard functions and procedures to implement the following goals. Print out:
- reversed array (
Reverse()
) - the index of
x
number (x
is entered) - the last index of
x
number (x
is entered) (LastIndexOf()
) true
ifx
exists in the array,false
if it doesn’t (Contains()
)- index of the first even element (
IndexOf()
) - the number of positive elements in the array (
Count()
). You should create your own function that returnstrue
if the checked number is positive. - maximum element and it’s index (
Max()
,IndexMax()
). - transformed array with a rule: if element is positive then square it, if it is negative then set it to 0 (
Transform()
).
Expected output:
1. [1,6,6,4,9,9,1,3,3,10] result: 10 3 3 1 9 9 4 6 6 1 2. [8,10,0,5,10,7,2,9,8,2] enter x: >>10 the result: 1 3. [8,10,0,5,10,7,2,9,8,2] enter x: >>10 the result: 4 4. [8,10,0,5,10,7,2,9,8,2] enter x: >>3 the result: false 5. [7,1,0,3,2,4,2,10,9,4] result: 2 6. [7,-1,0,3,-2,4,2,-10,9,4] result: 7 7. [7,1,0,3,2,4,2,10,9,4] result: max = 10 indexMax= 7 8. [-8,5,1,-5,-8,10,-9,-7,-7,1] result: 0 25 1 0 0 100 0 0 0 1
[Program name: 14task-05.pas
]
- Open taskBook of pascalAbc.net IDE:
- Choose
ArrTransF
group in the dropdown menu and click html-page button: - Complete the tasks giving the files the proper names (
ArrTransf1.pas
etc.)
To do: Create an array of integer elements. Pint out the array values in the interval [10,19] and increase by one it’s positive values with even indexes.
Expected output:
array: [41,90,100,12,16,7,69,23,59,37] array values in the interval [10,19]: 12 16
✍ Algorithm:
begin var a:=arrRandomInteger(10); print(a); // values in the interval [10,19] foreach var i in a.Indices(x -> x.InRange(10,20)) do print(a[i]); // positive values with even indexes foreach var i in a.Indices((x,i) -> (i mod 2 = 0) and (x > 0)) do a[i] += 1; end. |
{0.4 points}
Task 6:
To do: Create a randomly generated array. Use indeces
method to print out:
- The values of the array with odd indexes.
- The second half of the array elements.
Expected output:
array: [8,41,56,82,8,93,44,70,6,54] The second half of the array elements: 8 41 56 82 8 The values of the array with odd indexes: 41 82 93 70 54
[Program name: 14task-06.pas
]
To do: Create the procedure to shift circularly the elements to the left
✍ Algorithm:
procedure CircularShiftLeft<T>(a: array of T); begin var v := a[0]; for var i:=0 to a.Length-2 do a[i] := a[i+1]; a[a.Length-1] := v; end; begin var a := new integer[5]; a := arrRandomInteger(5); // [56,28,33,57,25] CircularShiftLeft(a); print(a)// [28,33,57,25,56] end. |
To do: Create the procedure to shift circularly the elements to the right
✍ Algorithm:
procedure CircularShiftRight<T>(a: array of T); begin var v := a[a.Length-1]; for var i:=a.Length-1 downto 1 do a[i] := a[i-1]; a[0] := v; end; begin var a := new integer[5]; a := arrRandomInteger(5); // [25,23,74,17,31] CircularShiftRight(a); print(a)// [31,25,23,74,17] end. |
{0.3 points}
Task 7:
To do: Create a randomly generated array. At first, transform its elements using the rule: a-1, and after, reverse it’s elements and after, make a circular shift it’s elements to the right and to the left.
Expected output:
array: [93,25,52,74,76,40,54,13,29,65] transformed: [92,24,51,73,75,39,53,12,28,64] Shift left: [24,51,73,75,39,53,12,28,64,92] Shift right: [92,24,51,73,75,39,53,12,28,64]
[Program name: 14task-7.pas
]
Занятие 6. Pascal abc.net: Lambda-выражения
Дальше — больше… Занятие 6. Pascal abc.net: Lambda-выражения