Урок 7. Основы работы с указателями

Теория

1. Основы работы с указателями

  • Указатели — это способ указать местоположение переменной. Вместо хранения значения (5 или символ ‘c’), значением указателя является адрес другой переменной.
  • Переменные-указатели имеют размер (количество байт в памяти), имя и значение. Они должны быть объявлены и инициализированы.
  • «Указатель» (сам по себе) — это не тип. Это конструктор типов — языковая конструкция, которая при применении к другому типу дает нам новый тип. В частности, добавление звездочки ( * ) после любого типа задает название типу, который является указателем на этот тип.
  • /*
    объявляет переменную с именем my_char_pointer 
    с указателем типа на char 
    (переменная, указывающая на символ)
    */
    char * my_char_pointer;
    Объявление указателя
  • Объявление указателя сообщает нам имя переменной и тип переменной, на которую будет указывать этот указатель.
  • Присваивание указателю
  • Можно выполнять присваивание указателям, изменяя их значения. Изменение значения указателя означает изменение того, куда он указывает.
  • Прежде чем использовать указатель, необходимо инициализировать его (дать ему что-то, на что можно указывать).
  • Если мы не инициализируем указатель перед его использованием, то он будет указывать на какое-то случайное место в программе (это может привести к сбою программы).
  • Чтобы получить указатель, указывающий на некоторый адрес, нужно назначить имя полю памяти, а затем нам нужно использовать оператор &.
  • /* код, который объявляет целое число x и указатель на целое число xPtr */
    int x = 5;
    int *xPtr;
    xPtr = &x; // устанавливает значение переменной xPtr на адрес x
  • x инициализируется значением 5 в той же строке, в которой оно объявлено;
  • значение xptr инициализируется местоположением x;
  • после того, как он инициализирован, xPtr указывает на переменную x.
  • Код &x = 5; не будет скомпилирован. Программист может получить доступ к местоположению переменной, но изменить местоположение переменной невозможно.
  • Разыменовывание указателя

  • Как только у нас появятся указатель на адреса переменных, мы хотим использовать их, «следуя за стрелкой» и изменить ячейку, на которую ссылается указатель.
  • Символ звездочка * — унарный оператор, который разыменовывает указатель.
  • Обратите внимание, что зеленая стрелка указывает на то, что эта строка еще не была извлечена, следовательно, x все еще имеет значение 5 в концептуальном представлении. Однако, как только строка 7 будет выполнена, значение будет равно 6.
  • 6
    7
    
    // Пример использования оператора разыменования:
    *xPtr = 6; // изменяет значение, которое хptr указывает на 6
  • Обратите внимание, что зеленая стрелка указывает на то, что эта строка еще не была выполнена, следовательно, x все еще имеет значение 5 в концептуальном представлении. Однако, как только строка 7 будет выполнена, значение будет равно 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, мы собираемся указать, что указатель ни на что не указывает. Всякий раз, когда у нас есть NULL.
  • Нулевой указатель имеет особый тип — void *. Указатель void указывает на на любой тип — мы можем присвоить ему значение int *, double* или любой другой тип указателя, который мы хотим.

2. Указатели и массив

  • Массив представляет собой константный указатель на свой первый элемент.
  • Доступ к элементу массива с помощью арифметики указателей работает нормально и иногда является естественным способом доступа к элементам. Но в случае, когда нам нужен просто n-й элемент массива, было бы громоздко объявлять указатель, добавлять к нему, а затем разыменовывать его.
  • Пример:
  • // * 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);
    }
  • Можно достичь этой цели, проиндексировав массив. Когда мы индексируем массив, мы записываем имя массива, за которым следуют квадратные скобки, содержащие номер элемента, на который мы хотим сослаться. Важно отметить, что в C++ индексы массивов начинаются с нуля — первым элементом массива является myArray[0].
  • // * 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);
    }
    Поставим указатель p на начало массива:
    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. Основы работы с указателями

Лабораторная работа 0:
Выполнить: Создайте функцию для вычисления суммы указателя и переменной целочисленного типа. То есть функция должна возвращать сумму указателя и значения переменной.

Указание: Объявление функции должно быть таким:

int addP(int var1, int var2);

Примерный вывод:

введите первое число (указатель):
>>>2
введите второе число (которое прибавить):
>>>500
результат: указатель + 500 = 502

