матеріали для
підтримки вивчення предмету

Одновимірні масиви

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

Розглянемо одну з таких задач: для метеорологічної станції потрібно розробити програму, яка зберігає інформацію про щоденну температуру повітря протягом XX століття. Крім збереження, програма повинна проводити різноманітну обробку інформації: пошук максимальних та мінімальних температур, середніх показників тощо. В даній задачі для збереження добової температури повітря протягом століття знадобиться 365 × 100 = 36500 змінних.

Постають питання:

Для виходу з ситуації використаємо поняття послідовності чисел. В математиці елементи послідовності позначають таким чином: t1, t2, t3,... В програмуванні використовують схожі позначення: t[1], t[2], t[3],... Таку послідовність в програмуванні називають одновимірним масивом.

Масив - це скінченна послідовність змінних одного типу, які мають однакове ім'я та розрізняються порядковим номером. Порядковий номер називають індексом елемента.

Оголошення одновимірного масиву

int [ ] a = new int [100];

Такий програмний рядок оголошує одновимірний масив на 100 елементів (змінних) типу int. За замовчуванням, значення всіх елементів такого масиву дорівнює 0.

В мові програмування C# нумерація елементів масиву починається з 0. Тобто, оголошений вище масив містить 100 елементів, починаючи з a[0] і закінчуючи a[99].

Присвоєння значення, введення та виведення елементів одновимірного масиву

Для присвоєння значення елементу масиву потрібно вказати його ім’я (ім’я масиву та індекс елемента) і, після знаку присвоювання, значення, що надається, наприклад:

a[3] = 5;

Даний рядок присвоює четвертому елементу масиву a значення числа 5.

Введення та виведення елементів одновимірного масиву, а також їх найпростішу обробку розглянемо на прикладі задачі «Чорна п’ятниця» (рис. 9.1).

Програмування на C#
рис. 9.1

Відомо ціни деякої кількості товарів (не більше 50). Провести переоцінку товарів, зменшивши всі ціни вдвічі. Вивести нові ціни товарів та кількість переоцінених товарів.

Створимо нове рішення (lesson_9, проект task_1).

Алгоритм розв’язання поділимо на три частини:

1 — зчитування введених користувачем даних (цін) у масив;

2 — обробка елементів масиву (переоцінка товарів);

3 — виведення елементів масиву (нових цін).

Перед початком реалізації алгоритму проведемо оголошення масивів:

int[] a = new int[50];
  double[] b = new double[50];

Масив a буде містити старі ціни (нехай старі ціни будуть цілими числами); масив b – нові ціни.

Зчитування введених користувачем даних. До цього моменту в інтерфейсі програми для введення даних з клавіатури ми використовували текстові поля TextBox, при чому для кожної величини окреме поле. В нашій задачі користувач може ввести до 50 значень і, зрозуміло, розташовувати на формі таку кількість об’єктів TextBox не є реальним. Ознайомимося з новою для нас властивістю Multiline об’єкта TextBox. Якщо надати їй значення True, то об’єкт Текстове поле стає багаторядковим – в нього можна вводити більше одного рядка.

При розв’язуванні задач на одновимірні числові масиви ми не будемо перевіряти правильність введених даних, а, отже, при роботі з програмами користувач повинен дотримуватися такого правила: кожен рядок містить лише число і закінчується натиснутою клавішею [Enter], окрім останнього рядка – після введення останнього рядка [Enter] не натискається.

На рис. 9.1. показано випадок, в якому користувач ввів сім чисел (сім цін товарів). Нам потрібно зчитати сім введених значень і записати їх в одновимірний масив.

Раніше для зчитування введеного значення ми використовували команду виду:

int a = int.Parse(textBox1.Text);

Але нам потрібно повторити зчитування даних багато разів, тому використаємо новий підхід: скористаємося циклом for, попередньо визначивши скільки ітерацій потрібно виконати. Кількість повторень можна дізнатися, порахувавши кількість введених значень (кількість рядків, введених користувачем в елемент TextBox).

Типовий приклад зчитування даних у масив:

