Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основи програмування Паскаль.docx
Скачиваний:
51
Добавлен:
12.05.2015
Размер:
511.7 Кб
Скачать

15. Розв'язок типових завдань на масиви

У главі 14 ми підкреслювали, що типові алгоритми, вивчені в темі "Цикли", повною мірою застосовні й до масивів. Займаючи певний обсяг оперативної пам'яті, одного разу отримані елементи масиву залишаються доступними весь сеанс роботи програми й не вимагають повторного обчислення або читання з файлу. Це породжує коло додатків, пов'язаних з типовою обробкою наборів даних – обчислення математичних і статистичних характеристик векторів, об'єднання масивів або пошук потрібних значень у них і т.д.  Інші цікаві приклади, такі як підрахунок частоти зустрічальності елементів у масиві, завдання сортування(упорядкування) даних, будуть розглянуто в главі 16.

Пр.Знайти суму, скалярний добуток і довжину двох векторів довільно заданої розмірності. Розмірність не може перевищувати значення 100.

Граничну розмірність масивів задамо константою Size=100. Розмірність реальних векторівaіb, з якими працює програма, не обов'язково настільки велика, позначимо їїnі подбаємо про те, щоб при введенні значенняnдотримувалося співвідношення2≤n≤size. Для різноманітності введемо вектор a із клавіатури, а вектор b згенеруємо з випадкових чисел, що належать діапазону від0до10. Для цього досить помножити на10значення, що вертається стандартною функцієюrandom, якщо вона викликана без параметрів:

b[i]:=random*10;

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

Як відомо з математики, сума векторів aіbшукається поэлементно за правиломci=ai+bi, скалярний добуток може бути обчислене по формулі, а довжина вектораaзnелементів шукається по формулі.

const Size=100;

var a,b,c:array [1..Size] of real;

n,i:integer;

la,lb,s:real;

begin

repeat

writeln;

write ('Уведіть розмірність векторів A і B, ',

'значення від 2 до ',Size,':');

{$I-}readln (n);{$I+}

if (Ioresult<>0) or (n<2) or (n>Size) then

writeln ('Невірне введення, будь ласка, повторите')

else break;

until false;

writeln ('Уведіть вектор A з ',n,' елем.:');

for i:=1 to n do begin

repeat

write ('A[',i,']=');

{$I-}readln (a[i]);{$I+}

if Ioresult=0 then break;

until false;

end;

writeln ('Генерується вектор B з ',n,' елем.:');

randomize;

for i:=1 to n do begin

b[i]:=random*10;

write (b[i]:8:2);

end;

la:=0;

lb:=0;

s:=0;

writeln;

writeln ('Вектор C=A+B:');

for i:=1 to n do begin

c[i]:=a[i]+b[i];

write (c[i]:8:2);

la:=la+sqr(a[i]);

lb:=lb+sqr(b[i]);

s:=s+a[i]*b[i];

end;

writeln;

writeln ('Довжина вектора A: ',sqrt(la):8:2);

writeln ('Довжина вектора B: ',sqrt(lb):8:2);

writeln (' Скалярний добуток:',s:8:2);

reset (input); readln;

end.

Думаю, при аналізі лістингу Ви звернули увагу ще на одну особливість програми — на кожному кроці циклу введення вектора aдодатково виконується циклrepeat...until, призначений для контролю правильності введення елементів масиву. Докладніше такі конструкції, називанікратними циклами, будуть вивчено в главі 16.

Пр.Задана вибірка з n випадкових чисел. Для n=100 визначити математичне очікування mx і дисперсію Dx вибірки по формулах:,

Дві підраховувані величини – найпоширеніші статистичні характеристики набору випадкових даних. Фактично, математичні очікування характеризує арифметичне середнєданих вибірки, а дисперсія —середньоквадратичне відхиленняданих від середнього значення. Для зберігання даних використовуємо масив X з 100 елементів, самі дані згенеруємо з випадкових чисел, що перебувають у діапазоні від -1 до 1 включно. Оскільки алгоритм нагромадження суми припускає послідовне й однократне використання кожного елемента масиву, у циклі генерації елементів масиву можуть бути підраховані значенняй, які потім дозволять знайти mx і Dx.

const n=100;

var x:array [1..100] of real;

s,d:real;

i:integer;

begin

writeln;

writeln ('Масив X[100]:');

randomize;

s:=0; d:=0;

for i:=1 to n do begin

x[i]:=random*2-1;

write (x[i]:8:3);

s:=s+x[i];

d:=d+sqr(x[i]);

end;

s:=s/n; {тепер в s - мат. очікування,}

d:=d/(n-1)-sqr(s)/(n*(n-1)); {а в d - дисперсія}

writeln;

writeln ('S=',s:8:4);

writeln ('D=',d:8:4);

reset (input); readln;

end.

Пр.Об'єднати 2 упорядкованих по зростанню масиву A і B у масив C.

Для розв'язку цього завдання теж достатньо одного проходу по масивах. Дійсно, завівши для кожного з масивів a,bіcпо власному лічильникові (позначимо їхia,ibіiвідповідно), ми можемо, залежно від істинності або хибності співвідношенняaia≤bibпереписувати в елементciзначенняaiaабоbibвідповідно. Залишається проконтролювати, щоб жоден з лічильників не вийшов за кордон розмірності свого масиву. Побачити деталі Вам допоможе уважний аналіз лістингу.

Для простоти не будемо змушувати користувача вводити із клавіатури дві неубутні послідовності чисел — уведення замінене генерацією випадкових елементів, сполученої з виводом генерируемых значень.

program m_concat;

const Size=10;

Step=5;

var a,b:array [1..Size] of integer;

c:array [1..2*Size] of integer;

i,n1,n2,ia,ib,ic:integer;

begin

writeln;

repeat

write('Уведіть розмірність 1 масиву ( від 2 до ',Size,'):');

read (n1);

until (n1>1) and (n1<=Size);

Randomize;

a[1]:=Random(Step);

write ('A= ',a[1],' ');

for i:=2 to n1 do begin

a[i]:=a[i-1]+Random(Step);

write (a[i],' ');

end;

writeln;

repeat

write('Уведіть розмірність 2 масиву ( від 2 до ',Size,'):');

read (n2);

until (n2>1) and (n2<=Size);

b[1]:=Random(Step);

write ('B= ',b[1],' ');

for i:=2 to n2 do begin

b[i]:=b[i-1]+Random(Step);

write (b[i],' ');

end;

writeln;

ia:=1; ib:=1;

write ('C= ');

for i:=1 to n1+n2 do begin

if a[ia]<=b[ib] then begin

c[i]:=a[ia];

if ia<n1 then Inc(ia)

else begin

a[n1]:=b[ib];

if ib<n2 then Inc (ib);

end;

end

else begin

c[i]:=b[ib];

if ib<n2 then Inc(ib)

else begin

b[n2]:=a[ia];

if ia<n1 then Inc(ia);

end;

end;

write (c[i],' ');

end;

writeln;

end.