✍ Алгоритм:

  1. Создайте проект Lesson7. Добавьте в соответствующие папки проекта файлы: main7lab0.cpp, L7lab0.cpp, L7lab0.h.
  2. Откройте main7.cpp и подключите все необходимые директивы и файлы. Выведите сообщение пользователю для ввода двух значений. Первое значение — указатель, второе — для добавления:
  3. cout << "Lab 0:" << endl;
    cout << "пожалуйста, введите первое число (для указателя): "<< endl;
    int var1; 
    cin >> var1;
    cout << "пожалуйста, введите второе число (для добавления): " << endl;
    int var2; 
    cin >> var2;
    
  4. Переключитесь на код файла string7.h и подключите необходимые файлы и директивы:
  5. #pragma once
    #ifndef STRING7_H
    #define STRING7_H
    
    #include 
    // здесь ваш код
    #endif
    
  6. Зда добавим объявление функции, как это было рекомендовано в тексте задания:
  7. //lab 0: Создайте функцию для вычисления суммы указателя и переменной целочисленного типа
    int addP(int var1, int var2);
    
  8. Теперь добавим реализацию функции. Откройте файл string7.cpp, подключите все необходимые директивы и добавьте код:
  9. //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.
  10. Теперь можно вызвать созданную нами функцию и вывести результаты. Это необходимо сделать в файле main7.cpp:
  11. cout << "Результат:" << endl;
    cout << "указатель + " << var2 << " = " << addP(var1,var2) << endl;
    
  12. Добавьте инструкцию, возвращающую значение 0 внутри основной функции. Запустите программу и проверьте выходные данные.
Задание 1:

Выполнить: Создайте приложение с функцией, которая принимает два аргумента - целые числа (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:
Выполнить: Создайте функцию для вычисления суммы элементов массива. Задача должна быть выполнена с использованием двух функций. Первая функция не использует указатель, вторая функция должна использовать указатель, обращающийся к элементу массива по индексу.

Указание 1: Объявление функции:

int sumArray1(int * array, int n);
int sumArray2(int * array, int n);

Примерный вывод:

array:
1 2 3 4 5
результат выполнения первой функции: sum = 15
результат выполнения второй функции: sum = 15

✍ Алгоритм:

  1. Сначала давайте создадим функцию, которая выполняет итерацию по элементам массива без использования указателя:
  2. 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;
    
  3. Рассмотрим работу с памятью:
  4. 1. Первая итерация цикла:
    2. Вторая итерация цикла:
    3.Третья итерация цикла:
    4.Последняя итерация цикла:
    Возвращаемся к функции main и уничтожение области sumArray1:
  5. Теперь давайте создадим функцию, которая выполняет итерацию по элементам массива, используя указатель, обращающийся к элементу массива по индексу:
  6. 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;
    }
    
  7. Вызовите функцию в функции main и запустите программу.
Лабораторная работа 2, Массивы:
Выполнить: 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. Откройте приложение, которое вы создали для лабораторной 1, или, если вы ее не сделали, сделайте следующее: создайте пустое консольное приложение с именем Lesson7. Добавьте файлы: main7.cpp, string7.cpp, string7.h.
  2. Подключите все необходимые библиотеки и файлы (если вы не делали этого раньше).
  3. Откройте файл main7.cpp. Выведите сообщение для пользователя, объявите массив и инициализируйте его значениями:
  4. cout << "Лабораторная работа 2, Массивы:\n";
    int my_arr[] = { 1,2,3,4,5,6,7,8,9 };
    
  5. Распечатайте элементы исходного массива:
  6. cout << "Исходный массив: " << endl;
    for (auto x : my_arr) {
    	cout << x << " ";
    }
    
  7. После этого откройте файл string7.h и подключим все необходимые директивы (если это не было сделано ранее):
  8. #pragma once
    #ifndef STRING7_H
    #define STRING7_H
    
    #include 
    
    #endif
    
  9. Объявление функции должно быть таким, как рекомендовано в задании:
  10. // Лабораторная работа 2, Массивы: Дан массив (1, 2, 3, 4, 5, 6, 7, 8, 9). 
    // каждый второй элемент установите в 0
    void DelEveryEven(int* , int);
    
  11. Теперь необходимо написать саму функцию, т.е. ее реализацию. Откройте файл string7.cpp, подключите все необходимые директивы и добавьте код:
  12. //Лабораторная работа 2, массивы
    void DelEveryEven(int* array, int n) {
    	for (int* p = array + 1; p < array + n; p = p + 2) {
    		*p = 0;
    	}
    }
    
    Параметр *array инициализируется адресом массива.
    Здесь, в качестве счетчика цикла используется указатель на первый элемент массива+1.
    Рассмотрим строку int* p = array + 1;.

  13. array возвращает ячейку памяти первого элемента. Но нам необходимо установить в 0 второй элемент. Поэтому имеем array + 1.
  14. В строке *p = 0 мы разыменовываем указатель, а второй элемент устанавливаем = 0.
  15. Чтобы проделать те же манипуляции с четвертым элементом (четным), мы можем увеличить указатель на 2 (p = p + 2).
  16. array + n - ячейка памяти первого элемента + n, это 9. Затем происходит выход их цикла.
  17. Теперь можно вызвать функцию и вывести результаты. Это необходимо сделать вmain7.cpp:
  18. DelEveryEven(my_arr, 9);
    cout << "Результат: " << endl;
    for (auto x : my_arr) {
    	cout << x << " ";
    }
    cout << endl;
    
  19. Добавьте код, чтобы функция main возвращала 0. Запустите программу и проверьте выходные данные.
