Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C _Учебник_МОНУ

.pdf
Скачиваний:
199
Добавлен:
12.05.2015
Размер:
11.12 Mб
Скачать

Масиви в С++

169

Приклад 5.1 Розробити схему алгоритму та проект програми для введення одновимірного масиву з 8-ми дійсних чисел та обчислення суми усіх елементів масиву.

Текст програми:

// Сума

void __fastcall TForm1::Button1Click(TObject *Sender)

{float A[8], sum = 0; for(int i = 0; i < 8; i++)

{A[i]=StrToFloat(Memo1->Lines->Strings[i]); sum += A[i];

}

Edit1->Text = FormatFloat("0.000", sum);

}

//--------------------------------------------

//Очищення

void __fastcall TForm1::Button3Click(TObject *Sender)

{Memo1->Clear(); Edit1->Clear();

}

//--------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender) //Вихід

{ Close();

}

Початок

sum=0

i 0,7

Введення

A[i]

sum=sum+A[i]

Виведення sum

Кінець

Приклад 5.2 Скласти консольну програму, яка вводить масив з 12-ти цілих чисел і обчислює кількість непарних елементів з проміжку (–10, 30).

Текст програми:

#include <conio.h> #include <iostream.h>

//--------------------------------------------------------

int main(int argc, char* argv[])

{int a[12],i,k=0; for(i=0; i<12; i++) { cin >> a[i];

if((a[i]%2 != 0) && (a[i] > -10) && (a[i] < 30)) k++;

}

cout << "k=" << a[i] << endl; getch(); return 0;

}

Результати виконання програми:

170

Розділ 5

Приклад 5.3 Скласти схему алгоритму і проект програми для обчислення елементів одновимірного масиву з 15-ти елементів за формулою Ai lg(i) tg(2i ) , де і = 1, 2, ..., 15, та їхнього виведення на форму, а також визначення мінімального елемента та його порядкового номера.

Розв‟язок. Схеми алгоритмів програми та приклад вигляду форми з результатами роботи наведено нижче.

Початок

min=A[0], ind=0

Початок

i 1,14

i 0,14

Ai lg(i 1) tg(2i 1)

Виведення

A[i]

Кінець

Блок-схема для кнопки “Обчислення вектора”

НіA[ind]>A[i]

Так

ind=i

A[ind], ind+1

Кінець

Блок-схема для кнопки “Мінімальний елемент”

Уцій програмі змінні A[15] та i оголошено глобально перед функціями для подій onClick. Це зроблено для того, щоб значення елементів масиву, набуті в одній функції, були доступними для опрацювання і в другій функції. Але слід звернути увагу на те, що оголошувати без нагальної потреби глобальні змінні вважається за неоптимальний стиль програмування.

Розглянемо алгоритм пошуку мінімального елемента масиву. Припустімо, що на столі лежить купа резюме, кожне з яких, окрім іншої інформації про кандидата на посаду, містить і його рік народження. Треба віднайти найстаршого з усіх кандидатів, тобто резюме з найменшим роком народження.

Беремо до рук перше резюме. Оскільки невідомо, що міститься у решті резюме, відкладаємо перше і вважаємо його власника за найстаршого.

Одне за одним переглядаємо решту резюме. Якщо натрапляємо на резюме, в якому подано рік менше за рік у відкладеному резюме, то відкладаємо його (попереднє нас вже не цікавить). Коли всі резюме переглянуто, виявляється, що відкладене резюме належить кандидатові з найменшим роком народження.

Увигляді словесного алгоритму пошук мінімального елемента масиву і його індексу можна записати в такий спосіб:

1) вважаємо перше число за найменше. Для цього присвоюємо перший

елемент масиву A[0] у змінну min, а змінній ind – значення 0 (тобто індекс першого елемента масиву);

Масиви в С++

171

2) у циклі переглядаємо всі елементи. Якщо зустрічаємо число, яке є менше за min, запам‟ятовуємо це число у min, а його індекс – в ind.

