Смекни!
smekni.com

Основы алгоритмизации и программирования 2 (стр. 15 из 32)

Двумерный массив такого вида объявляется следующим образом: <базовыйТип> [,] <имя>;

Описания массивов с большим числом размерностей требуют больше запятых. Например:

<базовыйТип>[,,,] <имя>;

Так объявляется четырехмерный массив.

Для присваивания значений используется аналогичный синтаксис, причем размерности отделяются одна от другой запятыми. Для того чтобы объявить и инициализировать обсуждавшийся выше двумерный массив hillHeight с базовым типом double, размерностью х, равной 3, и размерностью у, равной 4, необходима следующая строка.

double[,] hillHeight = new double[3,4];

В качестве альтернативы при начальном присваивании значений могут использоваться литеральные значения. Для этого воспользуемся вложенными блоками, взятыми в фигурные скобки и разделенными запятыми. Например:

double[,] hillHeight = new {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};

Этот массив имеет точно такие же описания размерностей, что и предыдущий, однако в данном случае значения элементов массива задаются явно.

Для того чтобы получить доступ к отдельным элементам многомерного массива, следует указать индексы этого элемента, разделенные запятыми. Например:

hillHeight[2,l]

Теперь над этим элементом можно выполнять действия так же, как и над другими элементами.

Это выражение позволяет получить доступ ко второму элементу третьего вложенного массива в соответствии с вышеприведенным описанием (в данном случае значение равняется 4). Отсчет начинается с 0 и что первая цифра относится к вложенному массиву, т.е. первая цифра определяет номер пары фигурных скобок, а вторая цифра определяет соответствующий элемент внутри этой пары фигурных скобок.

Цикл foreach позволяет осуществлять доступ ко всем элементам многомерных массивов так же, как и в случае одномерных. Например:

double [,] hillHeight = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};
foreach (double height in hillHeight)
Console.WriteLine("{0}", height); )

