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

Laboratornyy_praktikum_Programmirovanie_na_C

.pdf
Скачиваний:
42
Добавлен:
02.02.2015
Размер:
1.93 Mб
Скачать

n 1

сумму mi , где i – счѐтчик цикла, 0 – начальное значение, n – размер массива, (n –

i 0

1)– индекс последнего элемента. В программе P08_4 демонстрируется создание одномерного целого массива (т.е. все элементы целого типа) из десяти элементов, заполнение его случайными числами в диапазоне 0..9, и вычисление суммы значений его элементов. Сумма вычисляется в целой переменной sum, которая инициализирована в ноль. Число инициализации выбирается таким, чтобы проведение с ним операции не искажало результат. Таким образом, при вычислении суммы присваивают ноль, т.к. суммирование с нулѐм не меняет результат, также при вычислении произведения переменной накопления присваивают единицу, т.к. умножение на неѐ также не исказит результат. В цикле последовательно перебирают необходимые элементы массива, выполняя между ними и переменной накопления необходимые операции (суммирование или умножение). Рекомендуется описать размер массива с помощью констант, это позволит применять эти константы в операциях над массивами, что в свою очередь позволит быстро и без ошибок изменить размер массива (при этом изменение константы также повлияет на количество итераций в цикле). Обратите внимание, что индексация массивов начинается с нуля, поэтому индекс последнего элемента будет на единицу меньше количества элементов.

using System; class P08_4 {

static void Main() {

//Описание целочисленного массива из 5 элементов const int n = 5;

int[] m = new int[n];

//Инициализация экземпляра rnd генератора случайных чисел

Random rnd = new Random();

//Инициализация переменной накопления суммы int sum = 0;

//Цикл от 0 до n-1 включительно, счётчик цикла i for (int i = 0; i < n; i++) {

//Присваивание m[i] случайного числа в диапазоне 0..9 m[i] = rnd.Next(1, 10);

//Вывод очередного элемента массива на экран в строку

Console.Write("m[{0}]={1}, ",i, m[i]);

//Добавление (накопление) очередного значения в сумму sum += m[i];

}

//С новой строки вывод суммы элементов массива

Console.WriteLine("\b\b \nСумма элементов массива = " + sum);

}

}

91

Следует напомнить, что символ "\b" (back) в строке форматирования используется для возврата на один символ. В программе P08_4 вывод каждого элемента массива завершается разделяющими элементы запятой и пробелом. Возврат на два символа назад и вывод пробела позволяет затереть последнюю ненужную запятую, вместо того, чтобы усложнять программу условными операторами. Этот приѐм может не сработать, если был произведѐн переход на новую строку.

Среднее арифметическое вычисляется как частное суммы элементов и их

n

количества: 2 mi n2 n1 1 . Если среднее арифметическое вычисляется для

i n1

всего массива, то количество элементов совпадает с общим количеством элементов, которое хранится в свойстве экземпляра массива Length. Если вычисляется среднее арифметическое части элементов массива, то количество можно рассчитать или ввести дополнительный счѐтчик количества операций с приращением в цикле. При проведении операций над частью массива может потребоваться использование дополнительного цикла или условного оператора, что демонстрируют варианты программы P08_5. Так как среднее арифметическое чаще всего дробное число, операция деления требует произвести преобразование типов к double.

Использование условного оператора:

using System; class P08_5 {

static void Main() { const int n = 8; int[] m = new int[n];

Random rnd = new Random(); int sum = 0;

//Инициализация счётчика количества элементов int num = 0;

//Задание начального и конечного индексов диапазона const int n1 = 3; const int n2 = 6;

for (int i = 0; i < n; i++) { m[i] = rnd.Next(1, 10);

Console.Write("m[{0}]={1}, ", i, m[i]); if (n1 <= i && i <= n2) {

sum += m[i]; num++;

}

}

Console.WriteLine("\b\b \nСреднее арифметическое " + "для элементов диапазона {0}..{1} = {2}",

n1, n2, (double) sum / (double) num);

}

}

Использование второго оператора цикла:

92

using System; class P08_5 {

static void Main() { const int n = 8; int[] m = new int[n];

Random rnd = new Random(); int sum = 0; int num = 0;

const int n1 = 3; const int n2 = 6; for (int i = 0; i < n; i++) {

m[i] = rnd.Next(1, 10); Console.Write("m[{0}]={1}, ", i, m[i]);

}

for (int i = n1; i <= n2; i++) { sum += m[i]; num++;

}

Console.WriteLine("\b\b \nСреднее арифметическое " + "для элементов диапазона {0}..{1} = {2}",

n1, n2, (double) sum / (double) num);

}

}

Аналогично сумме вычисляется произведение элементов массива, которое

n

2

обозначается в математических документах как mi . Помните, что при

i n1