Коли цикл завершиться, у змінній min буде зберігатися найменший елемент масиву, а його індекс – у змінній ind. Оскільки нумерація індексів масиву розпочинається з 0, а не з 1, як у повсякденному житті, виводиться значення індексу, збільшене на 1.

Текст програми:

#include <math.h> double A[15]; int i;

//------------------------------------------------------

// Обчислення елементів вектора

void__fastcall TForm1:: Button1Click(TObject *Sender)

{Memo1->Clear(); for(i=0; i<15; i++)

{A[i]=log10(i+1)+tan(pow(2.,i+1)); Memo1->Lines->Add(FormatFloat("0.000", A[i]));

}

}

//---------------------------------

// Мінімальний елемент

void __fastcall TForm1::Button2Click(TObject *Sender)

{double min=A[0]; int ind=0; for(i=1; i<15; i++)

if(min > A[i]) { min=A[i]; ind=i; } Edit1->Text=FormatFloat("0.000", A[ind]) + " індекс - " +

IntToStr(ind+1);

}

Якщо треба віднайти лише значення мінімального елемента масиву, то програма для Button2Click матиме спрощений вигляд:

void __fastcall TForm1::Button2Click(TObject *Sender)

{double min=A[0]; for(i=1; i<15; i++)

if(min > A[i]) min=A[i]; Edit1->Text=FormatFloat("0.000", min);

}

Можна відшукати лише індекс мінімального елемента, а потім за його допомогою визначити мінімальний елемент. У цьому способі мінімальним буде елемент з віднайденим індексом: А[ind]. Цей спосіб реалізовано у такій програмі.

void __fastcall TForm1::Button2Click(TObject *Sender)

{int ind=0; for(i=1; i<15; i++)

if(A[ind] > A[i]) ind=i; Edit1->Text=FormatFloat("0.000", A[ind]) + " індекс - " +

IntToStr(ind+1);

}

172

Розділ 5

Приклад 5.4 Розробити консольний додаток для заповнення масиву з 20-ти

елементів за формулою

a 1 i

sin i2

 

 

та визначити найбільший від‟ємний

sin i

1

i

 

 

 

елемент масиву.

Розв‟язок. Оскільки невідомо, чи буде перший елемент масиву від‟ємним, не можна присвоїти початкове значення змінній max. Присвоїмо їй значення 0. Вважатимемо, що, якщо зустріли від‟ємний елемент і змінна max дорівнює 0, то це буде перший від‟ємний елемент і його слід присвоїти змінній max у якості початкового значення. Якщо змінна max вже набула певного значення, порівнюємо її з новим від‟ємним елементом, і якщо новий елемент перевищує max, записуємо його до max.

Текст програми

#include <conio.h> #include <math.h> #include <stdio.h>

int main(int argc, char* argv[]) {double a[20], max=0; int i; for(i=0; i<20; i++)

{ a[i]=pow(-1,i)*sin(i*i)/sin(i+1); printf("%5.2f ",a[i]);

}

for(i=0; i<20; i++)

if(a[i]<0) //Якщо віднайшли від‟ємний елемент і,

if(max==0 ||

max<0 && max<a[i])//якщо він є перший чи більший за max,

max=a[i];

//присвоюємо його max

printf("\n max = %5.2f",max); getch(); return 0;

}

Результати виконання програми:

k =k+1
р =р*А[i]

Масиви в С++

173

Приклад 5.5 Розробити проект програми для введення одновимірного масиву до 15-ти елементів та обчислення:

добутку ненульових елементів;

кількості від‟ємних елементів;

максимального елемента з переставлянням його з першим елементом

вектора.

Розв‟язок. Зверніть увагу, що чисел може бути введено менш за 15, але оголосити масив слід з максимально можливою кількістю елементів (15). У про-

грамі при опрацюванні масиву індекс у циклі

 

 

 

 

 

змінюється від 0 до n, де n – кількість реально

 

Початок

 

 