Задание 2_0:

Выполнить: Задан массив целых чисел. Создайте две функции, которые возвращают значение максимального элемента массива. Первая функция не использует указатель, вторая функция должна использовать указатель, обращающийся к элементу массива по индексу.

Указание: 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]

Task 2:

Выполнить: 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]

Task 3:

Выполнить: 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

Lab 3:
Выполнить: 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

✍ Алгоритм:

  1. Let's declare a function with two arguments, they are constant char pointers to the strings:
  2. int stringEqual(const char * str1, const char * str2){
    ...
    }
    
  3. Then, we're going to declare the pointers pointing at the first letter of str1 and the first letter of str2. Add the code into the function:
  4. const char* p1 = str1;
    const char* p2 = str2;
    
  5. Then, we're going to create a loop to be repeated as long as what p1 points at is the same as what p2 point at. We should use dereference operator to take the values, that is to take the characters of the strings:
  6.  while (*p1 == *p2) {
    
    	}
    
  7. 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 return 1 (that is answer "yes"):
  8. if (*p1 == '\0') {
        return 1;
    }
    
  9. After, we advance p1 and p2 to the next letter:
  10. p1++;
    p2++;
    
  11. After the loop we need to return answer "no", that is in our function means 0:
  12. return 0;
    
  13. Now, we're going to return to the main function and create two c-string. And then to call the function:
  14. char str1[] = "apple";
    char str2[] = "apples";
    cout << "the result for \'"<< str1 <<"\' and \'"<< str2 <<"\' is: " << stringEqual (str1,str2) << endl;
    
  15. Run the program and check the output.
Task 4:
Выполнить: 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]

Lab 4:
Выполнить: 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

✍ Алгоритм:

  1. 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.
  2. Include all necessary libraries and files (if you didn't do it before).
  3. 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):
  4. cout << "Lab 4:" << endl;
    char str[] = "Hello world"; 
    cout << "The string before lab is done: " << str << endl; 
    
  5. 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):
  6. #pragma once
    #ifndef STRING7_H
    #define STRING7_H
    
    #include 
    
    #endif
    
  7. The signature of the function was recommended in the task text, let's add that code with a comments of the task text:
  8. // Lab 4: Reverse the order of characters in the string. 
    void reverseString(char* str);
    
    str is initialized to the location of str.
  9. 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:
  10. // 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
    
    Here, we define a pointer to string's first character. The line (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).
  11. 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 variable t. 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:
  12. 	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
    	}
    
    
  13. Now you can call the function we've created and print the results. You must do it inside the main7.cpp file:
  14. reverseString(str);
    cout << "The string after lab is done: " << str << endl;
    
  15. Add the code to return a 0 value inside the main function. Run the program and check the output.
Task 5:
Выполнить: 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]

Task 6:

Выполнить: 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]

Task 7:

Выполнить: 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] == ' ')
    			//что-то делаем
    	}

Строковые функции

    Find()

    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 = '\''