int k = textBox1.Lines.Count();
  for (int i = 0; i < k; i++)
  {
     a[i] = int.Parse(textBox1.Lines[i]);
  }

В першому рядку визначаємо кількість ліній (рядків), введених в елемент TextBox, і записуємо в змінну k. Далі цикл виконує повторення для значень лічильника від 0 до k. При кожному повторенні число, записане в лінії з номером i, записується в елемент масиву з номером i. Нумерація рядків в елементі TextBox, так само, як і нумерація елементів масиву, починається з 0.

Обробка елементів масиву. Для переоцінки товарів потрібно значення кожного елемента масиву зменшити вдвічі. Для того, щоб виконати це багато разів скористаємося аналогічним циклом, в якому в елементи масиву b будемо записувати зменшені вдвічі відповідні елементи масиву a:

for (int i = 0; i < k; i++)
  {
     b[i] = a[i] * 0.5;
  }

Виведення елементів масиву. Знову скористаємося циклом for для виконання k ітерацій:

for (int i = 0; i < k; i++)
  {
     listBox1.Items.Add(b[i]);
  }

Поєднавши всі частини алгоритму, отримаємо один з можливих варіантів розв’язання задачі «Чорна п’ятниця»:

private void button1_Click(object sender, EventArgs e)
     {
        int[] a = new int[50];
        double[] b = new double[50];

        int k = textBox1.Lines.Count();

        for (int i = 0; i < k; i++)
        {
           a[i] = int.Parse(textBox1.Lines[i]);
        }

        for (int i = 0; i < k; i++)
        {
           b[i] = a[i] * 0.5;
        }

        for (int i = 0; i < k; i++)
        {
           listBox1.Items.Add(b[i]);
        }
     }

При повторному використанні програми (повторній переоцінці товарів) потрібно стирати попередні результати. Для цього додамо в початок програми рядок для очищення елемента ListBox:

listBox1.Items.Clear();

Також після проведення переоцінки потрібно вивести повідомлення про кількість переоцінених товарів:

label3.Text = "Переоцінено: " + k + " товарів";

В наведеному розв’язку тричі використовується один і той самий цикл for. Перший - для зчитування даних, другий – для обробки, а третій – для виведення результатів. Програмний код можна значно скоротити, помістивши всі три дії в один цикл.

Оголошення масивів можна також провести інакше. В реалізованому нами алгоритмі ми оголошуємо два масиви розмірністю по 50 елементів, адже в магазині не більше 50 товарів. Але користувач при роботі з програмою може вносити значно менше даних і, в такому випадку, деякі елементи масиву залишаються невикористаними. Тому більш раціональним буде спочатку визначити кількість введених цін k, а потім оголосити масиви розмірністю по k елементів.

Врахувавши все вищесказане, алгоритм розв’язання задачі може виглядати наступним чином:

private void button1_Click(object sender, EventArgs e)
     {
         listBox1.Items.Clear();
         int k = textBox1.Lines.Count();
         int[] a = new int[k];
         double[] b = new double[k];
         for (int i = 0; i < k; i++)
         {
             a[i] = int.Parse(textBox1.Lines[i]);
             b[i] = a[i] * 0.5;
             listBox1.Items.Add(b[i]);
         }
         label3.Text = "Переоцінено: " + k + " товарів";
     }

Задача №2 (Task_2). Відомо ціни деякої кількості товарів. Також відомо відсоток знижки (знижка однакова для всіх товарів). Провести переоцінку товарів. Вивести нові ціни товарів та кількість переоцінених товарів. (рис. 9.2).

Інтерфейс програми містить всі елементи попередньої програми та додаткове поле TextBox для введення відсотку знижки.

В програмному коді додамо рядок для визначення введеної користувачем знижки, а також змінимо формулу для переоцінки товарів.

