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

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

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

 

 

Масиви в С++

 

189

 

 

 

 

Таблиця 5.1

 

 

 

Основні властивості компонента StringGrid

 

 

 

 

 

 

 

 

 

 

 

Значення

Нові

 

 

Властивість

Опис

за замов-

значен-

 

 

 

 

чуванням

ня

 

RowCount

Кількість рядків

5

6

 

ColCount

Кількість стовпчиків

5

4

 

Cells

Програмно доступна властивість для звертання

 

 

 

 

 

до комірок таблиці. Приміром, Cells[j][i]

 

 

 

 

 

це комірка в i-тому рядку j-того стовпчика

 

 

 

 

 

(нумерація розпочинається від нуля)

 

 

 

FixedCols

Кількість фіксованих стовпчиків

1

1

 

 

 

(для заголовка рядків)

 

 

 

FixedRows

Кількість фіксованих рядків

1

1

 

 

 

(для заголовка стовпчиків)

 

 

 

Options.

Ознака дозволу на редагування

false

true

 

 

goEditing

змісту комірок

 

 

 

Options.

Ознака дозволу на переміщення

false

true

 

 

goTabs

таблицею за допомогою <Tab>

 

 

 

Options.

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

false

true

 

 

goColSizing

 

 

 

 

 

 

 

 

 

Options.

Ознака дозволу на змінення висоти рядків

false

true

 

 

goRowSizing

 

 

 

 

 

 

 

 

 

 

Приклад створення заголовків таблиці в комірках фіксованих рядка та стовпчика (з індексом 0) під час створення форми.

void __fastcall TForm1::FormCreate(TObject *Sender) { for(int i=1; i<=5; i++)

StringGrid1->Cells[0][i] = IntToStr(i) + "-й рядок"; for(int j=1; j<=3; j++)

StringGrid1->Cells[j][0] = IntToStr(j) + "-й стовпчик";

}

До прикладу введення матриці float В[5][3] з комірок StringGrid1

for(int i=0; i<5; i++) for(int j=0; j<3; j++)

B[i][j]=StrToFloat(StringGrid1->Cells[j+1][i+1]);

можна долучити перевірку на незаповнені комірки:

for(int i=0; i<5; i++) for(int j=0; j<3; j++)

if(StringGrid1->Cells[j+1][i+1] != "") B[i][j]=StrToFloat(StringGrid1->Cells[j+1][i+1]);

else

{ ShowMessage("Заповніть ["+IntToStr(i+1) + ","

+ IntToStr(j+1) + "] елемент");

break;

}

190

Розділ 5

Введення матриці z розміром m n у консолі:

for(int i=0; i<m; i++)

for(int j=0; j<n; j++) cin >> z[i][j];

Для виведення двовимірного масиву a[4][5] у консолі у вигляді матриці елементи слід розташувати у рівні стовпчики. Це можна зробити за допомогою маніпулятора setw(), який задає ширину виведення змінної у cout, (аналогічно до табуляції). Для використання маніпуляторів треба долучити до програми заголовний файл iomanip.h:

#include <iostream.h> #include <iomanip.h> int main()

{int a[4][5];

for(int i=0; i<4; i++)

for(int j=0; j<5; j++) a[i][j]=random(15)-5; for(int i=0; i<4; i++)

{ for(int j=0; j<5; j++)

// Аналогічне виведення рядка

cout<<setw(5)<<a[i][j];// з табуляцією: cout<<"\t"<<a[i][j];

cout<<endl;

//переведення курсора на новий рядок

}

 

cin.get();

 

return 0;

 

}

5.3.3Програмування базових алгоритмів опрацювання двовимірних масивів

Приклад 5.13 Скласти схему алгоритму і розробити проект для введення матриці дійсних чисел розмірністю 3 5 і віднайти максимальний елемент матриці та його індекси.

Розв‟язок. На формі розташовано компоненти StringGrid1, Edit1,

Button1, Button2, Button3, Label1 та Label2, а їхні нові властивості зазначено в таблиці.

Компоненти

Властивості

Нові значення

StringGrid1

RowCount

4

StringGrid1

ColCount

6

 

 

 

StringGrid1

Options.goEditing

true

StringGrid1

Options.goTabs

true

StringGrid1

Name

SG1

 

 

 

Button1

Caption

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

Button2

Caption

Очищення

Button3

Caption

Вихід

Масиви в С++

191

Початок

i 0,2

j 0,4

Ai,j

max=A00, ind_i=0, ind_j=0

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

// Створення форми