вычислении произведения переменная накопления инициализируется в единицу (программа P08_6).

using System; class P08_6 {

static void Main() { const int n = 6; int[] m = new int[n];

Random rnd = new Random(); int pr = 1;

const int n1 = 2; const int n2 = 4; for (int i = 0; i < n; i++) {

m[i] = rnd.Next(1, 10); Console.Write("m[{0}]={1}, ", i, m[i]);

}

for (int i = n1; i <= n2; i++) pr *= m[i]; Console.WriteLine("\b\b \nПроизведение для элементов "+

"диапазона {0}..{1} = {2}", n1, n2, pr);

}

}

93

8.2.1. Задача. Среднее арифметическое

Написать программу P08_7, в которой вычислить среднее арифметическое всех элементов целого массива из пяти элементов, заполненного случайными числами в диапазоне –9..9.

8.2.2. Задача.

Написать программу P08_8, в которой вывести с точностью до четырѐх знаков частное суммы и произведения (Σaiai) всех элементов целого массива из пяти элементов, заполненного случайными числами в диапазоне 1..9.

8.3. МНОГОМЕРНЫЕ МАССИВЫ

Из многомерных массивов, чаще всего используются двумерные массивы, ассоциирующиеся с таблицей данных. Трѐхмерные массивы часто представляют как кубик из ячеек, а представление массивов большей размерности может вызывать затруднения. Это происходит потому, что мерность массивов отождествляется с мерностью пространства. На самом деле мерность массивов абстрактна и используется для более удобного преставления структуры данных, которые представлены в памяти линейно (одномерным массивом), и адрес элемента вычисляется с использованием значений индексов и размера каждой мерности, т.к. размер массива в любой мерности массива конечен. Для наглядности рассмотрите следующее представление мерности массива. Строку клеток листа тетради в клеточку можно воспринимать как одномерный массив. В каждую пронумерованную клетку можно записать значения и обращаться позже к ним по индексу. Следует помнить, что в математике одномерный массив записывается как вектор в виде столбца. Страница тетради в клеточку может восприниматься как двумерный массив, к элементам которого можно обращаться по номеру строки и столбца. Если мы пронумеруем страницы, то получим трѐхмерный массив, к элементам которого можно обращаться по номеру страницы, строки и столбца. Необходимо отметить, что количество столбцов в строке, строк на странице совпадают для всех страниц, даже если не все из них используются и некоторые остаются пустыми. Если продолжить, пачка то пронумерованных идентичных по размеру тетрадей группы может восприниматься как четырѐхмерный массив. Набор одинаковых по количеству упаковок тетрадей групп одного факультета можно воспринимать как пятимерный массив. Для целого университета набор контейнеров одного размера, содержащих тетради факультетов можно воспринимать как шестимерный массив. Нумерованные вагоны одинакового объема, содержащие тетради различных университетов можно воспринимать как семимерный массив. Абстракцию можно продолжить далее на регионы, страны, континенты, планеты, звѐздные системы, галактики, вселенные и далее, насколько хватит фантазии и памяти ваших компьютеров. Но в любом случае размер любой мерности многомерного массива будет конечным.

94

Рисунок 8.2. Линейное расположение в памяти элементов двумерного массива

Рассмотрите вывод формулы, определяющей смещение элемента Аi,j в памяти для двумерного массива A с количеством строк n = 3 и столбцов m = 3 (Рис. 8.2), где i

– номер строки, j – номер столбца. Нумерация элементов начинается с нуля. Произведение номера строки на еѐ ѐмкость (количество столбцов) даѐт общее количество элементов до указанной строки. Добавление номера столбца даѐт общее смещение l в линейном массиве: l = i · m + j. Для элемента A2,0 , содержащего семѐрку, значение смещения будет l = 2 · 3 + 0 = 6, т.к. счѐт начинается с нуля, это седьмой элемент. Аналогично, с учѐтом количества строк на странице и номера страницы вычисляется линейное смещение элемента для трѐхмерного массива.

З д ч : Самостоятельно выведите, запишите в лабораторный журнал и покажите преподавателю выведенную формулу l для элемента Ap,i,j, где p – номер страницы, количество на странице строк n и столбцов m.

В случае необходимости инициализации при описании многомерного массива, в фигурные скобки заключается список инициализаторов каждого его размера, ниже приведѐн фрагмент кода для матрицы 3×3:

int[,] A = {{1, 2, 3}, {4, 5, 6,}, {7, 8, 9}};

У многомерных массивов свойство Length возвращает общее количество элементов в массиве.

Сумму всех элементов двумерного массива записывают как A или с

n 1 m 1

указанием индекса строк и столбцов Ai, j . В записи заданы два цикла –

i 0 j 0

внешний и внутренний. Внутренний цикл считает суммы элементов строк, внешний – суммирует их в общую сумму (P08_9).