введених чисел. Якщо введено менше за 15 чи-

 

 

 

 

 

 

 

 

 

 

Введення n

 

сел, зчитуються всі числа, які було введено.

 

 

 

 

 

 

Якщо чисел є більше за 15, зайвими числами

 

 

 

Так

 

 

n>15

n=15

нехтують.

Ні

 

 

 

 

 

 

 

 

 

 

 

Текст програми:

void __fastcall TForm1::

BitBtn1Click (TObject *Sender) {double A[15]; int i, n;

n = StrToInt(Memo1->Lines->Count); if (n>15) n=15;

for (i=0; i<n; i++) A[i]=StrToFloat(Memo1->Lines->Strings[i]); int k=0, ind=0;

double p=1, max=A[0]; for (i=0; i<n; i++)

{//Кількість від‟ємних елементів if (A[i] < 0) k++;

//Добуток ненульових елементів if (A[i] != 0) p *= A[i];

//Максимальний елемент та його індекс

if (A[i] > max)

{ max=A[i]; ind=i;

}

}

//Поміняти місцями максимальний елемент

//з першим елементом вектора

A[ind]=A[0]; A[0]=max; Edit1->Text=FloatToStr(p); Edit2->Text=IntToStr(k); Edit3->Text=FormatFloat("0.000", max)+

" індекс "+IntToStr(ind);

Memo2->Clear(); for(i=0; i<n; i++)

Memo2->Lines->Add(A[i]);

}

i 0, n 1

Введення

А[i]

k=0, Р=1, mах=А[0], ind=0

i 0,n 1

Так

А[i]<0

Ні Так

А[i] ≠ 0

Ні Ні

mах<А[i]

Так

mах=А[i], ind=i

А[ind]=v[0] А[0]=mах

Виведення p, k, max, ind

i 0, n 1

Виведення

А[i]

Кінець

174

Розділ 5

Приклад 5.6 Увести масив з 10-ти цілих чисел. Створити новий масив, елементи якого обчислити, поділивши кожен з елементів початкового масиву на суму його елементів з непарними індексами.

Розв‟язок. Щоб створити новий масив, спочатку обчислимо суму елементів з непарними індексами. Після цього послідовно поділимо всі елементи масиву на обчислену суму і присвоїмо результат відповідному елементові нового масиву. Після ділення елементи нового масиву матимуть тип float.

Будемо вводити початковий масив і виводити новий масив у компонент StringGrid, який міститься на панелі Additional (докладніше про цей компонент див. у п. 5.3). Цей компонент зазвичай використовується для таблиць. Він складається з комірок, кожна з яких є розміщена на перетині рядка і стовпчика і має два індекси. У цьому прикладі компоненти StringGrid матимуть імена (властивість Name) SG1 та SG2 і міститимуть по одному рядку (властивість RowCount=1) і 10 стовпчиків (властивість ColCount=10). Щоби надати користувачу можливість вводити числа у SG1, встановимо значення властивості Options->goEditing в true. Також встановимо для обох компонентів значення властивостей FixedCols=0 та FixedRows=0, тобто таблиці не матимуть заголовків рядків і стовпчиків:

 

Масиви в С++

175

Текст програми:

 

 

void __fastcall TForm1::Button1Click(TObject *Sender)

 

{ const int N=10;

// Константа N для кількості елементів масиву

int a[N], i, sum=0;

// a – початковий масив

 

float b[N];

// b – новий масив

 

for(i=0; i<N; i++)

// Введення елементів початкового масиву

 

a[i]=StrToInt(SG1->Cells[i][0]);//із StringGrid (стовпчик i, рядок 0)

 

for(i=0; i<N; i+=2)

// Обчислення суми елементів з непарними індексами

 

sum+=a[i];

 

 

Edit1->Text=IntToStr(sum);

 

for(i=0; i<N; i++)

 

 

{ b[i]=1.*a[i]/sum;

// Ділимо a[i] на sum і присвоюємо результат b[i]

SG2->Cells[i][0]=FormatFloat("0.00", b[i]);

}

}