void __fastcall TForm1::FormCreate(TObject *Sender) { for(int i=1; i<=3; i++)

SG1->Cells[0][i]=IntToStr(i)+"-й рядок"; for(int j=1; j<=5; j++)

SG1->Cells[j][0] = IntToStr(j)+"-й стовпчик";

}

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

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

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float A[3][5], max; int i, j, ind_i, ind_j; for (i=0; i<3; i++)

for (j=0; j<5; j++)

if (SG1->Cells[j+1][i+1] != "")

A[i][j] = StrToFloat(SG1->Cells[j+1][i+1]); else

{ ShowMessage("Введіть [" + IntToStr(i+1) + "," IntToStr(j+1)

i 0,2

j 0,4

Ні max<Aij

Так

max=Aij, ind_i=i, ind_j=j

max, ind_i+1, ind_j+1

Кінець

+

+ "] елемент");

break; }

max = A[0][0]; ind_i = 0; ind_j = 0; for (i=0; i<3; i++)

for (j=0; j<5; j++)

if (max < A[i][j]) { max = A[i][j]; ind_i = i; ind_j = j; } Edit1->Text = FormatFloat("0.00",max) + " " + IntToStr(ind_i+1)

+ "-й рядок і " + IntToStr(ind_j + 1) + "-й стовпчик";

}

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

void __fastcall TForm1::Button2Click(TObject *Sender) // Очищення

{for (int i=0; i<3; i++)

for (int j=0; j<5; j++) SG1->Cells[j+1][i+1] = "";

Edit1->Clear();

}

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

void __fastcall TForm1::Button3Click(TObject *Sender) // Вихід { Close(); }

192 Розділ 5

Приклад 5.14 Скласти схему алгоритму і розробити проект для введення матриці цілих чисел розмірністю 5 7 та обчислення елементів вектора сум від‟ємних елементів стовпчиків матриці.

Розв‟язок. Для заповнення вихідної матриці слід передбачити можливість заповнення комірок випадковими числами. Користувач може скористатись такою можливістю чи то заповнити комірки самостійно. Випадкові числа формуємо за допомогою функції генератора випадкових чисел random(N), яка міститься в бібліотеці <stdlib.h>. Функція random(N) генерує випадкове ціле додатне число в діапазоні від 0 до N – 1. Щоб формувались і від‟ємні числа, використаємо конструкцію (50 – random(100)). Функція randomize() ініціалізує генератор випадкових чисел (див. підрозд. 3.7).

Нові властивості компонента StringGrid1, розташованого на формі, наведено нижче в таблиці.

 

 

 

 

 

Початок

Компоненти

Властивості

Нові значення

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StringGrid1

ColCount

7

 

 

 

 

 

 

 

 

 

 

 

i 0,4

StringGrid1

RowCount

5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StringGrid1

Options.goEditing

true

 

 

 

 

 

 

 

 

 

 

 

j 0,6

StringGrid1

Options.goTabs

true

 

 

Введення

StringGrid1

FixedCols

0

 

 

 

 

 

 

Ai,j

 

 

 

 

 

 

 

StringGrid1

FixedRows

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StringGrid1

DefaultColWidth

40

 

 

 

 

 

 

 

 

 

StringGrid1

Name

SG1

 

 

 

 

 

 

 

 

 

 

 

j 0,6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Хj = 0

 

 

 

 

 

 

 

 

 

 

 

 

 

i 0,4

 

 

 

Ні

Aij<0

 

 

 

 

 

Так

Xj= Xj +Aij

Виведення

Xj

Кінець

Масив A та змінні i, j оголошено перед усіма функціями глобально, оскільки посилання до цих об‟єктів є в різних функціях.

Тексти програм для усіх кнопок:

int A[5][7], i, j;

void __fastcall TForm1::Button1Click(TObject *Sender) { randomize();// Заповнити випадковими числами

Масиви в С++

193

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

for (j=0; j<7; j++) SG1->Cells[j][i]=IntToStr(50-random(100));

}

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

void __fastcall TForm1::Button2Click(TObject *Sender)//Розв‟язок

{int X[7]; Memo1->Clear(); for (i=0; i<5; i++)

for (j=0; j<7; j++) A[i][j] = StrToInt(SG1->Cells[j][i]); for (j=0; j<7; j++)

{X[j] = 0;

for(i=0; i<5; i++) if(A[i][j] < 0) X[j] += A[i][j];

Memo1->Lines->Add(IntToStr(X[j]));

} }

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

void __fastcall TForm1::Button3Click(TObject *Sender)//Очищення

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

for (j=0; j<7; j++) SG1->Cells[j][i] = "";

}

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

void __fastcall TForm1::Button4Click(TObject *Sender) { Close(); // Вихід – закриття форми

}

