четверг, 24 января 2013 г.

Масиви

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

Масив - це великий простір чогось однорідного за типом.
(Зі словника іноземних слів, 1954 р.)
Масив у програмуванні - це тип структури даних, що має складені значення. (З Оксфордського словника англійської мови, 1995 р.)
Масив - це впорядкований скінченний набір елементів (даних) одного типу. Зазвичай працюють з масивами, які містять числа.
Масивом називається скінченна послідовність змінних одного типу, які мають однакове ім'я та різняться порядковим номером.

Індексом називається порядковий номер елемента масиву.

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

Як звернутися до елементів цього масиву? Для цього необхідно вказати індекс.

Наприклад,

T[2], T[5], T[i], T[i + j].

Але в третьому і четвертому прикладах для визначення необхідного елемента масиву треба знати значення величин і та j. Така загальність визначення індексу масиву є дуже потужним засобом програмування, але разом з цим і провокує можливі помилки: отриманий результат обчислення індексу масиву може виходити за межі інтервалу, виділеного для індексів даного масиву.

I ще один важливий момент, яким у жодному разі не можна нехтувати. Масиви відносяться до структур з так званим прямим або довільним доступом: щоб визначити окремий елемент масиву, достатньо вказати його індекс.

Тепер зрозуміло, як у циклі перебирати різні значення елементів масиву: для цього достатньо змінювати їх індекси. А закон зміни індексів дуже простий - кожне наступне значення більше попереднього на одиницю. Дуже зручна закономірність!


Оскільки у мові Pascal усе з чим ми працюємо потрібно оголошувати, то масиви також потрібно оголосити. Це можна зробити кількома способами:

у полі const

const <ім'я змінної>=array[1 .. <клькість елементів>] of <тип> = (1,2,3, ... <значення>);

у полі type

type <ім'я типу>=array[1 .. <кількість елементів>] of <тип>;
var <ім'я змінної> : <ім'я типу>; 

у полі var

var <ім'я змінної> : array[1 .. <кількість елементів>] of <тип>;

Приклад:

type Mas = array[1 .. 5] of integer;
var a : Mas;