Програмування на C#
рис. 9.2
private void button1_Click(object sender, EventArgs e)
     {
         listBox1.Items.Clear();
         int k = textBox1.Lines.Count();
         double[] a = new double[k];
         double[] b = new double[k];
         int v = int.Parse(textBox2.Text);
         for (int i = 0; i < k; i++)
         {
             a[i] = int.Parse(textBox1.Lines[i]);
             b[i] = a[i] - a[i] * v / 100.0;
             listBox1.Items.Add(b[i]);
         }
         label3.Text = "Переоцінено " + k + " товарів";
     }

Знаходження найбільшого та найменшого значення елементів масиву

Задача №3 (Task_3). Відомо оцінки учня в атестаті. Визначити найбільший та найменший бал учня, а також середній бал атестату. (рис. 9.3).

Програмування на C#
рис. 9.3

Для зручності читання програмного коду поділимо алгоритм на три окремих підзадачі. Відповіді будемо виводити не в окремі об’єкти Label, а в компонент ListBox.

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

Знаходження мінімального елемента в масиві виконується аналогічно.

Для знаходження середнього значення елементів масиву спочатку доведеться обчислити суму всіх елементів. Для цього в тілі циклу достатньо записати команду: s = s + a[i]; . Поза циклом залишиться поділити знайдену суму на кількість елементів.

Програмний код для розв’язання задачі №3 має наступний вигляд:

private void button1_Click(object sender, EventArgs e)
     {
         listBox1.Items.Clear();
         int[] m = new int[30];
         int k = textBox1.Lines.Count();
         // зчитування елементів масиву
         for (int i = 0; i < k; i++)
         {
             m[i] = int.Parse(textBox1.Lines[i]);
         }
         // пошук max
         int max = m[0];
         for (int i = 1; i < k; i++)
         {
             if (m[i] > max)
                max = m[i];
         }
         listBox1.Items.Add("MAX = " + max);
         // пошук min
         int min = m[0];
         for (int i = 1; i < k; i++)
         {
             if (m[i] < min)
                 min = m[i];
         }
         listBox1.Items.Add("MIN = " + min);
         // пошук середнього
         int sum = 0; double sa = 0;
         for (int i = 0; i < k; i++)
         {
             sum = sum + m[i];
         }
         sa = Math.Round(sum * 1.0 / k, 2);
         listBox1.Items.Add("AVERAGE = " + sa);
     }

Заповнення елементів масиву довільними значеннями. Функція Random

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

Для роботи з випадковими числами спочатку потрібно оголосити об’єкт типу випадкові числа:

Random x = new Random();

Після такого оголошення з’являється можливість генерувати випадкові числа таким чином:

a = x.Next(1, 101);

В круглих дужках задається числовий проміжок, в якому генеруються випадкові числа (ліва межа включно, права межа не включно). Тобто, даний рядок генерує випадкове число в межах від 1 до 100. Помістивши даний рядок в цикл, можна генерувати довільну кількість випадкових чисел. Виводити сформований таким чином масив зручно в елемент ListBox.

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

Програмування на C#
рис. 9.4

Задача №4 (Task_4). Гральний кубик кинули 600 разів. Визначити, скільки разів випало задане користувачем число. (рис. 9.4).

Для реалізації даного проекту потрібно написати два методи: button1_Click – для заповнення масиву випадковими числами і виведення його на екран; button2_Click – для обробки масиву і виведення результатів. Отже, один і той же об’єкт програми (в нашому випадку масив) буде використовуватися в двох різних методах. Опис об’єктів, які використовуються в декількох методах, потрібно виносити за межі методів.

int[] a = new int[600];

  private void button1_Click(object sender, EventArgs e)
  {
      Random x = new Random();
      listBox1.Items.Clear();
      for (int i = 0; i < 600; i++)
      {
          a[i] = x.Next(1, 7);
          listBox1.Items.Add("Спроба №" + (i + 1) + ": " + a[i]);
      }
  }

  private void button2_Click(object sender, EventArgs e)
  {
      int c = int.Parse(textBox2.Text);
      int k = 0;
      for (int i = 0; i < 600; i++)
      {
          if (a[i] == c)
             k++;
      }
      listBox2.Items.Add("Цифра " + c + " випала " + k + " разів");
  }