Символьная строка и указатели

  • Символьная строка -это строка (массив символов) с нулевым символом в конце (\0).
  • 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

    Лабораторная работа1:

    Выполнить: Дана переменная строкового типа (s="Hello world") и дан символ (переменная c) (пользователь его вводит). Проверьте, есть ли символ c среди символов строки. Создайте функцию с именем checkIfChar. Функция должна возвращать 1, если введенный символ найден, или 0 в противном случае..

    Указание 1: Сигнатура функции должна быть следующей:

    bool checkIfChar(string s, char c)

    Примерный вывод:

    lab 1
    "Hello world"
    введите символ:
    >>> o
    результат:
    1
    

    ✍ Алгоритм:

    1. Откройте visual studio и создайте консольное приложение с Lesson6.
    2. Добавьте два файла .cpp в папку исходных файлов проекта (basicStrings.cpp и main.cpp) и один файл заголовка должен быть добавлен в папку заголовочные файлы.
    3. Откройте код main.cpp и добавьте все библиотеки, которые нам нужны для выполнения лабораторной работы:
    4. #include 
      #include  //
      #include  // необходим для работы со строковым типом
      using namespace std;
      
    5. В функции main() добавьте код с просьбой пользователя ввести предложение и присвойте входное значение переменной str. Не забудьте объявить переменную::
    6. int main() {
      	cout << "lab 1:" << endl;
      	string str="Hello world"; 
      	
        // ..
      }
      
    7. Затем попросите пользователя ввести символ. Присвойте значение переменной c:
    8. cout << "Enter character :" << endl;
      	char c;
      	cin >> c;
      
    9. Теперь необходимо создать функцию для проверки, находится ли символ в предложении. Функция должна быть с двумя аргументами — предложением (str) и символом (c). Добавьте заголовок объявления функции перед функцией main():
    10.  //lab 1: 
      bool checkIfChar(string s, char c)
      {
      	// выполнение
      }
      
    11. Добавьте код прохода по символам строки, используя цикл for. Внутри тела цикла мы должны проверить, соответствует ли текущий символ строки символу c. Если это так, функция должна возвращать 1, в случае, когда это не так, функция возвращает 0.
    12. for (int i=0;i<= s.size();i++){
      		if (s[i]==c){
      			return 1;
                              break;
                       }
      	}
      return 0;
      
    13. Вернитесь к функции main() и вызовите созданную функцию. Результаты функции должны быть выведены, поэтому вызов должен быть внутри инструкции cout<<:
    14. cout << "result :" << checkIfChar(str, c) << endl;
      
    15. Не забудьте добавить инструкцию, чтобы окно консоли оставалось открытым:
    16. //...
      system("pause");
      return 0;
      //...
      
    17. Запустите программу и проверьте выходные данные.
    Задание 1:

    Выполнить: Создайте функцию для проверки того, содержит ли вводимый текст комбинацию букв "mo". Функция должна возвращать 1 (если содержит) или 0 (если не содержит). Не допускается использование каких-либо стандартных функций.

    Указание 1: Сигнатура функции должна быть следующей:

    bool findMo(string s)

    Указание 2: Чтобы проверить два или более условия в операторе if, вы должны использовать && (логическое И):

    if (condition_1 && condition_2){
    }

    Примерный вывод:

    Задание 1
    результат для 'Hello world':
    0
    ---
    Задание 1
    результат для 'My mom':
    1
    

    Задание 2: Символьные строки

    Выполнить: Создайте функцию для проверки, содержит ли строковая переменная слово "собака". Функция возвращает 1 или 0. Необходимо использовать символьную строку c и указатель. Не допускается использование каких-либо стандартных функций.

    Указание 1: Сигнатура функции должна быть следующей:

    bool findMo(char* p)

    Примерный вывод:

    задание 2
    строка: Hello world
    результат:
    0
    ---
    задание 2
    строка: my dog is nice
    результат:
    1
    
    Задание 3:

    Выполнить: Дано предложение: str = "слово1 слово2 слово3 слово4". Подсчитайте количество слов в нем. Не допускается использование каких-либо стандартных функций.

    Указание 1: Вы должны подсчитать количество слов по количеству пробелов между словами.

    Указание 2: Не забудьте проверить, не содержит ли предложение дополнительных пробелов в начале и конце предложения.

    Указание 3: Сигнатура созданной функции должна быть следующей:

    void countWords(string s, int& counter)

    Примерный вывод:

    задание 3
    Введите предложение:
    >>>  word1 word2 word3 word4
    результат:
    4
    

    Задание 4:

    Выполнить: Дана строка. Проверьте, совпадают ли ее первый и последний символы. Создайте функцию с идентификаторами LastAndFirst(). Не допускается использование каких-либо стандартных функций (кроме функции size()).

    Указание 1: Заголовок функции:

    bool LastAndFirst(string s)

    Указание 2: Метод size() может быть полезен для поиска последнего символа (s.size()).

    Примерный вывод:

    задание 4
    Для предложения Hello world
    результат:
    false
    ---
    задание 4
    Для предложения lucky ball
    результат:
    true
    

    String functions

    Задание 5:

    Выполнить: Создайте функцию для проверки, содержит ли текст слово 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
    
    Лабораторная работа 2:

    Выполнить: Даны две строки 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
    

    ✍ Алгоритм:

    1. Открытый файл main.cpp и в коде основной функции, под предыдущим кодом задания, добавьте комментария с номером задания. После этого объявите переменные строкового типа и инициализируйте их значениями:
    2. //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 используется для перехода на новую строку.
    3. Откройте файл basicStrings.cpp и добавьте код заголовка функции:
    4. // lab 2: 
      int countOccurrence(string s, string s0)
      {
         // to do:
      } 
      
    5. Функция должна возвращать целочисленный тип.
    6. Функция имеет два параметра строкового типа: s - строка, содержащая предложение, и s0 - подстрока, которую мы должны найти в строке s.
    7. Чтобы найти подстроку, мы собираемся использовать стандартный метод find() и переменную f типа size_t (целочисленный тип без знака). Переменная f хранит положение подстроки внутри строки s. И если нет искомой подстроки, то f сохранит число 0, так как оно будет увеличено на 1 (f+1). Когда функция find() достигнет конца строки, значение npos (npos — это константа - максимальное значение для size_t (обычно = 4294967295)) будет присвоено переменной f:
    8.  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 будет выполнен только в том случае, если при поиске подстрок мы дойдем до конца строки.
    9. Вернитесь к main.cpp файлу и внутри основной функции добавьте вызов нашей функции. Поскольку функция вернет целочисленное значение, то есть количество вхождений, мы должны сохранить результат функции в переменной:
    10. int counter = countOccurrence(str1, str2);
      cout << "result :"  << counter << endl;
      
    11. Запустите программу и посмотрите выходные данные.
    Задание 6:

    Выполнить: Даны строки 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
    
    Задание 7:

    Выполнить: Дана строка, содержащая по крайней мере один символ пробела. Необходимо возвратить подстроку между первым и последним пробелами строки. Если строка содержит один пробел, должна быть возвращена пустая строка.

    Указание 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 решение

    группа vk вконтакте

    группа fb facebook

    *** ПЛЕЙЛИСТ КАНАЛА ЮТЬЮБ ***
     
    ЕГЭ по информатике -> демоверсия ЕГЭ 2024
     
    Скачать pdf демоверсии варианта ->
      

    1.
    1 задание. Демо ЕГЭ 2024 информатика, ФИПИ:

    На рисунке изображена схема дорог Н-ского района. В таблице звёздочкой обозначено наличие дороги из одного населённого пункта в другой. Отсутствие звёздочки означает, что такой дороги нет.

    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)
    • Найдем эти вершины в таблице: пункты 2 и 6.
    • По таблице видим, что на пересечении данных пунктов находятся пункты 7 и 4, соответствующие вершинам D3 и G3.
    • Так как вершине C соответствует единственный уникальный пункт 1, то в таблице остаются только пункт 3 и 5, которые и соответствуют вершинам E и F.

    Ответ: 35

    2.
    2 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Миша заполнял таблицу истинности логической функции 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='')

    3.
    3 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Задание выполняется с использованием прилагаемых файлов

    В файле приведён фрагмент базы данных «Кондитерские изделия» о поставках конфет и печенья в магазины районов города. База данных состоит из трёх таблиц.
    Таблица «Движение товаров» содержит записи о поставках товаров в магазины в течение первой половины июня 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


    4.
    4 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    По каналу связи передаются сообщения, содержащие только восемь букв:
    А, Б, В, Г, Д, Е, Ж и З.
    Для передачи используется двоичный код, удовлетворяющий условию Фано.
    Кодовые слова для некоторых букв известны:

    А – 000
    Б – 001
    В - 0101
    Г - 0100
    Д - 011
    Е - 101
    

    Какое наименьшее количество двоичных знаков потребуется для кодирования двух оставшихся букв?
    В ответе запишите суммарную длину кодовых слов для букв: Ж, З

    Ответ: 5

    ✍ Решение:

      Для решения используем дерево. Влево откладываем 0, вправо — 1:

      Для букв Ж и З имеем кодовые слова: 100 и 11. Суммарная длина = 5.

    Ответ:

    5


    5.
    5 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
    1. Строится двоичная запись числа N.
    2. Далее эта запись обрабатывается по следующему правилу:
      а) если число N делится на 3, то к этой записи дописываются три последние двоичные цифры;
     б) если число N на 3 не делится, то остаток от деления умножается на 3, переводится в двоичную запись и дописывается в конец числа.
    Полученная таким образом запись является двоичной записью искомого числа R.
    3. Результат переводится в десятичную систему и выводится на экран.

    Например, для исходного числа 12 = 11002 результатом является число 11001002 = 100, а для исходного числа 4 = 1002 это число 100112 = 19.

    Укажите минимальное число R, большее 151, которое может быть получено с помощью описанного алгоритма В ответе это число запишите в десятичной системе счисления.

    Ответ: 163
      
      
    🎦 Программное решение (PascalAbc.Net): YouTube и RuTube
     
    ✍ Решение:

      ✎ Программное решение:

      Язык pascalABC.NET (классический):

      uses school;
      begin
        var l := new List<integer>;
        for var n_:=10 to 1000 do
        begin
          var n:=n_;
          var n2:=bin(n).ToString;
          if n.Divs(3) then
            n2+=(n2[n2.Length-2]+ n2[n2.Length-1]+n2[n2.Length])
          else
            n2+= bin((n mod 3)*3);
          var r:=dec(n2,2);
           if r>151 then
             l.Add(r)
        end;
        l.Min.Print;
      end.
      Python:

      res = set()
      for x in range(1, 152):
         nx = bin(x)[2:]
         if x % 3 == 0:
           nx += nx[-3: ]
         else:
           nx += bin((x%3) * 3)[2:]
         R = int(nx, 2)
         if R > 151:
            res.add(R)
      print(min(res))

    Ответ: 163


    6.
    6 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Исполнитель Черепаха действует на плоскости с декартовой системой координат. В начальный момент Черепаха находится в начале координат, её голова направлена вдоль положительного направления оси ординат, хвост
    опущен. При опущенном хвосте Черепаха оставляет на поле след в виде линии. В каждый конкретный момент известно положение исполнителя и направление его движения. У исполнителя существует две команды:
    Вперёд 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

    7.
    7 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Прибор автоматической фиксации нарушений правил дорожного движения делает цветные фотографии размером 1024×768 пикселей, используя палитру из 4096 цветов. Для передачи снимки группируются в пакеты по 256 штук. Определите максимальный размер одного пакета фотографий в Мбайт.

    В ответе запишите только число.

    Ответ: 288

      ✍ Решение:

    • По формуле объема файла изображения имеем:
    • I = N * i

      где N — общее количество пикселей или разрешение,
      а i — глубина цвета (количество бит, выделенное на 1 пиксель)

    • Глубину цвета можно найти из формулы:
    • 2i=кол-во цветов
    • Из формулы имеем i = 12.
    • Посчитаем объем, необходимый для передачи одной фотографии:
    • I = 1024*768*12 бит = 1024*768*12 / (8 * 1024 * 1024) Мбайт = 1.125 Мбайт

      Теперь вычислим объем, необходимый для передачи пакета:

      1.125 * 256 = 288 Мбайт

    Ответ: 288

    * При устном решении задания легче переводить значения в степени двойки, так 1024=210, 256=28, 8 = 23. После этого значения легко сокращаются в обыкновенной дроби.

    8.
    8 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

  • Сколько существует восьмеричных пятизначных чисел, не содержащих в своей записи цифру 1, в которых все цифры различны и никакие две чётные или две нечётные цифры не стоят рядом?
  • Ответ: 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

    9.
    9 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Задание выполняется с использованием прилагаемых файлов

    Откройте файл электронной таблицы, содержащей в каждой строке семь натуральных чисел. Определите количество строк таблицы, для чисел которых выполнены оба условия:

  • в строке есть два числа, каждое из которых повторяется дважды, остальные три числа различны;
  • среднее арифметическое всех повторяющихся чисел строки меньше среднего арифметического всех её чисел.
  • В ответе запишите только число.

    Ответ: 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)
      
    • Выделите диапазон ячеек с созданными формулами и щелкните по маркеру копирования (справа), чтобы скопировать формулы на нижние строки.
    • Затем создадим формулы для поиска строк, в которых 2 пары повторяющихся чисел, то есть 4 двойки, и остальные числа не повторяются, т.е. 3 единицы. Вместо логического результата будем выводить 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


    10.
    10 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Задание выполняется с использованием прилагаемых файлов

    Определите, сколько раз в тексте главы II повести А.И. Куприна «Поединок» встречается сочетание букв «все» или «Все» только в составе других слов, но не как отдельное слово. В ответе укажите только число.

    Ответ: 9


    11.
    11 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    При регистрации в компьютерной системе каждому объекту присваивается идентификатор, состоящий из 60 символов и содержащий только десятичные цифры и символы из 250-символьного специального алфавита.
    В базе данных для хранения каждого идентификатора отведено одинаковое и минимально возможное целое число байт. При этом используется посимвольное кодирование идентификаторов, все символы кодируются одинаковым и минимально возможным количеством бит.
    Определите объём памяти (в Кбайт), необходимый для хранения 65 536 идентификаторов.
    В ответе запишите только целое число – количество Кбайт.

    Ответ: 4352


    12.
    12 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Исполнитель Редактор получает на вход строку символов и преобразовывает её. Редактор может выполнять две команды, в обеих командах v и w обозначают цепочки символов.
    А) заменить (v, w).

    Эта команда заменяет в строке первое слева вхождение цепочки v на цепочку w. Например, выполнение команды заменить (111, 27) преобразует строку 05111150 в строку 0527150.Если в строке нет вхождений цепочки v, то выполнение команды заменить (v, w) не меняет эту строку.

    Б) нашлось (v).

    Эта команда проверяет, встречается ли цепочка 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))

    13.
    13 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    В терминологии сетей TCP/IP маской сети называют двоичное число, которое показывает, какая часть IP-адреса узла сети относится к адресу сети, а какая – к адресу узла в этой сети. Адрес сети получается в результате
    применения поразрядной конъюнкции к заданному адресу узла и маске сети.
    Сеть задана IP-адресом 192.168.32.160 и маской сети 255.255.255.240.
    Сколько в этой сети IP-адресов, для которых сумма единиц в двоичной записи IP-адреса чётна?

    В ответе укажите только число.

    Ответ: 8


    14.
    14 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:
    Пример 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.


    15.
    15 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Для какого наименьшего целого неотрицательного числа A выражение

    (x + 2y < A) ∨ (y > x) ∨ (x > 60)

    тождественно истинно, т.е. принимает значение 1 при любых целых неотрицательных x и y?

    Ответ: 181

    * в ответах ФИПИ дано ошибочное 7

     
    🎦 Программное решение (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.

    16.
    16 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Алгоритм вычисления значения функции 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


    17.
    17 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Задание выполняется с использованием прилагаемых файлов

    В файле содержится последовательность натуральных чисел, каждое из которых не превышает 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;

    18.
    18 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Задание выполняется с использованием прилагаемых файлов

      
    Квадрат разлинован на N × N клеток (1 < N < 30). Исполнитель Робот может перемещаться по клеткам, выполняя за одно перемещение одну из двух команд: вправо или вниз. По команде вправо Робот перемещается в соседнюю правую клетку, по команде вниз – в соседнюю нижнюю.
    Квадрат ограничен внешними стенами. Между соседними клетками квадрата также могут быть внутренние стены. Сквозь стену Робот пройти не может.
    Перед каждым запуском Робота в каждой клетке квадрата лежит монета достоинством от 1 до 100. Посетив клетку, Робот забирает монету с собой; это также относится к начальной и конечной клеткам маршрута Робота.
    В «угловых» клетках поля – тех, которые справа и снизу ограничены стенами, Робот не может продолжать движение, поэтому накопленная сумма считается итоговой. Таких конечных клеток на поле может быть несколько, включая правую нижнюю клетку поля. При разных запусках итоговые накопленные суммы могут различаться.

    Определите максимальную и минимальную денежные суммы, среди всех возможных итоговых сумм, которые может собрать Робот, пройдя из левой верхней клетки в конечную клетку маршрута. В ответе укажите два числа –
    сначала максимальную сумму, затем минимальную.

    Исходные данные представляют собой электронную таблицу размером N×N, каждая ячейка которой соответствует клетке квадрата. Внутренние и внешние стены обозначены утолщёнными линиями.

    Ответ: 2167 | 718

    19.
    19 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в кучу один камень или увеличить количество камней в куче в два раза. Для того чтобы делать ходы, у каждого игрока есть неограниченное количество камней.
    Игра завершается в тот момент, когда количество камней в куче становится не менее 129. Победителем считается игрок, сделавший последний ход, т.е. первым получивший кучу из 129 или больше камней.

    В начальный момент в куче было S камней, 1 ≤ S ≤ 128.
    Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.

    Укажите минимальное значение S, при котором Петя не может выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим первым ходом.

    Ответ: 64


    20.
    20 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Для игры, описанной в задании 19, найдите два наименьших значения S, при которых у Пети есть выигрышная стратегия, причём одновременно выполняются два условия:

  • Петя не может выиграть за один ход;
  • Петя может выиграть своим вторым ходом независимо от того, как будет ходить Ваня.
  • Найденные значения запишите в ответе в порядке возрастания.

    Ответ: 32 | 63


    21.
    21 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Для игры, описанной в задании 19, найдите минимальное значение S, при котором одновременно выполняются два условия:

  • у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;
  • у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.
  • Если найдено несколько значений S, в ответе запишите минимальное из них.

    Ответ: 62


    22.
    22 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Задание выполняется с использованием прилагаемых файлов

    В файле содержится информация о совокупности N вычислительных процессов, которые могут выполняться параллельно или последовательно. Будем говорить, что процесс B зависит от процесса A, если для выполнения процесса B необходимы результаты выполнения процесса A. В этом случае процессы A и B могут выполняться только последовательно.
    Информация о процессах представлена в файле в виде таблицы. В первой строке таблицы указан идентификатор процесса (ID), во второй строке таблицы – время его выполнения в миллисекундах, в третьей строке перечислены с разделителем «;» ID процессов, от которых зависит данный процесс. Если процесс независимый, то в таблице указано значение 0.

    Типовой пример организации данных в файле:
    ID процесса B

    Время выполнения процесса B (мс) ID процесса(-ов) A
    1 4 0
    2 3 0
    3 1 1;2
    4 7 3

    Определите максимальную продолжительность отрезка времени (в мс), в течение которого возможно одновременное выполнение четырёх процессов, при условии, что все независимые друг от друга процессы могут
    выполняться параллельно.

    Типовой пример имеет иллюстративный характер. Для выполнения задания используйте данные из прилагаемого файла.

    Ответ: 7


    23.
    23 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Исполнитель преобразует число на экране.
    У исполнителя есть две команды, которые обозначены латинскими буквами:
    А. Прибавить 1
    B. Умножить на 2
    C. Возвести в квадрат

    Программа для исполнителя – это последовательность команд.

    Сколько существует программ, для которых при исходном числе 2 результатом является число 20, при этом траектория вычислений не содержит числа 11?
    Траектория вычислений программы – это последовательность результатов выполнения всех команд программы.

    Например, для программы CBA при исходном числе 4 траектория будет состоять из чисел 16, 32, 33.

    Ответ: 37
      


    24.
    24 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:
     

    Задание выполняется с использованием прилагаемых файлов

     
    Текстовый файл состоит из символов T, U, V, W, X, Y и Z.
    Определите в прилагаемом файле максимальное количество идущих подряд символов (длину непрерывной подпоследовательности), среди которых символ T встречается ровно 100 раз.

    Для выполнения этого задания следует написать программу.

    Ответ: 133


    25.
    25 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    Назовём маской числа последовательность цифр, в которой также могут встречаться следующие символы:

  • символ «?» означает ровно одну произвольную цифру;
  • символ «*» означает любую последовательность цифр произвольной длины; в том числе «*» может задавать и пустую последовательность.
  • Например, маске 123*4?5 соответствуют числа 123405 и 12300405.

    Среди натуральных чисел, не превышающих 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 (классический):

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      begin
        var x: biginteger;
        x := 2024;
        while x <= 10000000000 do
        begin
          if(x.ToString[1] = '1') and (x.ToString[3] = '2') and
            (x.ToString[4] = '1') and (x.ToString[5] = '5') and
            (x.ToString[6] = '7') and (x mod 10 = 4) then
            println(x, x / 2024);
          x += 2024;
        end;
      end.
      Python:

      1
      
       
      С++:

      1
      
       

    26.
    26 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:
     

    Задание выполняется с использованием прилагаемых файлов

     
    Входной файл содержит сведения о заявках на проведение мероприятий в конференц-зале. В каждой заявке указаны время начала и время окончания мероприятия (в минутах от начала суток). Если время начала одного
    мероприятия меньше времени окончания другого, то провести можно только одно из них. Если время окончания одного мероприятия совпадает со временем начала другого, то провести можно оба. Определите, какое
    максимальное количество мероприятий можно провести в конференц-зале и каков при этом максимально возможный перерыв между двумя последними мероприятиями.

    Входные данные
    В первой строке входного файла находится натуральное число 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


    27.
    27 задание. Демоверсия варианта ЕГЭ по информатике 2024, ФИПИ:

    A
    B
    Задание выполняется с использованием прилагаемых файлов

      
    По каналу связи передаётся последовательность целых чисел – показания прибора. В течение 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

    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.
    Операции для типа char
    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. Создание пользовательского элемента управления

    Lesson #14. Lambda expressions

    lambda expression Theory

  • A lambda expression is some unnamed expression representing a functional dependency.
  • Based on lambda expression, the compiler builds a function, identifies it in some way and replaces this lambda expression with this identifier.
  • A lambda expression can be stored in procedural variables, or passed as parameters of a procedural type.
  • Sample 1: An example of a lambda expression that returns, first, the square of the parameter, and then returns the parameter to the third power. The lambda expression is stored in the procedural variable x.
    1. Declaring of a procedural variable, and then binding it to a lambda expression:

    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.
    IDE PascalABC.NET allows you to use a beautiful arrow instead of -> (on the keyboard: with the Alt key pressed, we type 26 on the small numeric keypad).
    Sample 2: An example of a procedural variable with two parameters that returns the maximum of the parameters using a lambda expression.
    begin
      var f: (integer,integer)integer :=(x, y) -> if x > y then result:=x else result:=y;
      print(f(5,13))
    end.
    If a procedural variable is intended to store procedures (and not functions), then when declaring it, empty brackets must be specified after the arrow -> ().
    Sample 3: An example of a procedural variable with two parameters that outputs the maximum of the parameters using a lambda expression.
    begin
      var f: (integer,integer)() :=(x, y) -> if x > y then print(x) else print(y);
      f(5,13)
    end.
    Sample 4: An example of a lambda expression that outputs the squared parameter.
    begin
    var x: integer-> () := t -> (t * t).Print();
    x(5) // 25
    end.
    Sample 5: Example of a procedural variable with tuple assignment: the variable is associated with a lambda expression that takes two integers and returns their sum and product:
    1. A classic solution using the procedure:

    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.
    Lambda function as a parameter
    Sample: Create a procedure that outputs a list of values of an arbitrary function of one argument on the range [a;b].

    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

    Lab 1:

    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.
    Lab 2:

    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.
    Lab 3:

    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:

    1. reversed array (Reverse())
    2. the index of x number (x is entered)
    3. the last index of x number (x is entered) (LastIndexOf())
    4. true if x exists in the array, false if it doesn’t (Contains())
    5. index of the first even element (IndexOf())
    6. the number of positive elements in the array (Count()). You should create your own function that returns true if the checked number is positive.
    7. maximum element and it’s index (Max(), IndexMax()).
    8. 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]

    Extra tasks:

    1. Open taskBook of pascalAbc.net IDE:
    2. Choose ArrTransF group in the dropdown menu and click html-page button:
    3. Complete the tasks giving the files the proper names (ArrTransf1.pas etc.)
    Lab 4, Loop over some indices:

    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]

    Lab 5:

    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.
    Lab 6:

    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]

    Вставить формулу как
    Блок
    Строка
    Дополнительные настройки
    Цвет формулы
    Цвет текста
    #333333
    Используйте LaTeX для набора формулы
    Предпросмотр
    \({}\)
    Формула не набрана
    Вставить