{

Элементы этого массива будут выводиться в том же порядке, в котором происходило присваивание им литеральных значений: hillHeight[0,0], hillHeight[0,1], hillHeight[0,2], hillHeight[0,3], hillHeight[1,0], hillHeight[1,1], hillHeight[1,2] и т д.

3.2.7.Массивы массивов

Многомерные массивы, обсуждавшиеся в предшествующем разделе, обычно называются прямоугольными, поскольку у них каждая "строка" имеет один и тот же размер. Если использовать предыдущий пример, то координата у может изменяться от 0 до 2 для любой координаты х.

Однако существует возможность использовать ступенчатых (jagged) массивов, у которых "строки" могут быть неодинакового размера. Для этого требуется массив, каждым элементом которого также является массив. При желании можно использовать массивы массивов массивов и даже более сложные конструкции. Однако это оказывается возможным только в том случае, если все массивы имеют один и тот же базовый тип.

Синтаксис, применяемый для объявления массивов массивов, подразумевает использование в объявлении массива нескольких пар квадратных скобок, например

int[ ] [ ] jaggedIntArray;

К сожалению, инициализация подобных массивов оказывается не таким простым делом, как инициализация многомерных массивов Так, например, мы не имеем возможности использовать вслед за этим объявлением следующую запись jaggedIntArray = new int[3] [4];

Но даже в том случае, если бы мы могли применять запись такого вида, вряд ли от этого была бы какая-нибудь польза, поскольку в случае многомерных массивов точно такого же эффекта можно достичь с меньшими затратами.

Следующий код также является недопустимым

jaggedIntArray = {{1, 2, 3}, {1}, {1, 2}};

На самом деле существуют две возможности. Можно сначала инициализировать массив, содержащий другие массивы (чтобы избежать путаницы, мы будем называть вложенные массивы субмассивами), а затем, в свою очередь, инициализировать эти субмассивы: jaggedIntArray = new int[2] []; jaggedIntArray [0] = new int[3]; jaggedIntArray [1] = new int[4];

Можно также воспользоваться видоизмененной формой приведенного выше литерального присваивания jaggedIntArray = {new int[] {1, 2, 3}, new int[] {1}, new int[] {1, 2}};

Для таких неоднородных массивов можно использовать циклы foreach, однако чаще всего вложенные циклы применяются для того, чтобы получить доступ к реальным данным. Например, допустим, что имеется следующий неоднородный массив, который включает в себя десять других массивов, каждый из которых содержит целые значения, являющиеся делителями целых чисел из диапазона от 1 до 10 int[][] divisors1Tol0 = {new int[] {1}, new int [] {1, 2}, new int[] {1, 3}, new int [] {1, 2, 4}, new int[] {1, 5}, new int[] {1, 2, 3, 6}, new int[] {1, 7}, new int [ ] {1, 2, 4, 8}, new int[] {1, 3, 9},

new int[] {1, 2, 5, 10}},

foreach (int divisor in divisors1To10) {
Console.WriteLine(divisor); }

Использование следующего кода является недопустимым, поскольку divisorslTol0 содержит в себе не элементы int, а элементы int [ ] Поэтому нам придется проходить не только по самому массиву, но и непосредственно по каждому субмассиву:

foreach (int[] divisors1To10 in divisors1Tol0) { foreach (int divisor in divisors1To10)

{

Console.WriteLine(divisor); } }

При использовании неоднородных массивов синтаксис очень быстро становится сложным. В большинстве случаев оказывается проще использовать либо прямоугольные массивы, либо какой-нибудь другой, более простой способ хранения данных.

3.2.8.Действия над строками

До сих пор все наши операции над строками сводились к выводу строк на консоль, чтению строк с консоли и объединению строк посредством оператора +. Переменная типа string – это всего лишь массив переменных типа char, доступных в режиме "только чтение". Иными словами, можно получить доступ к отдельным символам строки следующим образом:

string myString = "A string";
cnar myChar = myString[l] ;

Однако присваивать отдельные символы таким способом нельзя.

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

string myString = "A string";

char [ ] myChars = myStrrig.ToCharArray();

Теперь можно выполнять манипуляции с массивом типа char обычным путем. Строки могут использоваться и в циклах foreach:

foreach (char character m myString) {

Console WriteLine("{0}" , character);

}

Как и в случае других массивов имеется возможность узнать число элементов с помощью myString.Length. Таким же образом можно определить общее количество символов в строке:

string myString = Console.ReadLine() ;
Console.WriteLine("You typed {0} characters.", myString.Length);

Другим основополагающим способом работы со строками является использование команд в формате, аналогичном формату команды <string>ToCharArray(). Существуют две простые, но очень полезные команды <stnng>.ToLower() и <string>.ToUpper(). Они позволяют переводить всю строку целиком в нижний и верхний регистр соответственно. Они могут быть использованы, например, в поступлении от пользователя какого-то ответа, например, строки "yes". Если перевести всю введенную строку в нижний регистр, то можно воспринять и такие строки, как "YES", "Yes", "yeS" и т д.

string userResponse = Console.ReadLine() , if (userResponse.ToLower() == "yes") {

// выполнение действий в случае получения ответа }

Эта команда, как и другие рассматриваемые в данной лекции команды, на самом деле не изменяет ту строку, к которой применяется. Напротив, использование этой команды для некоторой строки приводит к созданию новой строки, которую можно сравнить с какой-либо другой строкой (как показано выше) или присвоить другой переменной. В роли этой переменной может выступать переменная, над которой выполняется данная операция:

userResponse = userResponse.ToLower();

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

<string>.Trim().

string userResponse = Console ReadLine(); userResponse = userResponse Trim(); if (userResponse ToLower() = = “yes”) {

// выполнение действий в случае получения ответа. }

В этом случае можно определить строки, подобные следующим: "YES" "Yes".

Такая же команда может быть использована для удаления любых других символов, которые задаются с помощью массива типа char, например:

char[] trimChars ={' ', 'е', 's'};

string userResponse = Console.ReadLine (); userResponse = userResponse.ToLower(); userResponse = userResponse Trim(trimChars); if {userResponse = = "y") {

// выполнение действий в случае получения ответа }

Это позволяет удалить все пробелы, символы "е" и символы "s", находящиеся в начале или в конце строки. Если предположить, что в строке отсутствуют какие-либо другие символы, то появится возможность определять строки: "Yeeeees" " У" и им подобные.

Существует также возможность использовать команды <string>.TrimStart() и <string>.TrimEnd(), которые будут удалять пробелы только из начала или только из конца строки соответственно. В этих командах также имеется возможность задания массива типа char удаляемых символов.

Имеются еще две команды работы со строками, которые выполняют манипуляции с пробелами внутри строк <string>.PadLeft() и <string>.PadRight () эти команды позволяют дополнять строки пробелами слева или справа до заданной длины строки. Они могут использоваться следующим образом:

<string>. PadX (<требуемаяДлина>); Например:

myString = "Aligned";
mуString = myString. PadLeft (10)

;

В результате к слову "Aligned", содержащемуся в переменной myString, будут добавлены три пробела слева. Этот метод может оказаться полезным для выравнивания строк, располагаемых одна над другой, в частности, при расположении строк с номерами