using System; class P08_9 {

static void Main() { const int n = 5;

int[,] A = new int[n,n]; Random rnd = new Random(); int sum = 0;

for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) {

sum += A[i,j] = rnd.Next(1, 10);

95

Console.Write("A[{0},{1}]={2}, ", i, j, A[i,j]);

}

Console.WriteLine("\b\b ");

}

Console.WriteLine("Сумма элементов A = " + sum);

}

}

Внутри цикла приведѐн тандем операторов: генерируемое случайное число присваивается очередному элементу массива, который в свою очередь добавляется к значению накопительной переменной суммы. При работе с квадратными матрицами возникает необходимость адресации ячеек относительно диагоналей. Главная диагональ определяется элементами, индексы строк и столбов которых равны (i == j). Соответственно условие расположения элемента ниже главной диагонали можно

записать как (i < j). а выше как (i > j).

 

 

 

 

A

0

1

2

3

0

 

1

2

3

4

1

 

5

6

7

8

2

 

9

0

1

2

3

 

3

4

5

6

Для приведѐнной выше матрицы A элементами главной диагонали являются A0,0, A1,1, A2,2 и A3,3 (значения 1, 6, 1, 6). Исходя из этой же матрицы, элементами побочной диагонали являются A0,3, A1,2, A2,1 и A3,0. Отсюда видно, что индекс строк увеличивается, а индекс столбцов уменьшается. В квадратной матрице n×n любую строку, столбец или диагональ можно воспринимать как вектор (одномерный массив) размером n. Для описания расположения элементов на побочной диагонали можно привести условие (i == n j – 1). Пример программы P08_10 демонстрирует создание и вывод векторов из диагоналей матрицы и вычисление их сумм. Для удобства цветом выводятся номера строк и столбцов матрицы.

using System; class P08_10 {

static void Main() { const int n = 5;

int[,] A = new int[n,n]; int[] C = new int[n]; int[] S = new int[n]; Random rnd = new Random(); int sumC = 0, sumS = 0;

Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(" 0 1 2 3 4");

for (int i = 0; i < n; i++) { Console.ForegroundColor = ConsoleColor.Green; Console.Write(i);

for (int j = 0; j < n; j++) { A[i,j] = rnd.Next(1, 10);

Console.ForegroundColor = ConsoleColor.Gray;

96

Console.Write(" " + A[i,j]);

if (i == j) sumC += C[i] = A[i, j];

if (i == n - j - 1) sumS += S[i] = A[i, j];

}

Console.WriteLine();

}

Console.Write("\nЭлементы главной диагонали :");

for (int i = 0; i < n; i++) Console.Write(" "+C[i]); Console.WriteLine("\nСумма элементов главной диагонали : "

+ sumC);

Console.Write("\nЭлементы побочной диагонали :");

for (int i = 0; i < n; i++) Console.Write(" " + S[i]); Console.WriteLine("\nСумма элементов побочной диагонали : "

+ sumS);

}

}

8.3.1. Задача. Среднее арифметическое области матрицы

Написать программу P08_11, в которой создать и заполнить случайными значениями в диапазоне 0..9 квадратную матрицу размером n = 4, вычислить и вывести на консоль среднее арифметическое элементов, расположенных выше побочной диагонали.

8.3.2. Задача. Диагонали матрицы

Написать программу P08_12, в которой создать и заполнить случайными значениями в диапазоне 0..9 квадратную матрицу, размер стороны матрицы n ввести с клавиатуры, вычислить и вывести на консоль среднее арифметическое диагоналей матрицы. Учесть, что при нечѐтном значении n центральный элемент принадлежит обеим диагоналям.

8.4. СТУПЕНЧАТЫЕ МАССИВЫ

Двумерные массивы являются прямоугольными, и длина всех строк одинакова во всѐм массиве. Прямоугольный массив соответствует таблице. В C# можно создать специальный тип двумерного массива, именуемый ступенчатым массивом. Ступенчатый массив представляет собой массив массивов, в котором размер каждого вложенного массива может быть разной. Переменная с именем массива хранит ссылку на одномерный массив, каждый элемент которого в свою очередь хранит ссылки на вложенные массивы. Поэтому каждый из этих массивов должен инициализироваться отдельно. Форма записи:

тип[][] имя_массива = new тип[размер][];

Пример программы P08_13 иллюстрирует работу со ступенчатыми массивами:

using System; class P08_13 {

static void Main() {

97

const int n = 7;

int[][] A = new int[n][]; Random rnd = new Random();

//Заполнение массива значениями for (int i = 0; i < n; i++) {

//Инициализация очередной строки массива

A[i] = new int[rnd.Next(5,10)];

for (int j = 0; j < A[i].Length; j++) {

//Заполнение значениями элементов массива

A[i][j] = rnd.Next(1, 10); Console.Write(" " + A[i][j]);

}

Console.WriteLine();

}

}

}

