DenisKrut 6 / 6 / 9 Регистрация: 18.03.2014 Сообщений: 176 |
||||
1 |
||||
Динамический массив, найти сумму элементов01.02.2015, 00:16. Показов 9671. Ответов 8 Метки нет (Все метки)
Помогите пожалуйста.В одномерном массиве состоящем из n целых элементов, вычислить. Добавлено через 6 минут
0 |
hoggy 8724 / 4304 / 958 Регистрация: 15.11.2014 Сообщений: 9,751 |
||||
01.02.2015, 00:33 |
2 |
|||
http://rextester.com/ZKNOIZ85999
0 |
ivan.-94 Я Фоюмчанин ? дааааа) 213 / 204 / 23 Регистрация: 02.06.2012 Сообщений: 1,424 Записей в блоге: 12 |
||||
01.02.2015, 17:09 |
3 |
|||
Вы бы хоть попытались разобраться
0 |
TaiGeddar 6 / 6 / 6 Регистрация: 13.01.2014 Сообщений: 110 |
||||
01.02.2015, 17:15 |
4 |
|||
Пардон, меня опередили. Добавлено через 5 минут
1 |
Я Фоюмчанин ? дааааа) 213 / 204 / 23 Регистрация: 02.06.2012 Сообщений: 1,424 Записей в блоге: 12 |
|
01.02.2015, 17:17 |
5 |
ivan.-94, а разве abs работает без math.h? Да, работает.
0 |
6 / 6 / 6 Регистрация: 13.01.2014 Сообщений: 110 |
|
01.02.2015, 17:21 |
6 |
ivan.-94, знаешь… я идиот упоротый, я хотел спросить работает ли rand() без cstdlib.
0 |
Я Фоюмчанин ? дааааа) 213 / 204 / 23 Регистрация: 02.06.2012 Сообщений: 1,424 Записей в блоге: 12 |
|
01.02.2015, 17:29 |
7 |
Да и abs определена в stdlib.h, но в этом проекте пока не убрал этот заголовочный – abs не работал. Добавлено через 5 минут Добавлено через 26 секунд
0 |
6 / 6 / 6 Регистрация: 13.01.2014 Сообщений: 110 |
|
01.02.2015, 17:37 |
8 |
ivan.-94,
sum=a[0]; a[0] может быть не нуливым, а ты его прибавляешь. Ошибся или я что-то не так понял? Добавлено через 3 минуты
0 |
ivan.-94 Я Фоюмчанин ? дааааа) 213 / 204 / 23 Регистрация: 02.06.2012 Сообщений: 1,424 Записей в блоге: 12 |
||||
01.02.2015, 17:44 |
9 |
|||
РешениеTaiGeddar, Да вы почти правы, только не в ту сторону)) Добавлено через 5 минут
1 |
Обычно, объем памяти, необходимый для той или иной переменной, задается еще до процесса компиляции посредством объявления этой переменной. Если же возникает необходимость в создание переменной, размер которой неизвестен заранее, то используют динамическую память. Резервирование и освобождение памяти в программах на C++ может происходить в любой момент времени. Осуществляются операции распределения памяти двумя способами:
- с помощью функции malloc, calloc, realloc и free;
- посредством оператора new и delete.
Функция malloc резервирует непрерывный блок ячеек памяти для хранения указанного объекта и возвращает указатель на первую ячейку этого блока. Обращение к функции имеет вид:
void *malloc(size);
Здесь size — целое беззнаковое значение, определяющее размер выделяемого участка памяти в байтах. Если резервирование памяти прошло успешно, то функция возвращает переменную типа void *, которую можно привести к любому необходимому типу указателя.
Функция — calloc также предназначена для выделения памяти. Запись ниже означает, что будет выделено num элементов по size байт.
void *calloc (nime, size);
Эта функция возвращает указатель на выделенный участок или NULL при невозможности выделить память. Особенностью функции является обнуление всех выделенных элементов.
Функция realloc изменяет размер выделенной ранее памяти. Обращаются к ней так:
char *realloc (void *p, size);
Здесь p — указатель на область памяти, размер которой нужно изменить на size. Если в результате работы функции меняется адрес области памяти, то новый адрес вернется в качестве результата. Если фактическое значение первого параметра NULL, то функция realloc работает также, как и функция malloc, то есть выделяет участок памяти размером size байт.
Для освобождения выделенной памяти используется функция free. Обращаются к ней так:
void free (void *p size);
Здесь p — указатель на участок памяти, ранее выделенный функциями malloc, calloc или realloc.
Операторы new и delete аналогичны функциям malloc и free. New выделяет память, а его единственный аргумент — это выражение, определяющее количество байтов, которые будут зарезервированы. Возвращает оператор указатель на начало выделенного блока памяти. Оператор delete освобождает память, его аргумент — адрес первой ячейки блока, который необходимо освободить.
Динамический массив — массив переменной длины, память под который выделяется в процессе выполнения программы. Выделение памяти осуществляется функциями calloc, malloc или оператором new. Адрес первого элемента выделенного участка памяти хранится в переменной, объявленной как указатель. Например, следующий оператор означает, что описан указатель mas и ему присвоен адрес начала непрерывной области динамической памяти, выделенной с помощью оператора new:
int *mas=new int[10];
Выделено столько памяти, сколько необходимо для хранения 10 величин типа int.
Фактически, в переменной mas хранится адрес нулевого элемента динамического массива. Следовательно, адрес следующего, первого элемента, в выделенном участке памяти — mas+1, а mas+i является адресом i-го элемента. Обращение к i-му элементу динамического массива можно выполнить, как обычно mas[i], или другим способом *(mas +i). Важно следить за тем, чтобы не выйти за границы выделенного участка памяти.
Когда динамический массив (в любой момент работы программы) перестает быть нужным, то память можно освободить с помощью функции free или оператора delete.
Предлагаю рассмотреть несколько задач, закрепляющих данный урок:
Задача 1
Найти сумму вещественных элементов динамического массива.
//Пример использования функции malloc и free #include "stdafx.h" #include <iostream> using namespace std; int main() { setlocale(LC_ALL,"Rus"); int i, n; float *a; //указатель на float float s; cout<<"n"; cin>>n; //ввод размерности массива //выделение памяти под массив из n вещественных элементов a=(float *)malloc(n*sizeof(float)); cout<<"Введите массив A n"; //ввод элементов массива for (i=0; i<n; i++) { cin>>*(a+i); } //накапливание суммы элементов массива for (s=0, i=0; i<n; i++) s+=*(a+i); //вывод значения суммы cout<<"S="<<s<<"n"; //освобождение памяти free(a); system("pause"); return 0; }
Задача 2
Изменить динамический массив целых чисел таким образом, чтобы его положительные элементы стали отрицательными и наоборот. Для решения задачи мы будем умножать каждый элемент на -1.
//Пример использования операторов new и delete #include "stdafx.h" #include <iostream> using namespace std; int main() { setlocale(LC_ALL,"Rus"); int i, n; //ввод количества элементов массива cout<<"n="; cin>>n; //выделение памяти int *a=new int[n]; cout<<"Введите элементы массива:n"; //ввод массива for (i=0; i<n; i++) cin>>a[i]; //вывод заданного массива for (i=0; i<n; i++) cout<<a[i]<<"t"<<"n"; //преобразование массива for (i=0; i<n; i++) a[i]=-a[i]; //вывод преобразованного массива for (i=0; i<n; i++) cout<<a[i]<<"t"; cout<<"n"; //освобождение памяти delete []a; system("pause"); return 0; }
printf(“По адресу p1=%p хранится *p1=%gn”,p1,*p1); printf(“По адресу p2=%p хранится *p2=%en”,p2,*p2);
}
По адресу p1=0012FF7C хранится *p1=3.14159
По адресу p2=0012FF7C хранится *p2=2.642140e-308
В указателях p1 и p2 хранится один и тот же адрес, но значения, на которые они ссылаются, оказываются разными. Это связано с тем, указатель типа *float адресует 4 байта, а указатель *double 8байт .После присваивания p2=(double *)p1;при обращении к *p2происходит следующее: к переменной, хранящейся по адресу p1, дописывается еще 4 байта из памяти. В результате значение *p2 не совпадает со значением *p1.
А что произойдет в результате следующей программы?
#include <stdio.h> #include <math.h> int main()
{
double PI=3.14159,*p1; float *p2;
p1=&PI; p2=(float *)p1;
printf(“По адресу p1=%p хранится *p1=%gn”,p1,*p1); printf(“По адресу p2=%p хранится *p2=%en”,p2,*p2);
}
После присваивания p2=(double *)p1; при обращении к *p2 происходит следующее: из переменной, хранящейся по адресу p1, выделяется только 4 байта. В результате и в этом случае значение *p2 не совпадает со значением *p1.
ВЫВОД. При преобразовании указателей разного типа приведение типов разрешает только синтаксическую проблему присваивания. Следует помнить, что операция * над указателями различного типа, ссылающимися на один и тот же адрес, возвращает различные значения.
Если есть следующий оператор
float *p;
то в переменной p хранится адрес, а с помощью конструкции *p можно получить значение, хранящееся по адресу p.
В случае использования оператора
float p;
то для вычисления адреса используется конструкция &p, а в переменной p находится вещественное значение.
Над адресами в языке Си определены следующие операции:
●суммирование, можно добавлять к указателю целое значение;
●вычитание, можно вычитать указатели или вычитать из указателя целое число. Однако при выполнении арифметических операций есть некоторые особенности. Рассмотрим их на следующем примере.
double *p1; float *p2; int *i;
p1++
p2++;
i++;
}
Операция p1++ увеличивает значение адреса на 8, операция p2++ увеличивает значение адреса на 4, а операция i++ на 2. Операции адресной арифметики выполняются следующим образом:
● операция увеличения приводит к тому, что указатель будет слаться на следующий объект базового типа (для p1 это double,для p2 float,для i int);
●операция уменьшения приводит к тому, что указатель, ссылается на предыдущий объект базового типа.
●после операции p1=p1+n, указатель будет передвинут на n объектов базового типа; p1+n как бы адресует n-й элемент массива, если p1 адрес начала массива .
5.4.5. Использование адресов и указателей при работе с массивами. Динамические массивы.
С помощью указателей в Си можно выделить участок памяти (динамический массив1) заданного размера для хранения данных определенного типа. Для этого необходимо выполнить следующие действия :
1.Описать указатель (например, переменную p) определенного типа.
2.Начиная с адреса, определенного указателем, с помощью функций calloc, malloc или операции new выделить участок памяти определенного размера. После этого p будет адресом первого элемента выделенного участка оперативной памяти (0-й элемент массива), p+1 будет адресовать следующий элемент в выделенном участке памяти (1-й элемент динамического массива), & , p+i является адресом i-го элемента.
Необходимо только следить, чтобы не выйти за границы выделенного участка памяти. К i-му элементу динамического массива p можно обратиться одним из двух способов
*(p+i) или p[i].
3.Когда участок памяти будет не нужен, его можно освободить с помощью функции free(), операции delete.
Перед подробным описанием работы с динамическими переменными, рассмотрим функции calloc, malloc, realloc и free и операции new и delete.
Единственным параметром функции malloc является целое беззнаковое значение, определяющее размер выделяемого участка памяти в байтах. Функция malloc возвращает бестиповый указатель (void *) на выделенный участок памяти. Обращение к функции malloc имеет вид
void *malloc(n);
здесь n определяет размер выделяемого участка памяти в байтах, функция вернет значение NULL, если выделить память не удалось и указатель на выделенный участок памяти, при успешном выделении.
В качестве примера использования функции malloc решим следующую задачу.
Найти сумму элементов динамического массива вещественных чисел.
#include <iostream> #include <malloc.h> using namespace std; int main()
{
int i,n; float *a,s;
cout<<“n=”;
cin>>n;
// Выделение памяти для динамического массива а. a=(float *)malloc(n*sizeof(float));
cout << “Vvedite massiv A”; for(i=0;i<n;i++)
// cin>>a[i]; cin>>*(a+i);
for(s=0,i=0;i<n;i++)
//s+=a[i];
s+=*(a+i); cout << “S=”<<s;
//Освобождение памяти. free(a);
return 0;
}
Кроме функции malloc для выделения памяти в Си есть функция calloc. Ее особенностью является обнуление всех выделенных элементов. Обращение к функции имеет вид:
void *calloc (num, size);
Функция calloc выделяет num элементов по size байт и возвращает указатель на выделенный участок или NULL при невозможности выделить память.
Ниже приведено решение задачи поиска суммы элементов динамического массива
вещественных чисел с помощью функции calloc.
#include <iostream> #include <malloc.h> using namespace std; int main()
{
int i,n; float *a,s; cout<<“n=”; cin>>n;
// Выделение памяти для динамического массива а. a=(float *)calloc(n,sizeof(float));
cout << “Vvedite massiv A”; for(i=0;i<n;i++)
cin>>*(a+i);
for(s=0,i=0;i<n;i++)
s+=*(a+i); cout << “S=”<<s;
//Освобождение памяти. free(a);
return 0;
}
Функция realloc изменяет размер выделенной ранее памяти, обращение к ней имеет вид:
char *realloc(void *p, size);
Функция изменяет размер участка памяти, на который указывает p, новый размер участка памяти size. Если при этом пришлось изменять месторасположение участка памяти, то новое его месторасположение и возвращается в качестве результата. Если в качестве p передается NULL, то функция realloc работает аналогично функции malloc.
Для освобождения выделенной памяти используется функция free. Обращение к ней имеет вид
Соседние файлы в предмете Программирование на C++
- #
- #
- #
- #
- #
- #
- #
- #
Работа с динамическими массивами в Паскаль abc.net
Содержание:
- Динамические массивы
- Объявление, выделение памяти
- Инициализация, присваивание и вывод
- Вывод массива
- Очистка динамического массива
- Работа с элементами массива
- Методы для работы с массивами
- Некоторые алгоритмы работы с массивами
- Срезы
- Удаление и вставка элементов массива. Списки
- Решение задач
- Простые задачи
- Задачи на срезы
- Использование методов
Динамические массивы
Объявление, выделение памяти
Обычно в языке Паскаль используются статические массивы вида:
var mas: array [1..10] of integer;
Границы статического массива изменить в ходе программы нельзя, так как они задаются в разделе объявлений «раз и навсегда».
Основным недостатком такого массива является то, что в случае, когда заранее не известно количество элементов массива, то приходится выделять память максимального размера, что называется «на всякий случай».
Рассмотрим работу с динамическим массивом.
Объявляется динамический массив в теле программы:
begin ... var a: array of integer;
Или объявление с инициализацией:
А выделение памяти и размер такого массива задается уже по ходу программы:
var a: array of integer; var n:=readInteger; a:=new integer[n];
var a: array of integer; a:=new integer[readInteger];
var a: array of integer; var n:=readInteger; SetLength(a,n); // устанавливаем размер массива а
Ссылочная объектная модель: память выделяется служебным словом NEW
Организация памяти для массива a
Инициализация, присваивание и вывод
Возможна инициализация динамического массива при описании:
var a: array of integer := (1,2,3);
Новые способы заполнения массива (заполнители):
var a:=Arr(1,2,3);// по правой части - integer
var a:=ArrFill(5,2); // 2 2 2 2 2
Ввод с клавиатуры:
var a:=ReadArrInteger(5); var a:=ReadArrReal(5);
Заполнение случайными числами:
var a:=new integer[10]; a:=arrRandomInteger(10);
или с дополнительными параметрами (диапазон [5;15]):
var a:=arrRandomInteger(10,5,15);
Вывод массива
Или с разделителем между элементами:
Или:
Или с использованием метода:
a.Print; // пример вывода: 1 5 3 13 20 a.PrintLines; // каждый элемент с новой строки
Переприсваивание:
var a: array of integer := (1,2,3); var b:=a; // [1,2,3]
Но!
Если теперь переприсвоить значение элементов массива b
, то изменится и массив a
:
var a: array of integer := (1,2,3); var b:=a; b[2]:=1; print(a); //[1,2,1]
Для того, чтобы избежать данной ситуации, необходимо создать массив b
, как копию массива a
:
var a: array of integer := (1,2,3); var b:=Copy(a); b[2]:=1; print(a); //[1,2,3]
Очистка динамического массива
Если в программе случайно создается повторно один и тот же массив:
var a: array of integer; a:=new integer[4]; ... a:=new integer[5];
В результате возникают так называемые участки «утекшей» памяти (неиспользуемой).
Постепенно произойдет переполнение памяти. В платформе .net используется автоматический сборщик мусора.
Но можно очистить память и принудительно:
В процессе очистки выполнение программы и всех процессов приостанавливается. По этой причине сборщик мусора в системах реального времени не используется.
Работа с элементами массива
- Цикл for
- Цикл foreach
for var i:=0 to High(a) do print(a[i]);;
foreach var x in a do print(x);
High(массив)
— возвращает верхнюю границу динамического массива
Пример: поиск элемента в массиве (выдавать индекс искомого)
Выполнение:
Выполним сначала БЕЗ использования обобщенной функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function IndexOf(a:array of integer;x:integer):integer; begin result:=-1; for var i:=0 to High(a) do if a[i]=x then begin result:=i; break end end; begin var a:=Arr(1,2,3,4,5); print(IndexOf(a,5)) end. |
А теперь, выполним с использованием обобщенной функции:
1 2 3 4 5 6 7 8 |
function IndexOf<T>(a:array of T;x:T):integer; begin ... end; begin var a:=Arr(1,2,3,4,5); print(IndexOf(a,5)) end. |
При вызове обобщенной функции компиляция будет в два этапа:
- Автовыведение типа Т, сравнение с реальными цифрами, и т.к. числа целые, то Т определится как integer.
- Берется тело функции и заменяется Т на integer (инстанцирование функции с конкретным типом)
Методы для работы с массивами
Reverse(a)
var a:=Arr(1,2,3,4,5); reverse(a); // [5,4,3,2,1]
Sort(a)
var a:=Arr(2,3,1,4,5); //[1,2,3,4,5] sort(a);
SortByDescending(a);
— по убываниюСледующие методы не меняют сам массив:
a.Min
a.Max
a.Sum
a.Average
— среднее арифметическое
a.IndexOf(x)
и a.LastIndexOf(x)
:begin var a := new integer[10]; a := arrRandomInteger(5,0,5); //[1,3,5,4,5] print(a.IndexOf(3)) // 1 end.
или метод a.Contains(x)
наравне с x in a
:
begin var a := new integer[10]; a := arrRandomInteger(5,0,5); //[1,3,5,4,5] print(a.Contains(3)); // True print(3 in a)// True end.
Некоторые алгоритмы работы с массивами
Сдвиги
Пример: дан массив, надо сдвинуть его элементы:
Стандартное выполнение:
var a:=Arr(1,2,3,4,5,6); var x:=a[0]; for var i:=0 to 4 do a[i]:=a[i+1]; a[5]:=x; print(a)
Если сдвиг вправо:
// … var v := a[0]; for var i:=0 to a.Length-2 do a[i] := a[i+1]; a[a.Length-1] := v;
- либо задействовать еще один массив (𝜭 (n-k) — по времени)
- либо много раз запускать один и тот же алгоритм (𝜭 (1) — по памяти)
Минимальный элемент и его индекс:
Решение 1:
// … var (min, minind) := (a[0], 0); for var i:=1 to a.Length-1 do if a[i]<min then (min, minind) := (a[i], i); Result := (min, minind);
Решение 2:
// … var (min, minind) := (real.MaxValue, 0); for var i:=0 to a.Length-1 do if a[i]<min then (min, minind) := (a[i], i); Result := (min, minind);
Решение 3:
begin var a := new integer[5]; a := arrRandomInteger(5); // [86,37,41,45,76] print(a.Min,a.IndexMin); // 37 1 end.
Циклический сдвиг влево:
// … var v := a[0]; for var i:=0 to a.Length-2 do a[i] := a[i+1]; a[a.Length-1] := v;
Циклический сдвиг вправо:
// … var v := a[a.Length-1]; for var i:=a.Length-1 downto 1 do a[i] := a[i-1]; a[0] := v;
Срезы
Срез массива — это подмножество исходного массива.
- Срезы доступны только на чтение, присваивать им значения нельзя.
- Тип среза такой же, как у массива.
- Срезы работают с массивами, строками и со списками.
var a:=Arr(1,2,3,4,5,6); print(a[1:5]) // [2,3,4,5]
a[1:5]
— 1-й элемент включая, 5-й не включая
println(a[:5]); // [1,2,3,4,5] - с начала до 5-го не включая println(a[1:]); // [2,3,4,5,6] - до конца println(a[::2]); // [1,3,5] - третий параметр - это шаг
a[::-1]
— получим 6 5 4 3 2 1
Т.о. выполнение при помощи срезов выглядит так:
Перестановка:
var a:=Arr(1,2,3,4,5,6); var k:=a.Length-1; // 6 - 1 a:=a[k:]+a[:k]; print(a) // [6,1,2,3,4,5]
Т.е. создан еще массив уже со сдвигом.
Время работы алгоритма n+n
, 𝜭 (n)
Подробнее со срезами можно ознакомиться здесь
Удаление и вставка элементов массива. Списки
Для расширения массива путем вставки какого-либо элемента, необходимо предусмотреть место в памяти. По этой причине для данных случаев проще использовать списки:
Списки — List — это тоже динамический массив, который может «расширяться» и «сужаться» по ходу программы (вставка и удаление элементов).
Подробнее со списками можно ознакомиться здесь
Решение задач
Простые задачи
Пример: Напишите функцию SumArray
, возвращающую сумму элементов заданного динамического массива. Выведите длину и сумму элементов массива
Выполнение:
1 2 3 4 5 6 7 8 |
function SumArray(var a: array of integer): integer:=a.Sum; begin var a:=new integer[10]; a:=arrRandomInteger(10); foreach var x in a do print(x); println('длина массива = ',a.Length,' сумма = ',ArraySum(a)) end. |
Задание 0: Дан массив, вывести его содержимое на экран, разделяя элементы точкой с запятой (процедура PrintArr
). Используйте для разделителя delim
значение по умолчанию равное ‘;
‘
Выполнение:
Дополните код:
1 2 3 4 5 6 7 8 9 10 |
procedure PrintArr( a: array of integer; delim:string:='; '); begin foreach var ... in ... do print(x,delim); end; begin var a:=new integer[10]; a:=arrRandomInteger(10); ... end. |
Пример «Универсальный тип»:
Написать процедуру для печати значений массива любого типа.
В определении универсального типа функции или процедуры параметр типа является заполнителем для определенного типа, который клиент указывает при создании экземпляра универсального типа.
✍ Решение:
procedure printArray<T>(a: array of T); begin for var i:=0 to a.Length-1 do begin print(a[i]); end; println end;
Задание 1: Исправить процедуру PrintArr предыдущего задания 0 так, чтобы за последним элементом символ-разделитель не ставился. Реализовать данную процедуру как процедуру универсального типа.
Задание 2: Заполнить массив (b
) первыми N
(N ≥ 0
) положительными нечётными числами массива a
. Необходимо реализовать два различных решения задачи:
- Функция
MakeOddArrFunc
с одним параметромN
, возвращающая массив. - Процедура
MakeOddArrProc
с двумя параметрами: входным —массив a
и выходным параметром — массивом положительный нечетных чисел
Фрагмент программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
function MakeOddArrFunc (a: array of integer; n:integer):array of integer; begin var b:= new integer[n]; var j:=0; for var i:=0 to ... do if ... then begin ...;...;end; SetLength(...,...); result:=b; end; procedure MakeOddArrProc (a: array of integer;var b: array of integer; n:integer); begin b:= new integer[n]; var j:=0; for var i:=0 to ... do if ... then begin ...;...;end; SetLength(...,...); end; begin var a:=arrRandomInteger(20); var b: array of integer; var n:=readInteger('введите N'); println('исходный массив ',a); println('результат работы с функцией ',MakeOddArrFunc(a,n)); MakeOddArrProc(a,b,n); print('результат работы с процедурой ',b) end. |
Задание 3: Заполнить целочисленный массив первыми N
(N ≥ 0
) числами Фибоначчи. Достаточно одной из реализаций: функции или процедуры
Фрагмент программы:
1 2 3 4 5 6 7 8 9 10 11 12 |
function MakeFibArr (n : integer):array of integer; begin var c:= new integer[n]; c[0]:=...;c[1]:=...; for var i:=2 to n-1 do ...; result:=c; end; begin var n:= readinteger; ...; end. |
Задание 4: Дан целочисленный массив. Написать процедуру EvenMult
с двумя параметрами: входным (параметр по значению) — целочисленным массивом и выходным (параметр по ссылке) — evensCnt
— значением целого типа, которая увеличивает все элементы массива с чётными значениями в два раза и записывает в evensCnt
количество таких элементов
Пример: Описать функцию MakeRandomRealArr
с тремя параметрами: целым числом N
(N ≥ 0
), вещественными параметрами a
и b
(a < b
).
Функция должна возвращать массив (тип которого либо RealArr
либо array of real
) из N
случайных вещественных элементов в диапазоне a..b
.
Продемонстрируйте заполнение и вывод на экран массива
Выполнение:
1 2 3 4 5 6 7 8 9 10 11 |
function MakeRandomRealArr (n : integer;a,b:real):array of real; begin var c:= ArrRandomReal(n,a,b); result:=c; end; begin var n:= readinteger; var a:=readReal; var b:=readReal; println('результат работы с функцией ',MakeRandomRealArr(n,a,b)); end. |
Задание 5: Дан непустой массив вещественных чисел. Найти его наименьший элемент. Выполнить задание с помощью пользовательской функции FindMin
.
Пример: Дан целочисленный массив. Обнулить все его элементы
с нечётными индексами (процедура SetToZeroOddIndexes
).
Условный оператор не использовать
Выполнение:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
procedure SetToZeroOddIndexes(a: array of integer); begin var j:=0; while j<=a.Length-1 do begin a[j]:=0;j+=2; end; println('результирующий массив: ',a); end; begin var a:=arrRandomInteger(10); println('исходный массив: ',a); SetToZeroOddIndexes(a); end. |
Задание 6: Дан целочисленный массив, содержащий не менее трёх элементов. Найти значение первого локального минимума. Выполнить задание с помощью пользовательской функции FirstLocMin
.
Пояснение: локальным минимумом считается тот элемент, который меньше каждого из своих соседей. Считать, что локальный минимум в массиве есть. Первый и последний элемент в качестве локальных минимумов не рассматривать.
Задание 7: Дан массив целых чисел, содержащий не менее трёх элементов. Найти значение и номер последнего локального максимума. Для этого написать процедуру с двумя выходными параметрами (параметры по ссылке)
Задачи на срезы
Задание srez1: Дан массив размера N
. Вывести его элементы в обратном порядке
Пример: Дан массив A
размера N
и целое число K
(1<=K<=N
). Вывести его элементы с порядковыми номерами, кратными K
:
Ak, A2*k, A3*k...
Условный оператор не использовать.
Выполнение:
1 2 3 4 |
var n:=ReadInteger; var a:=ReadArrReal(n); var k:=ReadInteger; a[k-1 : : k].Print; |
Задание srez2: Дан массив A
размера N
(N
– четное число). Вывести его элементы с четными номерами в порядке возрастания номеров:
а2, а4, а6, ... аn
Условный оператор не использовать.
Задание srez3: Дан массив A
размера N
(N
– нечетное число). Вывести его элементы с нечетными номерами в порядке убывания номеров:
аn, аn-2, аn-4, ... а1
Условный оператор не использовать.
Пример: Дан массив A
размера N
. Вывести сначала его элементы с четными номерами (в порядке возрастания номеров), а затем – элементы с нечетными номерами (также в порядке возрастания номеров):
а2, а4, а6,...а1, а3, а5...
Условный оператор не использовать
Выполнение:
1 2 3 4 |
var n:=ReadInteger; var a:=ReadArrReal(n); var srez:=a[1::2]+a[::2]; Print(srez); |
Задание srez4: Дан массив A
размера N
. Вывести сначала его элементы с нечетными номерами (в порядке возрастания номеров), а затем – элементы с четными номерами (в порядке убывания номеров):
а1, а3, а5, ..., а6, а4, а2...
Условный оператор не использовать
Пример: Дан массив размера N
и целые числа K
и L
(1<=K<=L<=N
). Найти среднее арифметическое элементов массива с номерами от K
до L
включительно
Выполнение:
1 2 3 4 5 6 |
var n:=ReadInteger; var a:=ReadArrReal(n); var k:=ReadInteger; var l:=ReadInteger; var srez:=a[k-1:l].Average; print(srez); |
Задание srez5: Дан массив размера N
и целые числа K
и L
(1<=K<=L<=N
). Найти сумму элементов массива кроме элементов с номерами от K
до L
включительно
Пример: Дан массив А
размера N
. Найти минимальный элемент из его элементов с четными номерами: а2, а4, а6,… .
Выполнение:
1 2 3 |
var n:=ReadInteger; var a:=ReadArrReal(n); print(a[1::2].min); |
Задание srez6: Дан массив. Поменять в нем первую половину со второй (считать, что длина массива – четное число). Порядок элементов в половинах не менять.
Например:
[1,2,3,4,5,6,7,8] -> [5,6,7,8,1,2,3,4]
Использование методов
Пример: Дан случайный массив. Найти сумму элементов между первым минимальным и последним максимальным. Сделайте 2 версии – с использованием методов и без их использования. Выдайте время работы каждой версии (для достаточно больших массивов) – можно использовать System.DateTime.Now
Выполнение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
function MyMin(a: array of real): integer; begin var minInd:=0; for var i:=1 to a.Length-1 do begin if a[minInd]>a[i] then minInd:=i; end; result:=minInd; end; function MyMax(a: array of real): integer; begin var maxInd:=0; for var i:=1 to a.Length-1 do begin if a[maxInd]<=a[i] then maxInd:=i; end; result:=maxInd; end; begin //использование методов var n:=readinteger; var a:=readArrreal(n); var t:=System.DateTime.Now; var minInd:=a.IndexMin; var maxInd:=a.LastIndexMax; var srez1:=a[minind+1:maxind].sum; println('Результат 1: ',srez1); var t1:=System.DateTime.Now; println('Время выполнения: ',t1-t); // без использования методов t:=System.DateTime.Now; minind:= MyMin(a); maxind:= MyMax(a); srez1:=a[minind+1:maxind].sum; println('Результат 2: ',srez1); t1:=System.DateTime.Now; println('Время выполнения: ',t1-t); end. |
Задание: Даны 2 упорядоченных массива. Создайте третий – их объединение с сохранением упорядоченности (сортировка – метод sort
). Как и для предыдущей задачи, сделайте хотя бы 2 варианта работы и сравните их.
Фрагмент кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
procedure MySort(c: array of integer); begin // сортировка методом Пузырька for ... for ... ... end; begin var a:=arr(1,3,5,6,12); var b:=arr(2,6,8,12,16); var c:=a+b; //использование методов var t:=System.DateTime.Now; ... ... var t1:=System.DateTime.Now; println('Время выполнения с методом: ',t1-t); t:=System.DateTime.Now; //без использования методов ... ... ... end. |
есть код:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int sumOfOdd(int* array, int n);
int main() {
setlocale(0, "rus");
int n;
printf("введите размер массива: ");
scanf_s("%d", &n);
int* array = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
printf("a[%d] = ", i);
scanf_s("%d", &array[i]);
}
int sum = sumOfOdd(array, n);
printf("сумма нечетных элементов массива: %d", sum);
free(array);
return 0;
}
int sumOfOdd(int* array, int n) {
if (n == 0) {
return 0;
}
else {
int sum = sumOfOdd(array, n - 1);
if (array[n - 1] % 2 != 0) {
return sum += array[n - 1];
}
else {
return sum;
}
}
}
иногда он считает неправильно.
например: размер массива = 4. элементы: a[0] = 1, a[1] = 2, a[2] = 3, a[3] = 4. программа выводит сумму = 4. хотя должно быть 6 (4+2=6).
в чем у меня ошибка?