Масиви бувають одновимірними (у вигляді послідовності чисел), двовимірними (у вигляді таблиць чисел розміром m x n) і багатовимірними (3-,4-вимірні і т.д. 3-вімірні - це об'ємний простір з комірками, а 4-вимірні і більше - це фантастично-абстрактні поняття). 

Масив називається одновимірним, якщо для задання місцеположення елемента в масиві необхідно вказати значення лише одного індексу.
Масив називається двовимірним, якщо для задання місцеположення елемента в масиві необхідно вказати значення двох індексів.
Запам'ятайте, що у двовимірних масивах перший індекс завжди вказує на номер рядка, а другий - на номер стовпчика в цьому рядку!
Розмірність масивів у Pascal необмежена, вона визначається лише об'ємом пам'яті вашого комп'ютера.
Резонним буде запитання: а як же розташовуються масиви в пам'яті комп'ютера? Пояснення для одновимірних масивів дуже просте – всі вони розташовані в пам'яті підряд. Двовимірні масиви розташовуються дещо інакше - спочатку елементи пер­шого рядка, потім другого і т. д. Розташування масивів більшої розмірності пояснюється аналогічно.
Залишилося з'ясувати, як пояснити програмі, що ви працюватимете з елементами, які утворюють масив значень.Загальний вигляд опису масивів:
<ім'я змінної>: array [<межі зміни індексів>] of <тип>.
Наприклад,
varA: array[1..10] of real;B: array[1..100,1..100] of byte;C: array[1..100] of array[1..100] of byte.
Цікаво, що другий і третій приклади описують однакові ма­сиви. Справді, адже будь-яку таблицю можна розглядати як послідовність рядків, де кожний рядок у свою чергу є також послідовністю. Звернення до елементів останнього масиву буде мати такий вигляд: C[i][j].
Зауваження.
По-перше, межі індексів завжди вказуються через два символи «.».
По-друге, при розподілі пам'яті в опи­совій частині програми під масив буде зарезервовано стільки місця, скільки передбачає вказана кількість елементів масиву. Тому при виконанні програми ви можете використовувати кількість елементів не більшу, ніж описана в розділі змінних.
По-третє, межі зміни індексів повинні бути сталими величи­нами, а не змінними, інакше невідомо буде, скільки місця не­обхідно відвести в пам'яті під такий масив.

Розглянемо таку задачу.
Нехай дано таблицю здійснення рейсів N автобусами протягом M днів. Рейси, що відбулися, позначаються в таблиці цифрою 1, а ті, що з деяких причин не відбулися, - цифрою 0. Треба скласти програму, яка підраховує кількість рейсів, що не відбулися.
Приклад програми
program voyage;
var R :array[1..30,1..100] of byte;

і, j, n, m, count : integer;
begin
write ('Задайте кількість автобусів: ');
repeatreadIn(n) until (n > 0) and (n <= 30);
write ('Задайте кількість днів: ');
repeatreadln (m) until (m > 0) and (m <= 100);
writeln ('Задайте інформацію про здійснення рейсів: ');
for i := 1 to n do for j := 1 to m do beginwrite (i, ' автобус, ', j, ' день: ');
repeatreadln(R[i,j]) until (R[i, j] = 0) or (R[i, j] = 1) end;count := 0;
for і := 1 to n do
for j := 1 to m do
if R[i. j] = 0 then count := inc (count);
writeln ('Кількість нездійснених рейсів: ', count:5);
repeat
until
Key
Pressed
end.
У цій програмі використано нову стандартну процедуру мови Pascal inc (count). Ії призначення - заміна значення пара­метра на 1. Можливий ще такий варіант використання цієї процедури: inc (n, step). У цьому разі збільшення параметра п відбуватиметься з кроком step. У Pascal існує альтернативна процедура Dec, яка зменшує значення вказаного параметра.

Якщо ви спробували виконати цю програму на комп'ютері, то, напевно, під час виправлення можливих помилок вам що­разу доводилося знову і знову задавати початкові дані. Можли­вості мови Pascal дають змогу уникнути такої незручності.

Повернемося до початку знайомства з Pascal, де вводилося поняття про розділ констант const. У цьому розділі ідентифіка­торами позначаються сталі величини. Надалі в програмі замість цих сталих величин вказуватимемо лише відповідні їм ідентифікатори. Зручність полягає в тому, що якщо знадобить­ся поміняти значення якоїсь константи, то достатньо це зроби­ти тільки в розділі const, не чіпаючи всієї програми.

Наприклад, можна розміри масиву задати таким чином:
const SizeLine = 100;
SizeColumn = 100;
var A: array [1..SizeLine, 1..SizeColumn] of real;
.............................................
repeatread (n, m) until (n > 0) and (n <= SizeLine) and (m > 0) and (m <= SizeColumn);


Зверніть увагу на те, що в розділі констант стоїть символ «=», а не символ «:=».Використовуючи в програмі константи, необхідно врахувати таку особливість: їх значення не можна змінювати під час виконання програми. Тобто ідентифікаторам, що визначають

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

Ми говорили про те, як незручно під час редагування програми щоразу заново задавати значення елементів масиву. Спробуємо і це зробити за допомогою розділу констант:

constA:array[1..3, 1..4] of real= ((1.5, 1.2, 2.1,-4.42), (2.4,5.7,-1, 45.4), (-1.1,7, 45,-10));

3 останнього прикладу видно, що в розділі констант можна задавати ще й тип. Такі константи називаютьсятипізованими. Значення масивам задаються таким чином: в одновимірних масивах вони записуються через кому, у двовимірних – значення елементів рядків беруться у круглі дужки, для тривимірних – аналогічним чином. Відмінність типізованих констант від простих, для яких тип не вказується, полягає в тому, що їх значен­ня можна змінювати під час виконання програми.

Якщо ж вас не цікавлять конкретні дані, які будуть надані елементам масиву під час виконання програми, то скористайтеся можливостями стандартної процедури Pascal Randomize та функції Random (n), що генерують випадкові числа. Параметр n (типу Word) у процедурі Random визначає праву межу інтервалу, в якому будуть визначатися випадкові числа (ліва межа завжди 0). Функція Random може задаватися і без параметра. У цьому разі вона генеруватиме те дійсне число в діапазоні [0; 1). А для того щоб випадкові числа в програмі з кожним її наступним запуском не повторювалися (хоча вони і випадкові, але послідовність цих чисел постійна), то скористайтеся процедурою Randomize, яка встановить початок відрахунку випадкових чисел залежно від поточного стану системного годинника вашого комп'ютера.

Фрагмент програми, що використовує випадкові числа, може виглядати так:

randomize;
for і := 1 to n doa[i] := random (100);


Одновимірні масиви 
  Введення масиву з клавіатури
     for i:=1 to n do readln(a[i]);    тут (і надалі) і - параметр, n - кількість елементів у 
                                                       масиві, а -  одновимірний масив
  Друк масиву на екран 
     for i:=1 to n do writeln(a[i]);
   Перебір всіх елементів
     for i:=1 to n do
        begin
       if a[i]=0 then s:=s+1;    - кількість елементів, які відповідають умові (у даному разі 
                                       ті, що рівні  нулю). Кількість буде записана до змінної s 
      if a[i]=0 then k:=i;        - порядковий номер елементу, який відповідає умові (=0)
        end;
  Пошук мінімального/максимального елеманту 
Припускаємо, що це перший і переглядаємо масив. Якщо зустрінемо більший (чи менший) за нього елемент, то цей елемент стає максимальним (мінімальним). Розглянемо пошук максимального:
max:=a[1]; 
for i:=1 to n do
   if a[i]>max then max:=a[i];
  Сортування за зростанням/спаданням 
Переглянемо масив n разів. Кожного разу розглядаємо всі елементи від 1 до n-1. Якщо елемент більший (сортування за зростанням) за нступний за ним, то міняємо їх місцями.
fo j:=1 to n do        {переглядаємо масив n разів}
for i:=1 to n-1 do    {переглядаємо кожного разу елементи від 1 до n-1 (бо можемо                          
                      поміняти міцями  a[n-1] і a[n] - а у програмі буде a[i] та a[i+1] при i=n-1)}
    if a[i]>a[i+1] then
       begin
            b:=a[i];       {зберігаємо значення a[i] в іншу змінну, тип якої такий як і   
                                               елементів масиву}
            a[i]:=a[i+1];  {власне міняємо місцями елементи - записуємо менше значення на 
                                              місце    більшого}
            a[i+1]:=b;       {"витягуємо" з пам'яті значення a[i], більше, і записуємо на нове   
                                                               місце}
       end; 
Такий метод сортування називається бульбашковим (або "Метод бульбашки"). Різні особи по-різному трактують цю назву, тому я взагалі не буду трактувати її. Сприймайте цей метод так, як його обізвали.
Двовимірні масиви (n x m)
  Введення масиву з клавіатури 
for i:=1 to n do       {перебір n рядків}
  for j:=1 to m do     {перебір m стовпців}
    readln(a[i,j]);         {власне ввід кожного елементу}
  Вивід масиву на екран 
Щоб вивести двовимірний масив на екран у вигляді таблиці роблять наступне: 
for:=1 to n do     {перебір рядків}
  begin
     for j:=1 to m do write(a[i,j],' ');      {вивід кожного рядка}
     writeln;                                       {перехід на новий рядок}
  end; 

Приклад програми.
Утворити і вивести масив у з елементами у(к), к=1,12. Перший додатний елемент поміняти місцями з максимальним
program Masuvu;
uses crt;
var y,g:array [1..12] of real; max,h:real;
k,n,m:integer;
begin 
clrscr; 
max:=-1000000; 
n:=0; 
for k:=1 to 12 do 
begin 
y[k]:=sin(k*k)*cos(k*k*k)-sin(k)+5.2; 
if y[k]>max then 
begin 
max:=y[k]; 
m:=k; 
end; 
if y[k]>0 then 
begin 
n:=n+1; 
g[n]:=y[k]; 
h:=g[1]; 
end; 
if y[k]=g[1] then 
begin 
y[k]:=max; 
y[m]:=h; 
end; 
writeln (k,' element ',y[k]:5:2); 

if n>0 then writeln ('pershuj dodatnij element',g[1]:5:2)else writeln('nema dodatnih elementiv'); 
writeln ('maksumalnuj element - ', m,' -',max:5:2); 
readln; 
end. 
end.

вторник, 22 января 2013 г.

задачі

 Одним з способом реалізації статичних масивів з одним типом елементів є наступний (в Фортрані порядок індексів протилежний такому в Сі [4]):

    
Під масив виділяється безперервний блок пам'яті об'ємом S * m1 * m2 * m3 ... mn, де S - розмір одного елемента, а m1 ... mn - розміри діапазонів індексів (тобто кількість значень, які може приймати відповідний індекс).
    
При зверненні до елементу масиву A [i1, i2, i3, ..., in] адресу відповідного елемента обчислюється як B + S * ((... (i1p * m1 + i2p) * m2 + ... + i (n-1) p) * mn -1 + inp), де B - база (адреса початку блоку пам'яті масиву), ikp - значення k-го індексу, наведене до цілого з нульовим початковим зміщенням.
Таким чином, адреса елемента із заданим набором індексів обчислюється так, що час доступу до всіх елементів масиву однаково.
Перший елемент масиву, в залежності від мови програмування, може мати різний індекс. Розрізняють три основних різновиди масивів: з відліком від нуля (zero-based), з відліком від одиниці (one-based) і з відліком від специфічного значення заданого програмістом (n-based). Відлік індексу елемента масивів з нуля більш характерний для низькорівневих мов програмування, проте цей метод був використаний в мовах більш високого рівня мовою програмування Сі.
Більш складні типи масивів - динамічні і гетерогенні - реалізуються складніше.Переваги

    
легкість обчислення адреси елемента за його індексом (оскільки елементи масиву розташовуються один за іншим)
    
однаковий час доступу до всіх елементів
    
малий розмір елементів: вони складаються тільки з інформаційного поля
Недоліки

    
для статичного масиву - відсутність динаміки, неможливість видалення або додавання елемента без зсуву інших
    
для динамічного і / або гетерогенного масиву - більш низьке (у порівнянні зі звичайним статичним) швидкодія і додаткові накладні витрати на підтримку динамічних властивостей і / або гетерогенності.
    
при роботі з масивом в стилі C (з покажчиками) і при відсутності додаткових засобів контролю - загроза виходу за межі масиву і пошкодження даних



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

const 
  Sz = 100;
var 
  a: array [1..Sz] of real;
  N: integer;   
  min: real;
  minind: integer;
begin
  N := 20;
  for var i:=1 to N do
    a[i] := Random(100);
  writeln('Элементы массива: ');
  for var i:=1 to N do
    write(a[i],' ');
  writeln;  
 
  min := a[1];
  minind := 1;
  for var i:=2 to N do
    if a[i]then
begin min := a[i]; minind := i; end;   writeln('Минимальный элемент: ',min); writeln('Индекс минимального элемента: ',minind); end.
 
 алгоритм обчислення середньорічної температури.
 
 Program Temperature;
var T: array [1 .. 12] of real;
I: integer; Tsred: real;
begin
         {Цикл введення}
      for I: = l to 12 do
      begin
           write ('T [', 1:2, '] =');
           readln (T [I])
      end;
         {Цикл підсумовування}
      Tsred: = 0;
      for I: = l to 12 do
           Tsred: = Tsred + T [I];
         {Обчислення середнього}
      Tsred: = Tsred/12;
      writeln ('Середньорічна температура =', Tsred: 6:2, 'градусів')
end.

вторник, 25 декабря 2012 г.

задачі

 вивід букв англійського алфавіту
 
var c: char;
 
begin
  for c := 'a' to 'z' do
    write(c,' ');
  writeln;  
  c := 'A';
  while c<='Z' do
  begin
    write(c,' ');
    c := succ(c);
  end;
end.
 
вивід послідовностей 1 2 3 4 5 і 5 4 3 2 1
 
 var i: integer;
begin
//  for
  for i := 1 to 5 do
    write(i,' ');
  writeln;
 
  for i := 5 downto 1 do
    write(i,' ');
  writeln;
  writeln;
 
// while
  i := 1;
  while i<=5 do
  begin
    write(i,' ');
    i := i + 1;
  end;
  writeln;
 
  i := 5;
  while i>=1 do
  begin
    write(i,' ');
    i := i - 1;
  end;
  writeln;
  writeln;

вторник, 11 декабря 2012 г.

Таблиця множення на Паскалі

Досить часто потрібно побудувати на екрані якусь двовимірну таблицю. Це можна реалізувати за допомогою двох циклів для. При цьому один цикл повинен бути вкладений в інший.

Припустимо, нам потрібно вивести на екран таблицю множення.
Алгоритм рішення задачі:

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

Внутрішній цикл для формує кожне значення в рядку. Всього значень у рядку 10. Значить і число його ітерацій повинно бути 10.

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

Після виходу з внутрішнього циклу, перед наступною ітерацією зовнішнього циклу потрібно здійснити перехід на новий рядок. Інакше всі значення будуть записані не у вигляді таблиці, а у вигляді одного рядка.


var
  x,y:0..10;
  s:integer;
begin
  for x:= 0 to 10 do
    for y:= 0 to 10 do
      begin
        s:=(x+1)*(y+1);
        write(s:5);
      end;
   writeln;
end.
 
в такому вигляді таблиця виходить до 11, і останній WriteLn не належить першому циклу, від того і не переносить рядок, після завершення другого. 


 Визначення чверті на координатній площині

 Всім відома прямокутна (декартова) система координат, в якій дві перпендикулярні осі ділять площину на чверті. У першу чверть потрапляють точки, у яких обидві координати (X і Y) більше нуля. У другу: х <0 span="span">, у> 0; третю: х <0, у <0 span="span">; четверту: х> 0, у <0 span="span">.

Допустимо, потрібно написати програму, що визначає по координатам точки, в якій чверті вона знаходиться.
Алгоритм рішення задачі:

Для вирішення цього завдання доречно використовувати умовні оператори, якщо-інакше вкладені одна в одну.



var
    x,y: real;
 
begin
    write ('x = '); read (x);
    write ('y = '); readln (y);
 
    write ('Номер четверті координатної  площини: ');
    if (x > 0) and (y > 0) then
        writeln ('I')
    else
        if (x < 0) and (y > 0) then
            writeln ('II')
        else
            if (x < 0) and (y < 0) then
                writeln ('III')
            else
                if (x > 0) and (y < 0) then
                    writeln ('IV')
                else
                    writeln ('-. Точка лежить на осі.');
 
readln
end.

вторник, 4 декабря 2012 г.

Практичне заняття

Визначити яке з трьох, введених користувачем, чисел максимальне і вивести його на екран.

У програмі буде три змінні для чисел, що вводяться користувачем: N1, N2, N3. Також для спрощення алгоритму введемо четверту змінну, в яку по ходу виконання коду буде поміщено максимальне значення: макс.

 
Алгоритм

     Порівняти перше і друге число (N1 і N2). Змінної макс присвоїти значення змінної, що містить більше значення.
     Порівняти значення змінної макс з третім числом, введеним користувачем (n3). Якщо значення n3 виявиться більше, ніж максимальна, то привласнити максимальне значення третього числа. Якщо ж значення максимальної виявиться більше, то нічого не робити.


var
    a1, a2, a3, max: integer;
 
begin
    write ('Введіть три числа: ');
    readln (a1, a2, a3);
 
    if a1 >= a2 then
        max := a1
    else
        max := a2;
 
    if a3 > max then
        max := a3;
 
    writeln ('Максимальне з них: ', max);
 
readln
end.


Як можна переписати цю програму, щоб позбутися від мітки.


label lab;
var month;
begin
    lab:
    write('Введіть номер місяця: ');
    readln(month);
    if not (month in [1..12]) then
        goto lab;
 
 
 Рішення
 
 while not (month in [1..12]) do begin
    write('Номер місяця : ');
    readln(month);
end;
 

среда, 28 ноября 2012 г.

задачі

Знайти кількість цифр у цілому числі.


Program c0;
Uses crt;
Var n,k:integer;
Begin
ClrScr;
Writeln('введіть число');
readln (n);
k:=0;
while n>0 do
begin
n:=n div 10;
k:=k+1;
end;
writeln('кількість цифр =',k);
readln;
end.

Ввести дріб а / б. Визначити,  Чи дріб є скоротний. (Дріб є нескоротним, якщо НСД (A, B) = 1.



Program cikl_15;
uses crt;
var m,n : longint;
begin
clrscr;
write('чисельник ');readln(m);
write('знаменник ');readln(n);
while m<>n do
if m>n
then m:=m-n
else n:=n-m;
n:=m;
if n=1
then write('скорочений')
else write('нескорочений');
readln;
end.

вторник, 27 ноября 2012 г.

Задачі

Вгадати число
 
var
    a,b: integer;

begin
    randomize;
    a := random(100);

    while a <> b do begin
        write('Введіть число: ');
        readln(b);
        if b > a then
            writeln('Багато')
        else
            if b < a then
                writeln('Мало')
            else
                writeln('Вгадал');
    end;

readln
end.

Написати програму, яка виводить квадрати цілих чисел на проміжку від  A до B.

var a,b:integer;k:real;
begin
writeln('a,b');
readln(a,b)
while a<>b
 begin
 k:=sqr(a);
writeln(k);
a:=a+1;

end;
 end.