Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Масиви масивів
Ще одним видом масивів C# є масиви масивів, названі також порізаними масивами (jagged arrays). Такий масив масивів можна розглядати як одномірний масив, елементи якого є масивами, елементи яких, у свою чергу, знову можуть бути масивами, і так може тривати до деякого рівня вкладеності. У яких ситуаціях може виникати необхідність у таких структурах даних? Ці масиви можуть застосовуватися для подання дерев, у яких вузли можуть мати довільне число нащадків. Таким може бути, наприклад, генеалогічне дерево. Вершини першого рівня - Fathers, що представляють батьків, можуть задаватися одномірним масивом, так що Fathers[i] - це i-й батько. Вершини другого рівня представляються масивом масивів - Children, так що Children[i] - це масив дітей i-го батька, а Children[i][j] - це j-й дитина i-го батька. Для подання онуків знадобиться третій рівень, так що GrandChildren [i][j][k] буде представляти к-го онука j-го дитини i-го батька. Є деякі особливості в оголошенні й ініціалізації таких масивів. Якщо при оголошенні типу багатомірних масивів для вказівки розмірності використалися коми, то для порізаних масивів застосовується більш зрозуміла символіка - сукупності пари квадратних дужок; наприклад, int[][] задає масив, елементи якого - одномірні масиви елементів типу int. Складніше зі створенням самих масивів і їхньою ініціалізацією. Тут не можна викликати конструктор new int[3][5], оскільки він не задає порізаний масив. Фактично потрібно викликати конструктор для кожного масиву на самому нижньому рівні. У цьому й складається складність оголошення таких масивів. Почну з формального прикладу: //масив масивів - формальний приклад//оголошення й ініціалізаціяint[][] jagger = new int[3][]{ new int[] {5, 7, 9, 11}, new int[] {2, 8}, new int[] {6, 12, 4}};Масив jagger має всього два рівні. Можна вважати, що в нього три елементи, кожний з яких є масивом. Для кожного такого масиву необхідно викликати конструктор new, щоб створити внутрішній масив. У даному прикладі елементи внутрішніх масивів одержують значення, будучи явно ініціалізовані константними масивами. Звичайно, припустиме й таке оголошення: У цьому випадку елементи масиву одержать при ініціалізації нульові значення. Реальну ініціалізацію потрібно буде виконувати програмним шляхом. Варто помітити, що в конструкторі верхнього рівня константу 3 можна опустити й писати просто new int[][]. Саме забавне, що виклик цього конструктора можна взагалі опустити - він буде матися на увазі: int[][] jagger2 ={ new int[4], new int[2], new int[3]};А от конструктори нижнього рівня необхідні. Ще одне важливе зауваження - динамічні масиви можливі й тут. У загальному випадку, границі на будь-якому рівні можуть бути вираженнями, що залежать від змінних. Більше того, припустимо, щоб масиви на нижньому рівні були багатомірними. Але це вже " від лукавого" - навряд чи варто користуватися такими складними структурами даних, адже з ними треба буде ще й працювати. Приведу тепер ледве більше реальний приклад, що описує просте генеалогічне дерево, що умовно назву " батьки й діти": //масив масивів -" Батьки й діти" int Fcount =3; string[] Fathers = new string[Fcount]; Fathers[0] =" Микола"; Fathers[1] = " Сергій"; Fathers[2] = " Петро"; string[][] Children = new string[Fcount][]; Children[0] = new string[] {" Ольга", " Федір" }; Children[1] = new string[] {" Сергій", " Валентина", " Ира", " Дмитро" }; Children[2] = new string[]{" Марія", " Ирина", " Надія" }; myar.PrintAr3(Fathers, Children);Тут батьків описує звичайний динамічний одномірний масив Fathers. Для опису дітей цих батьків необхідний уже масив масивів, що також є динамічним на верхньому рівні, оскільки число його елементів збігається із числом елементів масиву Fathers. Тут показаний ще один спосіб створення таких масивів. Спочатку конструюється масив верхнього рівня, що містить посилання зі значенням void. А потім на нижньому рівні конструктор створює дійсні масиви в динамічній пам'яті, з якими й зв'язуються посилання. Я не буду демонструвати роботу з генеалогічним деревом, обмежуся лише печатанням цього масиву. Тут є кілька повчальних моментів. У класі Array для печатання масиву створений спеціальний метод PrintAr3, якому як аргументи передаються масиви Fathers й Children. От текст даної процедури: public void PrintAr3(string [] Fathers, string[][] Children){ for(int i = 0; i < Fathers.Length; i++) { Console.WriteLine(" Батько: {0}; Його діти: ", Fathers[i]); for(int j = 0; j < Children[i].Length; j++) Console.Write(Children[i][j] + " "); Console.WriteLine(); }}//PrintAr3Приведу деякі коментарі до цієї процедури: · Зовнішній цикл організований по числу елементів масиву Fathers. Помітьте, тут використається властивість Length, на відміну від раніше застосовуваного методу GetLength. · У цьому циклі з тим же успіхом можна було б використати й ім'я масиву Children. Властивість Length для нього повертає число елементів верхнього рівня, що збігає, як уже говорилося, із числом елементів масиву Fathers. · У внутрішньому циклі властивість Length викликається для кожного елементу Children[i], що є масивом. · Інші деталі, сподіваюся, зрозумілі. Приведу вивід, отриманий у результаті роботи процедури PrintAr3.
В наданих задачах виділіть стандартні блоки та проаналізуйте їх роботу. Задача 12.1. Дано довільний двомірний масив, парні рядки розмістити по зростанню, непарні по спаданню.
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace _28 { class Program { static void Main(string[] args) { Console.Write(" N="); int n=Int32.Parse(Console.ReadLine()); Console.Write(" M="); int m = Int32.Parse(Console.ReadLine()); int i = 0, j = 0, max=0, f=1, t=0; int[, ] mas=new int[n, m]; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { Console.Write(" [" + i + ", " + j + " ]="); mas[i, j] = Int32.Parse(Console.ReadLine()); } } for (i = 0; i < n; i+=2) { f = 1; while (f == 1) { f = 0; for (j = 1; j < m; j++) { if (mas[i, j] < mas[i, j - 1]) { t = mas[i, j]; mas[i, j] = mas[i, j - 1]; mas[i, j - 1] = t; } } } }
for (i = 1; i < n; i += 2) { f = 1; while (f == 1) { f = 0; for (j = 1; j < m; j++) { if (mas[i, j] > mas[i, j - 1]) { t = mas[i, j]; mas[i, j] = mas[i, j - 1]; mas[i, j - 1] = t; } } } }
for (i = 0; i < n; i++) { for (j = 0; j < m; j++) Console.Write(" " + mas[i, j]); Console.WriteLine(); } Console.ReadKey(); } } } Задача 12.2. Дано довільний двомірний масив, парні рядки поміняти місцями з непарними. using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace _29 { class Program { static void Main(string[] args) { Console.Write(" N="); int n = Int32.Parse(Console.ReadLine()); Console.Write(" M="); int m = Int32.Parse(Console.ReadLine()); int i = 0, j = 0, t=0; int[, ] mas = new int[n, m]; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { Console.Write(" [" + i + ", " + j + " ]="); mas[i, j] = Int32.Parse(Console.ReadLine()); } } for (i = 1; i < n; i+=2) { for (j = 0; j < m; j++) { t = mas[i - 1, j]; mas[i - 1, j] = mas[i, j]; mas[i, j] = t; } } for (i = 0; i < n; i++) { for (j = 0; j < m; j++) Console.Write(" " + mas[i, j]); Console.WriteLine(); } Console.ReadKey(); } } } Задача 12.3. Дано довільний двомірний масив, видалити рядок і стовпчик де знаходиться максимальний елемент масиву. using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace _30 { class Program { static void Main(string[] args) { Console.Write(" N="); int n = Int32.Parse(Console.ReadLine()); Console.Write(" M="); int m = Int32.Parse(Console.ReadLine()); int i = 0, j = 0, ms=0, mr=0, i1=0, j1=0, f; int[, ] mas = new int[n, m]; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { Console.Write(" [" + (i+1) + ", " + (j+1) + " ]="); mas[i, j] = Int32.Parse(Console.ReadLine()); } } for (i = 0; i < n; i++) { f = 1; mr=mas[i, 0]; while (f == 1) { f = 0; for (j = 1; j < m; j++) { if (mr < mas[i, j]) { mr = mas[i, j]; i1 = i; } } } } for (j = 0; j < n; j++) { f = 1; ms = mas[0, j]; while (f == 1) { f = 0; for (i = 1; i < m; i++) { if (ms < mas[i, j]) { ms = mas[i, j]; j1 = i; } } } } for (i = 0; i < n; i++) { if (i == i1) continue; for (j = 0; j < m; j++) { if (j == j1) continue; Console.Write(" " + mas[i, j]); } Console.WriteLine(); } Console.ReadKey(); } } } Задача 12.4. Дано двомірний масив розмірністю N-M, знайти суму рядка і стовпчика на перетинанні яких знаходиться максимальний елемент масиву. using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace _31 { class Program { static void Main(string[] args) {
Console.Write(" N="); int n = Int32.Parse(Console.ReadLine()); Console.Write(" M="); int m = Int32.Parse(Console.ReadLine()); int i = 0, j = 0, ms = 0, mr = 0, i1 = 0, j1 = 0, f; int[, ] mas = new int[n, m]; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { Console.Write(" [" + (i + 1) + ", " + (j + 1) + " ]="); mas[i, j] = Int32.Parse(Console.ReadLine()); } } mr = mas[0, 0]; for (i = 0; i < n; i++) { f = 1; while (f == 1) { f = 0; for (j = 1; j < m; j++) { if (mr < mas[i, j]) { mr = mas[i, j]; i1 = i; } } } } ms = mas[0, 0]; for (j = 0; j < n; j++) { f = 1; while (f == 1) { f = 0; for (i = 1; i < m; i++) { if (ms < mas[i, j]) { ms = mas[i, j]; j1 = i; } } } } int sums = 0, sumr = 0; Console.WriteLine(i1+" " +j1); for (i = 0; i < n; i++) { sums += mas[i, j1]; for (j = 0; j < m; j++) Console.Write(" " + mas[i, j]);
Console.WriteLine(); } for (j=0; j< m; j++) sumr += mas[i1, j]; Console.WriteLine(" Сума рядка=" +sumr); Console.WriteLine(" Сума стовбчика=" +sums); Console.ReadKey(); } } } Задача 12.5. Дано двомірний масив розмірністю N-N, знайти суму рядка і стовпчика на перетинанні яких знаходиться максимальний елемент другорядної діагоналі. using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace _32 { class Program { static void Main(string[] args) { Console.Write(" N="); int n = Int32.Parse(Console.ReadLine()); int m = n; int i = 0, j = 0, i1 = 0, j1 = 0; int[, ] mas = new int[n, m]; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { Console.Write(" [" + (i + 1) + ", " + (j + 1) + " ]="); mas[i, j] = Int32.Parse(Console.ReadLine()); } }
int max = mas[0, 0]; for (i = 1; i < n; i++) { if (max < mas[i - 1, i]) { max = mas[i - 1, i]; i1 = i - 1; j = 1; } } int sums = 0, sumr = 0; Console.WriteLine(i1 + " " + j1); for (i = 0; i < n; i++) { sums += mas[i, j1]; for (j = 0; j < m; j++) Console.Write(" " + mas[i, j]);
Console.WriteLine(); } for (j = 0; j < m; j++) sumr += mas[i1, j]; Console.WriteLine(" Сума рядка=" + sumr); Console.WriteLine(" Сума стовбчика=" + sums); Console.ReadKey(); Console.ReadKey(); } } }
Задача 12.6. Дано двомірний масив розмірністю N-M, перетворити його в одномірний. using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace ConsoleApplication6 { class Program { static void Main(string[] args) { int i = 0, j = 0, k=0; // об’явлення змінних Console.Write(" N="); int n = Int32.Parse(Console.ReadLine()); // введення кількості рядків Console.Write(" М="); int m = Int32.Parse(Console.ReadLine()); // введення кількості стовпців Random r = new Random(); int[, ] mas = new int[n+1, m+1]; // оголошеня масиву int l = 0; l = n * m; int[] mas1 = new int[l+1];
for (i = 0; i < n; i++) // початок циклу роботи з рядками { for (j = 0; j < m; j++) // початок циклу роботи зі стовпцями { mas[i, j] = r.Next(100); } } for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { k++; mas1[k] = mas[i, j]; } }
for (i = 1; i < n*m; i++) Console.Write(mas1[i] + " "); Console.WriteLine(); } } } Задача 12.7. Заповнити двомірний масив N-N по спіралі числами 1.2.3.4.5..
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace ConsoleApplication7 { class Program { static void Main(string[] args) { int i = 0, j = 0; // об’явлення змінних Console.Write(" N="); int n = Int32.Parse(Console.ReadLine()); // введення кількості рядків int[, ] mas = new int[n + 1, n + 1]; // оголошеня масиву int l = 0, k = 0; while (l < n * n) { // заповнення верхнього ряду зліва направо k = k + 1; i = k; for (j = k; j < = n - k + 1; j++) { l = l + 1; mas[i, j] = l; } // заповнення правого стовпця зверху вниз j = n - k + 1; for (i = k + 1; i < = n - k + 1; i++) { l = l + 1; mas[i, j] = l; } // заповнення нижнього ряду зправа наліво i = n - k + 1; for (j = n - k; j > = k; j--) { l = l + 1; mas[i, j] = l; } // заповнення лівого стовпця зверху вниз j = k; for (i = n - k; i > = k + 1; i--) { l = l + 1; mas[i, j] = l; } // вивід заповненого кільця для перевірки for (i = 1; i < = n; i++) { for (j = 1; j < = n; j++) Console.Write(mas[i, j] + " "); Console.WriteLine(); } Console.ReadLine(); } // вивід результату роботи програми for (i = 1; i < = n; i++) { for (j = 1; j < = n; j++) Console.Write(mas[i, j] + " "); Console.WriteLine(); } } } }
Проаналізуйте наведені задачі, перевірте їх працездатність в середовищі програмування.
|