Приклад 5.15 З елементів матриці розмірністю 4 7 дійсних чисел обчислити вектор добутків ненульових елементів парних (2, 4 та 6) стовпчиків матриці.

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

Компонент BitBtn, зображений на формі, є різновидом стандартної кнопки Button, але з можливістю виведення на кнопку, окрім надпису, піктографічних зображень за допомогою властивості Kind чи Glyph.

Початок

i 0,3

j 0,6

Введення

Сi,j

k = 0

j 0,6

Ні Парний стовпчик? Так

pk = 1

i 0,3

Ні Сij 0

Так

pk= pk*Cij

Виведення pk

k=k+1

Кінець

194

Розділ 5

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

void __fastcall TForm1::BitBtn1Click(TObject *Sender) { int i, j, k=0; float C[4][7], p[3];

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

for (j=0; j<7; j++) C[i][j]=StrToFloat(SG1->Cells[j][i]); for (j=0; j<7; j++)

if ((j+1)%2 == 0) //Стовпчик є парний?

{ p[k]=1;

 

 

 

 

 

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

 

 

 

 

 

if (C[i][j]!=0) p[k]*=C[i][j];

 

 

 

 

 

SG2->Cells[k][0]=FormatFloat("0.00", p[k]);

 

 

 

 

 

k++;

 

 

 

 

 

} }

 

 

 

 

 

Приклад 5.16 Увести матрицю розмірністю 4 4 дій-

Початок

сних чисел і замінити елементи головної діагоналі на мі-

 

 

 

 

 

німальні елементи відповідних рядків.

i 0,3

 

 

 

 

 

j 0,3

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

void __fastcall TForm1::BitBtn1Click(TObject *Sender)

{ int

i, j,

k;

float B[4][4], X[3], min;

for

(i=0;

i<4;

i++)

for (j=0; j<4; j++) B[i][j]=StrToFloat(SG1->Cells[j][i]);

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

{ min=B[i][0]; // Запам‟ятати перший елемент рядка k=0; // та його індекс як мінімальний.

for (j=0; j<4; j++)//Рухаючись по стовпчиках if(B[i][j]<min)//перевірити: якщо елемент є менший

{ min=B[i][j];//за min, запам‟ятати його значення

k=j;

//та індекс.

}

 

// Замінити мінімальний елемент рядка на елемент B[i][k]=B[i][i];// діагоналі, а елемент діагоналі – B[i][i]=min; // на мінімальний елемент.

Введення

Вij

i 0,3

min= Вi0, k=0

j 0,3

Ні min>Bij

Так

min= Вij, k=j

Bikii, Вii=min

i 0,3

j 0,3

Виведення

Вij

}

Кінець

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

 

for (j=0; j<4; j++) SG2->Cells[j][i]=FormatFloat("0.00", B[i][j]);

}

i3 j2
Приклад 5.18

Масиви в С++

195

Приклад 5.17 З елементів матриці розмірністю 7 7 цілих чисел обчислити вектор скалярних добутків елементів першого рядка на стовпчики матриці.

Розв‟язок. Нагадаємо, що скалярний добуток – це сума добутків відповідних елементів. У даному разі:

W[0] = p[0][0]*p[0][0] + p[0][1]*p[1][0] + p[0][2]*p[2][0] + p[0][3]*p[3][0] + ...

W[1] = p[0][0]*p[0][1] + p[0][1]*p[1][1] + p[0][2]*p[2][1] + p[0][3]*p[3][1] + ...

W[2] = p[0][0]*p[0][2] + p[0][1]*p[1][2] + p[0][2]*p[2][2] + p[0][3]*p[3][2] + ...

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

void __fastcall TForm1::BitBtn1Click

(TObject *Sender)

{int i, j, p[7][7], W[7]; for (i=0; i<7; i++)

for (j=0; j<7; j++)

p[i][j] = StrToInt(SG1->Cells[j][i]); for (j=0; j<7; j++)

{W[j]=0;

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

W[j] += p[0][i] * p[i][j];

SG2->Cells[j][0]=IntToStr(W[j]);

}

}

Початок

i 0,6

j 0,6

Введення

pij

j 0,6

Wj = 0

i 0,6

Wj +=p0i* pij

Виведення

Wj

Кінець

Обчислити елементи матриці розмірністю 5 3 за формулою

aij

 

 

 

 

. Обчислити кількість елементів цієї матриці, які є менше за 2.

 

 

 

 

ln i j 1

 

 

196

Розділ 5

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

#include <math.h>