Приклад 5.7 Увести масив до 10-ти дійсних чисел і створити новий масив з його ненульових елементів.

Розв‟язок. Оскільки реальна кількість ненульових елементів початкового масиву є невідома, оголошуємо новий масив з максимально можливою кількістю елементів, тобто 10. У попередньому прикладі індекси елементів нового масиву при створенні збігалися з індексами відповідних елементів початкового масиву. У цьому прикладі нульові елементи пропускаються і не записуються до нового масиву, тому індекси початкового й результуючого масивів не збігатимуться:

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender) { const int N=10;

floata[N],b[N]={0};//Cпочатку елементи нового масиву мають нульові значення

int i,j=0;

// Кількість елементів нового масиву дорівнює 0

for(i=0; i<N; i++)

 

{ a[i]=StrToInt(SG1->Cells[i][0]);

if (a[i]!=0)

// Якщо елемент a[i] є ненульовий,

{ b[j]=a[i]; j++; // записати його до b[j] та збільшити j

}

}

SG2->ColCount=j; // Тепер вже є відома реальна кількість комірок SG2 for(i=0; i<j; i++) SG2->Cells[i][0]=FormatFloat("0.0", b[i]);

}

176

Розділ 5

5.2.4 Опрацювання одновимірних масивів у функціях

Більш докладно правила організації функцій розглядаються у розд. 8. Тут лише зауважимо, що функцією є окремо організований поіменований блок команд програми, в якому розв‟язується невелика і специфічна частина загального завдання. Організація програмного проекту з розподілом великого складного завдання на набір більш простих задач і завдань, розв‟язування яких виокремлено в логічні блоки – функції, дозволяє спростити читаність програми, її розуміння. Окрім того, застосовування функцій вивільняє програмний код від повторюваних блоків команд, які багаторазово реалізовують один і той самий алгоритм для різних даних. В таких випадках створюється функція з певним набором операторів, а виклик цієї функції здійснюють в основній програмі потрібну кількість разів для різних вхідних параметрів.

Якщо результатом виконання функції є одне значення, яке повертається оператором return, то воно підставляється у точку виклику функції. Тому тип функції і є типом результату. Коли функція має повертати масив, типом функції слід оголосити вказівник на тип елемента масиву. Наприклад, оголошена в такий спосіб функція може повертати масив цілих чисел:

int * function ();

Якщо масив використовують у якості параметра функції, то треба зазначити адресу початку масиву. Зробити це можна одним з трьох способів:

float fun (int a[10]); float fun (int a[]); float fun (int *a);

За першим способом явно зазначено кількість елементів масиву. У другій синтаксичній формі константний вираз у квадратних дужках є відсутній. Така форма є припустима, коли кількість елементів масиву є глобальною змінною чи константою. За третього способу передається вказівник як посилання на масив, явно визначений в основній програмі. Більш докладно роботу з вказівниками буде розглянуто в розд. 6.

Хоча наведені записи мають різний синтаксис, насправді вони є рівнозначними, оскільки авторами стандарту C для більшої ясності було вирішено, що масив оголошений як параметр функції є вказівником. При цьому число у квадратних дужках ігнорується. А тому доцільно передавати розмірність масиву окремим параметром:

float fun (int a[], int n); float fun (int *a, int n);

Якщо функцію організовано для опрацювання елементів масиву, наприклад для сортування елементів, у такому разі можна оголосити функцію з типом результату void (нема величини, що повертається). Оскільки сам масив передається у функцію за посиланням, то будь-які змінювання значень елементів масиву у функції буде видно і в основній програмі, яка викликає цю функцію (див. нижче приклади 5.9 – 5.12).

Масиви в С++

177

Приклад 5.8 Ввести масив до 11-ти дійсних чисел і з‟ясувати, чи є він упорядкованим за зростанням.