Задача №5 (Task_5). Відомо річну кількість опадів протягом 10 років (для легкості тестування заповнимо випадковими числами в межах від 300 до 1000). Також відома річна норма опадів (задає користувач з клавіатури). Скласти програму, яка виводить два списки:

1. номери посушливих років та їх кількість;

2. номери років із нормальною або збільшеною кількістю опадів та їх кількість.

В інтерфейсі програми використаємо елемент TextBox (для введення норми опадів з клавіатури) та три елементи ListBox (один - для виведення масиву випадкових чисел і ще два - для виведення результатів (рис. 9.5).

Програмування на C#
рис. 9.5

В методі button1_Click заповнимо масив на 20 елементів випадковими числами в межах від 300 до 1000 та виведемо його на екран. В методі button2_Click за допомогою циклу проглянемо всі елементи масиву: обчислимо кількість елементів, значення яких менше введеної користувачем норми, та виведемо їх на екран в список «Менше норми»; всі інші елементи будемо виводити в список «Норма або більше».

int[] v = new int[20];

  private void button1_Click(object sender, EventArgs e)
  {
      listBox1.Items.Clear();
      Random x = new Random();
      for (int i = 0; i < 20; i++)
      {
          v[i] = x.Next(300, 1001);
          listBox1.Items.Add((i + 2000) + " рік - " + v[i] + "мм");
      }
  }

  private void button2_Click(object sender, EventArgs e)
  {
      listBox2.Items.Clear(); listBox3.Items.Clear();
      int norm = int.Parse(textBox2.Text);
      int k1 = 0, k2 = 0;
      for (int i = 0; i < 20; i++)
      {
          if (v[i] < norm)
          {
              listBox2.Items.Add((i + 2000) + " рік");
              k1++;
          }
          else
          {
              listBox3.Items.Add((i + 2000) + " рік");
              k2++;
          }
      }
      listBox2.Items.Add("Кількість = " + k1);
      listBox3.Items.Add("Кількість = " + k2);
   }

Динамічне створення об’єктів форми. Візуалізація елементів одновимірних масивів

Програмування на C#
рис. 9.6

До цього часу всі візуальні об’єкти інтерфейсу ми створювали на етапі конструювання форми програми. Але існує можливість створювати об’єкти інтерфейсу динамічно – під час виконання проекту. Розглянемо динамічне створення об’єктів на наступному прикладі: потрібно створити програму для динамічного створення п’яти Кнопок (рис. 9.6).

На етапі конструювання додамо на форму один об’єкт Button – кнопку «Створити» та об’єкт Panel – контейнер, в якому будуть розташовані динамічно створені кнопки.

В обробнику події button1_Click запишемо наступний програмний код:

private void button1_Click(object sender, EventArgs e)
  {
      Button[] a = new Button[5];
      for (int i = 0; i < 5; i++)
      {
          a[i] = new Button();
          a[i].Parent = panel1;
          a[i].Width = 120; a[i].Height = 35;
          a[i].Text = "Кнопка №" + (i + 1);
          a[i].Top = i * 40 + 5;
          a[i].Left = 5;
          a[i].BackColor = Color.Yellow;
      }
  }

Тут, в першому рядку, ми оголошуємо масив на п’ять об’єктів Button. Далі в тілі циклу створюємо кожен з об’єктів Button; вказуємо батьківським елементом контейнер Panel; задаємо ряд параметрів Кнопки: розміри, текст, положення відносно контейнеру та фоновий колір. Для того, щоб кожна наступна кнопка розташовувалася нижче попередньої, потрібно у властивості Top (відстань від верхнього краю Панелі до верхнього краю Кнопки) зробити прив’язку до лічильника i.

Задача №7 (Task_7). Програма генерує випадкову погоду протягом перших семи днів серпня (можливо три стани погоди: «сонячно», «хмарно», «дощ»). Провести візуалізацію стану погоди (рис.9.7).

Дана програма складається з двох частин. Для генерації випадкової погоди використаємо числовий масив a з семи елементів, які заповнимо випадковими цифрами від 1 до 3. Кожній цифрі поставимо у відповідність стан погоди. За допомогою розгалуження перейдемо від цифр до погодних станів: 1 – сонячно, 2 – похмуро, 3 – дощ.

Для реалізації другої частини програми – візуалізації погоди - знадобляться три зображення станів погоди, які потрібно розмістити в папку Debug відповідного проекту. На початку алгоритму оголосимо два масиви на 7 елементів кожний: масив p – масив зображень PictureBox та масив t – масив написів Label. Далі в циклі на сім ітерацій будемо створювати відповідні об’єкти і задавати їх параметри. Вибирати і додавати зображення в об’єкти PictureBox будемо на основі вже згенерованого числового масиву a. В зв’язку з тим, що даний масив використовується в різних методах, його оголошення винесемо за межі методів.

В обробнику події button1_Click запишемо наступний програмний код:

Програмування на C#
рис. 9.7

Один з можливих варіантів розв’язання даної задачі наведено нижче:

int[] a = new int[7];

   private void button1_Click(object sender, EventArgs e)
   {
       Random x = new Random();
       listBox1.Items.Clear();
       string s;
       for (int i = 0; i < 7; i++)
       {
           a[i] = x.Next(1, 4);
           if (a[i] == 1)
               s = "сонячно";
           else if (a[i] == 2)
               s = "похмуро";
           else
               s = "дощ";
           listBox1.Items.Add((i + 1) + " серпня: " + s);
       }
   }

   private void button2_Click(object sender, EventArgs e)
   {
      PictureBox[] p = new PictureBox[7];
      Label[] t = new Label[7];

      panel1.Controls.Clear();
      for (int i = 0; i < 7; i++)
      {
          p[i] = new PictureBox();
          p[i].Parent = panel1;
          p[i].Size = new Size(40, 40);
          p[i].Top = 0;
          p[i].Left = 50 * i + 5;
          if (a[i] == 1)
              p[i].Image = Image.FromFile("sun.png");
          else if (a[i] == 2)
              p[i].Image = Image.FromFile("cloud.png");
          else p[i].Image = Image.FromFile("rain.png");
          p[i].SizeMode = PictureBoxSizeMode.StretchImage;

          t[i] = new Label();
          t[i].Text = (i + 1) + " серпня";
          t[i].Parent = panel1;
          t[i].Font = new Font("Arial", 7, FontStyle.Bold);
          t[i].Top = 45;
          t[i].Left = 50 * i + 5;
          t[i].Width = 50;
      }
  }

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

Завдання №8 (рішення lesson_9, проект task_8). Відомо розміри заробітної платні деякої групи працівників (кількість працівників не перевищує 20). Обчислити податок, який буде стягнуто з кожного працівника (податок становить 17%). (рис. 9.8).

Програмування на C#
рис. 9.8

Завдання №9 (рішення lesson_9, проект task_9). Відомо ціни деякої кількості товарів в доларах (кількість працівників не перевищує 100). Перевести всі ціни товарів в гривні. Курс долара вводить користувач. (рис. 9.9).

Програмування на C#
рис. 9.9

Завдання №10 (рішення lesson_9, проект task_10). Відомо щоденну температуру повітря протягом першого тижня травня. Вивести на екран мінімальну і максимальну температуру та дні, коли це сталося, а також середню температуру тижня. (рис. 9.10).

Програмування на C#
рис. 9.10

Завдання №11 (рішення lesson_9, проект task_11). Гральний кубик кинули 30 разів. Визначити, скільки разів випала кожна із граней кубика. (рис. 9.11).

Програмування на C#
рис. 9.11

Завдання №12 (рішення lesson_9, проект task_12). Відомо щомісячну кількість проданих автомобілів протягом року (програма генерує випадкові продажі). Також відомо місячну норму продажів (задає користувач). Провести візуалізацію продаж, позначивши місяці з виконаним планом веселим смайликом, а з невиконаним – сумним. (рис. 9.12).

Програмування на C#
рис. 9.12