void __fastcall TForm1::Button1Click(TObject *Sender) { double a[5][3]; int i, j, k=0;

for (i=0; i<5; i++) for (j=0; j<3; j++)

{// Обчислення елементів матриці if (i==0 && j==0) a[i][j]=0;

else a[i][j]=sqrt(fabs(pow(i,3)-j*j))/

log(i+j+1); SG1->Cells[j][i]=FormatFloat("0.0000",

a[i][j]); // Виведення матриці // Обчислення кількості елементів <2

if (a[i][j]<2) k++;

} Edit1->Text=IntToStr(k);

}

Приклад 5.19 Увести дві цілочисельні матриці 3 3 і обчислити добуток цих матриць.

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

 

 

 

 

 

 

 

 

 

 

1

2

1

 

 

3

0

1

 

 

3 4

0

 

1

1

0

 

 

 

 

 

 

 

 

 

 

 

1

0

1

 

2

5

7

 

 

1

3

2 ( 1) 1 2

1

0

2 1 1 5

11 2

0

1 7

 

3

7

 

 

 

 

 

 

 

 

 

 

 

 

3 3

4 ( 1) 0 2

3 0

4 1 0 5

3 1 4

0

0 7

 

5

4

 

 

3 0 ( 1) 1 2

1

0 0 1 1 5

 

 

 

 

 

5

1

11 0 0 1 7

1

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

void __fastcall TForm1::Button1Click(TObject *Sender)

{const int n=3;

int i, j, k, a[n][n], b[n][n], c[n][n]; for (i=0; i<n; i++)

for (j=0; j<n; j++)

{ a[i][j]=StrToInt(StringGrid1->Cells[j][i]); // Введення

b[i][j]=StrToInt(StringGrid2->Cells[j][i]); // матриць

}

8

36

Масиви в С++

197

//Обчислення матриці-результату for (i=0;i<n;i++)

for (j=0;j<n;j++) { c[i][j]=0;

for (k=0;k<n;k++) c[i][j]+=a[i][k]*b[k][j];

}

//Виведення результату for (i=0;i<n;i++)

for (j=0;j<n;j++) StringGrid3->Cells[j][i]=IntToStr(c[i][j]);

}

Приклад 5.20 Скласти схему алгоритму і розробити програму для введення матриці цілих чисел розмірністю 5 5 та обчислення суми елементів в секторі під головною діагоналлю. Замінити елементи побічної діагоналі на цю суму.

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

Початок

s = 0

i 0,4

j 0,4

aij

 

i>j

Ні

 

Так

 

 

 

s = s + aij

 

i 0,4

ai,4-i = s

i 0,4

j 0,4

aij

Кінець

void __fastcall TForm1::Button1Click(TObject *Sender)

{int i, j, a[5][5], s=0; for (i=0; i<5; i++) for (j=0; j<5; j++)

{a[i][j]=StrToInt(StringGrid1->Cells[j][i]);

if (i>j) s += a[i][j];

}

for (i=0; i<5; i++) a[i][4-i]=s;

198

Розділ 5

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

for (j=0; j<5; j++) StringGrid2->Cells[j][i]=IntToStr(a[i][j]); Edit1->Text=IntToStr(s);

}

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

Як буде зазначено у підрозд. 8.1, при передаванні до функції двовимірних масивів обидві розмірності зазначають чи то як константи, якщо їхнє значення відомо (див. приклади 5.21, 5.23), чи передають як окремі параметри, якщо вони не є відомі на етапі компіляції (див. приклад 8.10).

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

Розглянемо кілька варіантів передавання матриці цілих чисел А[3][4] у функцію print(), яка організовує виведення цієї матриці на екран у консолі.

1) Якщо розміри обох індексів є відомі, то проблем немає: void print(int А[3][4])

{for (int i=0; i<3; i++)

{ for (int j=0; j<4; j++) cout << ' ' << А[i][j];

cout << '\n';

} }

Матриця і тут передається як вказівник, а розмірності наведено просто для повноти опису. Виклик такої функції може бути таким:

int х[3][4]; print(х);

2)Перша розмірність для обчислення адреси елемента є неважлива, тому

їїможна передавати як параметр:

void print(int А[][4], int m)

{for (int i=0; i<m; i++)

{ for (int j=0; j<4; j++) cout << ' ' << А[i][j];

cout << '\n';

} }

Виклик цієї функції:

int х[3][4]; print(х,3);

3) Самий складний випадок – коли треба передавати обидві розмірності. Наведений нижче код функції є поширеною помилкою:

void print(int А[][], int m, int n) // Помилка!

{for (int i=0; i<m; i++)

{for (int j=0; j<n; j++) cout << ' ' << А[i][j]; cout << '\n';

}}

По-перше, опис параметра А[][] є неприпустимий, оскільки для обчислення адреси елемента двовимірного масиву слід знати другу розмірність. У такому разі найбільш поширеним і грамотним є застосування динамічних маси-

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