У ступенчатых массивов свойство Length возвращает размеры массивов каждого уровня.

8.5. ОПЕРАТОР ЦИКЛА FOREACH

Оператор цикла foreach повторяет группу вложенных операторов для каждого элемента массива или коллекции объектов. Оператор foreach используется для итерации коллекции с целью получения необходимой информации, однако его не следует использовать для добавления или удаления элементов исходной коллекции во избежание непредвиденных побочных эффектов. Если нужно добавить или удалить элементы исходной коллекции, следует использовать цикл for. Т.е. считываемые элементы используются в режиме «для чтения», например, для вычисления суммы

(программа P08_14), что максимально соответствует записи A.

using System; class P08_14 {

static void Main() { const int n = 4;

int[,] A = new int[n,n]; Random rnd = new Random(); int sum = 0;

//Заполнение массива значениями for (int i = 0; i < n; i++) {

for (int j = 0; j < n; j++) { A[i,j] = rnd.Next(1, 10); Console.Write(" " + A[i,j]);

}

Console.WriteLine();

}

98

foreach (int k in A) sum += k; Console.WriteLine("\nСумма элементов массива : " + sum);

}

}

8.6. ВОЗВРАТ МАССИВА ИЗ МЕТОДА

Ранее рассматривались методы и возврат значений из методов оператором return. В качестве типа метода нужно указать тип массива, создать и заполнить массив внутри метода, затем указать переменную массива оператору return. В место вызова будет возвращена ссылка на массив, созданный внутри метода.

Покажите результаты работы преподавателю, закройте Visual Studio, а затем

уд л т с со д нны м о р мя р боты ф йлы п пк в папке

D:\Program\VS.

Вопросы к под ото к :

1.Что такое массивы и для чего они применяются?

2.Какие виды массивов вы знаете?

3.Как создать массив?

4.Как обратиться к отдельному элементу массива?

5.Чем отличаются алгоритмы вычисления суммы и произведения элементов массива?

6.Чем отличаются алгоритмы обработки одномерного и двумерного массива?

7.Как определить, расположен ли элемент на диагонали матрицы?

99

ЛАБОРАТОРНАЯ РАБОТА 9. СТРОКИ

Цель работы: Научиться работать со строками, рассмотреть связанные с ними основные алгоритмы и методы. Программы работы записать (вклеить распечатку) с пояснениями в лабораторный журнал.

9.1.СТРОКИ

Впрограммах строки играют важную роль. В строках формируется понятная пользователю текстовая информация. Строки содержат шаблоны форматирования результатов вычислений. Выводом строк можно манипулировать и направлять его на различные устройства: на экран, на принтер, записывать в файлы. Со строками выполняют следующие операции: клонирование, объединение/вставка, усечение/удаление, извлечение подстроки, изменение регистра символов, поиск подстроки и т.д.

ВC# строки, как и массивы, являются объектами, поэтому строковый тип – ссылочный. Переменная, ссылающаяся на экземпляр строки, может изменяться, присваивая ссылку на новый объект. Сам экземпляр строки меняться н мож т (правило постоянства строк). Операции, манипулирующие строками, создают новые строковые объекты и возвращают ссылки на них. Старые экземпляры теряются и автоматически утилизируются при «сборке мусора» в оперативной памяти механизмами .NET Framework. Для сравнения, Pascal воспринимает строку как массив символов, которые можно читать и записывать отдельно непосредственно в памяти, выделенной для хранения строки. В C# к отдельным символам строки также можно обратиться по индексу (нумерация с нуля), указанному в квадратных скобках, как к элементу символьного массива char[], но в режиме только чтения (описывается свойством класса Chars).

Чаще всего строки инициализируются строковыми литералами (набор символов, заключѐнный в двойные кавычки), в этом случае оператор new необязателен, как и в случае инициализации массивов константами. Строки также можно инициализировать с помощью конструкторов (отсутствует конструктор по умолчанию, возвращающий пустую строку, т.к. можно просто присвоить ""). При вызове конструктора, создающего экземпляр строки и возвращающего ссылку на него, используется (как и для других объектов) оператор new. Конструкторы могут инициализировать содержимым символьного массива, указанным числом символов (см. справку). Строковую переменную можно также инициализировать, присвоив ссылку, сгенерированную методом уже существующей строки.

При инициализации экземпляра строки вычисляется доступное для чтения в программе свойство Length, содержащее количество символов в строке. Это свойство удобно применять в цикле для перебора символов, составляющих строку. Необходимо помнить, что нумерация символов строки начинается с нуля, поэтому значение Length на единицу больше индекса последнего элемента.

Пример фрагмента программы инициализации строк:

char[] c = { 'И','н','ф','о','р','м','а','т','и','к','а' }; string s1 = "Курс обучения: ";

100

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