Розв‟язок 1. У циклі порівнюватимемо кожну пару сусідніх елементів. Якщо принаймні для однієї пари виконається умова (a[i]>a[i+1]) (наступний елемент є менший за попередній), це означатиме, що масив не є впорядкований, і в такому разі слід вивести про це повідомлення і перервати виконування функції Button1Click. Якщо цикл завершиться, а виконування функції перервано не було, це означатиме, що масив є впорядкований, про що виведеться відповідне повідомлення.

void __fastcall TForm1::Button1Click(TObject *Sender)

{double a[11];

int i, N=Memo1->Lines->Count; if (N>11) N=11;

for(i=0; i<N; i++)a[i]=StrToFloat(Memo1->Lines->Strings[i]); for(i=0; i<N-1; i++)

if(a[i] > a[i+1])

{ShowMessage("Не є впорядкований за зростанням"); return;} ShowMessage("Впорядкований за зростанням");

}

Розв‟язок 2. Напишемо аналогічну програму зі створенням функції sorted(), яка повертає значення true, якщо масив є впорядкований за зростанням, і false – якщо ні. У циклі порівнюємо кожну пару елементів, і, якщо зустрінеться пара, для якої наступний елемент є менше за попередній, перериваємо виконування функції й повертаємо false. Якщо цикл завершено і виконування функції перервано не було, повертаємо true. Докладніше про специфіку організації функцій див. у розд. 8.

bool sorted(double a[], int n) { for (int i=0; i<n-1; i++)

if (a[i] > a[i+1]) return false; return true;

}

178

Розділ 5

void __fastcall TForm1::Button1Click(TObject *Sender)

{double a[11];

int i, N=Memo1->Lines->Count; if (N>11) N=11;

for (i=0; i<N; i++) a[i]=StrToFloat(Memo1->Lines->Strings[i]);

if (sorted(a, N)) ShowMessage("Впорядкований за зростанням");

else ShowMessage("Не є впорядкований за зростанням");

}

Приклад 5.9 Розробити схему алгоритму і проект програми для введення до 15-ти дійсних чисел із компонента Меmо і впорядкувати їх за зростанням.

Розв‟язок. Упорядкування масивів за будь-якою ознакою називається також сортуванням. Існують різні методи сортування. Вони розрізняються переважно швидкістю отримання результату. Розглянемо лише три з них.

П е р ш и й с п о с і б

В наведеній нижче функції sort() запропоновано найбільш поширений метод “бульбашки” (bublesort). Алгоритм сортування полягає у переставлянні двох сусідніх порівнюваних елементів масиву, якщо вони йдуть у неправильному порядку.

Перш ніж розглянемо повний текст програм, звернімо увагу на певні її фрагменти.

Для послідовного порівняння сусідніх елементів масиву a[i] та a[i+1] слід організувати цикл. При цьому останнє значення параметра циклу і у циклі for має бути на один менше за кількість усіх елементів, щоб на останній ітерації можна було порівнювати передостанній елемент з останнім.

Для того щоб переставити місцями два елементи, слід застосувати тимчасову змінну tmp:

tmp = a[i];

// Запам‟ятати значення a[i]

a[i] = a[i+1];

// і в a[i] записати a[i+1],

a[i+1] = a[i];

// а в a[i+1] записати те, що спочатку було в a[i]

Щоб краще зрозуміти необхідність тимчасової змінної, слід уявити собі склянку соку і чашку кави і спробувати перелити сік у чашку, а каву – у склянку. Це неможливо буде зробити без додаткового посуду, до якого спочатку треба перелити вміст, наприклад, склянки.

Якщо в умові порівняння елементів записати знак “>”, то елементи сортуватимуться за зростанням, а якщо знак “<” – за спаданням.

Цикл для одноразового проходження по n елементах масиву і за потреби переставляння елементів має вигляд

for (i=0; i<n-1; i++) if (a[i] > a[i+1]) { tmp = a[i];

a[i] = a[i+1]; a[i+1] = tmp;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]