
Laboratornyy_praktikum_Programmirovanie_na_C
.pdfstring s2 = new String(c); string s3 = new String('-', 80); Console.WriteLine(s1 + s2);
Console.WriteLine("В слове {0} {1} символов", s2, s2.Length); Console.WriteLine(s3);
В приведѐнном выше примере инициализируется три строки, первая – строковым литералом, вторая – конструктором из массива символов, третья – конструктором последовательностью указанного символа в указанном количестве. С помощью свойства Length определяется длина строки.
Наиболее часто используемые методы класса string: Clone – возвращает ссылку на данный экземпляр.
Compare – сравнивает две строки, возвращает отрицательное значение, если первая строка меньше второй, положительное, если больше и ноль, если строки равны. В дополнительных параметрах можно указать режим сравнения (см. справку).
Concat – объединяет строки.
Contains – возвращает true, если строка содержит указанную подстроку. Copy – создаѐт новый экземпляр строки с копией содержимого.
EndsWith – возвращает true, если указанная подстрока совпадает с концом строки.
Equals – возвращает true, если строки равны.
Format – заменяет один или более элементов формата в указанной строке строковым представлением соответствующего объекта. Формат задаѐтся аналогично строке формата оператора WriteLine, что рассматривалось ранее.
IndexOf – выполняет поиск подстроки с указанной позиции и возвращает первый индекс вхождения.
Insert – вставляет одну строку в другую по указанному смещению. LastIndexOf – возвращает индекс последнего вхождения подстроки в строке.
PadLeft, PadRight – возвращают новую строку, в которой знаки данного экземпляра выровнены по правому (левому) краю путем добавления слева (справа) пробелов или указанного знака Юникода до указанной общей длины.
Remove – удаляет подстроку из строки.
Replace – заменяет все вхождения подстроки в строке на указанное значение. Split – возвращает строковый массив, содержащий подстроки данной строки,
разделенные указанными символами.
StartsWith – возвращает true, если указанная подстрока совпадает с началом текущей строки.
Substring – извлекает подстроку.
ToCharArray – копирует строку в символьный массив.
ToLower – возвращает копию строки с переведенными в нижний регистр символами.
ToUpper – возвращает копию строки с переведенными в верхний регистр символами.
Trim – удаляет начальные и конечные пробелы или другие указанные символы в строке.
101
TrimEnd, TrimStart – удаляет все конечные (начальные) вхождения набора знаков, заданного в виде массива, из текущей строки.
9.2. ОПЕРАЦИИ СО СТРОКАМИ
Рассмотрите пример программы P09_1:
using System; class P09_1 {
static void Main() {
string s1 = "Курс обучения - Информатика";
string s2 = "формат", s3 = s1, s4 = String.Copy(s1); string s5 = new String('-', 80); Console.WriteLine("Строка:\t\t"+s1); Console.WriteLine("Длина строки:\t" + s1.Length); Console.WriteLine("Все строчные:\t" + s1.ToLower()); Console.WriteLine("Все прописные:\t"+ s1.ToUpper()); Console.WriteLine("Сравнение:\t" + String.Compare(s1, s2)); Console.WriteLine("В строке {1}содержится подстрока "+
"\"{0}\"", s2, s1.Contains(s2) ? "":"не "); Console.WriteLine("С позиции:\t" + s1.IndexOf(s2)); Console.WriteLine("Замена:\t\t" + s1.Replace(s2,"женер")); Console.WriteLine("Подстрока:\t" + s1.Substring(18, 5)); Console.WriteLine("Удаление:\t" + s1.Remove(4, 9)); Console.WriteLine("Вставка:\t" + s1.Insert(0, "1 ")); Console.WriteLine(s5);
}
}
Строки s1 и s2 инициализируется с помощью строкового литерала, строковая переменная s3 ссылается на строку s1, строка s4 образована копией s1, но является отдельным экземпляром. Строка s5 образована набором символов. В программе выводятся последовательно: исходная строка, еѐ длина, строка со всеми строчными, а затем прописными символами, результаты сравнения и поиска, замена подстроки на другую, удаление части, вставка строки.
9.2.1. Задача. Замена подстроки
Написать программу P09_2, в которой описать и инициализировать строковым литералом "Курс обучения - Информатика" строку s1. Записать выражение, которое преобразует исходную строку к виду "Новое направление обучения - Информатика". Результат вывести на консоль.
9.2.2.Конвейерная передача результата
Впримере P09_3 демонстрируется замена символов, для экземпляра строки s1 вызывается метод Replace, т.к. результатом работы метода является строка, то для неѐ также можно вызвать метод Replace. Таким образом результаты обработки передаются далее по конвейеру:
102
using System; class P09_3 {
static void Main() {
Console.Write("Введите предложение: "); string s1 = Console.ReadLine();
Console.WriteLine(s1.Replace('е','ё').Replace('о','а'));
}
}
9.2.3.Посимвольный перебор
Впримере P09_4 демонстрируется подсчѐт гласных букв. Задан символьный массив c1, содержащий гласные буквы, строка s1 перебирается посимвольно в цикле до длины строки, обращаясь к элементам строки по индексу. Каждый символ во вложенном цикле по очереди сравнивается с элементами массива гласных букв. В случае сравнения значение счѐтчика num увеличивается и внутренний цикл прерывается оператором break для исключения бессмысленного продолжения цикла, т.к. сравнение уже выполнено успешно и совпадений далее быть не может. Для поиска в любом регистре используется нижний регистр.
using System; class P09_4 {
static void Main() {
Console.Write("Введите предложение: "); string s1 = Console.ReadLine();
char[] c1 = { 'ё', 'у', 'е', 'ы', 'а', 'о', 'э', 'я', 'и', 'ю' };
int num = 0;
for (int i = 0; i < s1.Length; i++)
{
char c0 = Char.ToLower(s1[i]);
for (int j = 0; j < c1.Length; j++)
{
if (c0==c1[j])
{
num++; break;
}
}
}
Console.WriteLine("Гласных символов: "+num);
}
}
103
9.2.4. Использование шаблона
Вы рассматривали форматированный вывод, в котором используется шаблон форматирования и набор параметров. Аналогично можно создать строку, которую можно использовать для вывода в форму, файл и др.
using System; class P09_5 {
static string SH(DateTime d)
{
int h = d.Hour % 10;
if (h > 4 || h==0) return "часов"; else if (h == 1) return "час"; else return "часа";
}
static string SM(DateTime d)
{
int m = d.Minute % 10;
if (m > 4 || m == 0) return "минут"; else if (m == 1) return "минута"; else return "минуты";
}
static void Main()
{
string format = "Текущее время: {0:HH} {1} {0:mm} {2}"; var d1 = DateTime.Now;
string s1 = String.Format(format, d1, SH(d1), SM(d1)); Console.WriteLine(s1);
}
}
Спомощью шаблона представления в программе создаѐтся строка s1, в которую
спомощью строки формата вводится значение текущего времени с учѐтом склонения слов, вычисляемого в отдельных методах.
9.2.5. Разбор командной строки
9.3. ПРОГРАММИРОВАНИЕ
9.3.1. Задача. Реверс строки
Написать программу P09_6, преобразующую введѐнную с клавиатуры строку в обратном порядке (первый символ становится последним, последний – первым и т.д.). Вывести результат на консоль.
104
9.3.2. Задача. Поиск количества слов
Написать программу P09_7, в которой ввести строку с клавиатуры, затем ввести слово с клавиатуры, вычислить количество вхождений заданного слова в строке. Вывести результат на консоль.
9.3.3. Задача. Поиск количества слов в предложении
Написать программу P09_8, в которой ввести строку с клавиатуры, вычислить количество слов, разделѐнных пробелом. Вывести результат на консоль.
9.3.4. Задача. Поиск количества слов в предложении 2*
Написать программу P09_9, в которой ввести строку с клавиатуры, вычислить количество слов, разделѐнных пробелом и знаками препинания. Разделяющие символы могут располагаться подряд, в начале и в конце строки. Вывести результат на консоль.
9.3.5. Задача. Поиск количества слов в предложении 3*
Написать программу P09_10, в которой ввести строку с клавиатуры, вычислить количество слов, первая и последняя буква которых совпадают (без учѐта регистра). Разделяющие символы могут располагаться подряд, в начале и в конце строки. Вывести результат на консоль.
9.3.6. Задача. Поиск самого короткого и длинного слова*
Написать программу P09_11, в которой ввести строку с клавиатуры. Найти самое короткое и самое длинное слово. Разделяющие символы могут располагаться подряд, в начале и в конце строки. Вывести результат на консоль.
9.3.7. Задача. Поиск количества предложений*
Написать программу P09_12, в которой ввести строку с клавиатуры, вычислить количество предложений. Предложения разделяются точками, восклицательными и вопросительными знаками. Знаки могут комбинироваться ?!, !!! и т.д. Вывести результат на консоль.
9.3.8. Задача. Удаление лишних пробелов
Написать программу P09_13, в которой ввести строку с клавиатуры. Удалить из строки, идущие между слов подряд пробелы, оставив по одному. Лидирующие и завершающие строку пробелы также удалить. Вывести результат на консоль.
9.3.9. Задача. Преобразование числа в текст*
Написать программу P09_14, преобразующую введѐнное с клавиатуры целое число (Int32) в строку текста (словами) и выводящую еѐ на консоль.
9.3.10. Задача. Преобразование числа в текст 2*
Модифицировать предыдущую программу, создав новую P09_15, которая преобразует введѐнное с клавиатуры число двойной точности (с точностью до двух знаков после запятой) в текстовую денежную запись. После целой части поместить « грн.». Дробную часть с точностью до двух знаков добавить в числовом виде и поместить после неѐ « коп.». Для исключения подделок (дописывания слов спереди)
105
первый символ полученной строки должен быть прописным (заглавным), остальные символы – строчными. Выведите полученную строку на консоль.
9.3.11. Задача. Преобразование числа в текст 3**
Написать программу P09_16, преобразующую строку текста, содержащую денежную сумму (полученную в предыдущей задаче, или в результате сканирования и распознавания документа), в число. Вывести полученное число на консоль.
Покажите результаты работы преподавателю, закройте Visual Studio, а затем
уд л т с со д нны м о р мя р боты ф йлы п пк в папке
D:\Program\VS.
Вопросы к под ото к :
1.Для чего используются строки?
2.Как определить длину строки?
3.Как преобразовать строчные символы в строке в прописные?
4.Как прочитать определѐнный символ в строке?
106
ЛАБОРАТОРНАЯ РАБОТА 10. СТРУКТУРЫ, ПЕРЕЧИСЛЕНИЯ
Цель работы: Рассмотреть структуры и перечисления, связанные с ними основные алгоритмы. Программы работы записать (вклеить распечатку) с пояснениями в лабораторный журнал.
10.1.СТРУКТУРЫ
Вязыке C# есть типы данных – структуры, похожие на классы, доступ к которым осуществляется непосредственно (как к простым типам значений), а не по ссылке (как к экземплярам классов, массивам и строкам). Структура описывается служебным словом struct. Структуры, как и все типы данных наследуют класс object. Структуры:
копируются при присваивании;
не могут наследовать в другие структуры и классы;
могут содержать методы, поля, индексаторы, свойства, операторные методы и события;
допускают использование конструкторов, используемых для инициализации данных, но не конструкторы по умолчанию (без параметров), конструктор по умолчанию определяется автоматически, и его нельзя изменить;
позволяют использовать вызов конструктора с оператором new для инициализации, без вызова конструктора объект создаѐтся, но его нужно инициализировать вручную;
допускают значение NULL.
Структуры можно использовать вместо простых классов, не требующих наследования. Довольно часто структуры применяют без методов для хранения данных, аналогично записям в других языках программирования. Запись – именованный набор разнотипных данных, называемых полями, доступ к которым осуществляется по имени поля, отделѐнного от имени переменной (экземпляра) структуры точкой. Удобство использования записей (структур) обусловлено тем, что такой набор данных соответствует полям заполняемых бланков и является кортежем (строкой таблицы, набором атрибутов, экземпляром сущности) при использовании в базах данных. Для использования доступа к полям снаружи структуры, члены структуры необходимо описывать с модификатором доступа public. Структуры можно организовывать в массивы и коллекции.
using System; struct Stud
{
public string Name, Group, Addr, PhoneNum; public DateTime BirthDate, EntryDate; public double CurrentAverageScore;
public Stud(string n, string g, string a, string p, DateTime b, DateTime e, double c) {
Name = n; Group = g; Addr = a;
107
PhoneNum = p; BirthDate = b;
EntryDate = e; CurrentAverageScore = c;
}
}
class P10_1
{
static void Main()
{
Stud[] X = new Stud[30];
X[0].Name = "Сидоров Петр Иванович"; X[0].Group = "ИТ-41";
X[0].BirthDate = new DateTime(1992, 9, 1); Console.WriteLine(X[0].Group);
DateTime TD = DateTime.Today;
int Y = TD.Year - X[0].BirthDate.Year;
if (X[0].BirthDate > TD.AddYears(-Y)) Y--; Console.WriteLine("{0}, {1} лет", X[0].Name, Y); X[1] = new Stud("Николаенко Олег Михайлович",
"ИТ-41", "ул.Центральная 3,8", "7771234", new DateTime(1992, 5, 28),
new DateTime(2011, 7, 15), 4.3); Y = TD.Year - X[1].BirthDate.Year;
if (X[1].BirthDate > TD.AddYears(-Y)) Y--; Console.WriteLine("{0}, {1} лет", X[1].Name, Y);
}
}
Впрограмме P10_1 описан тип структуры Stud, имеющий строковые поля имени, группы, адреса и номера телефона, поля даты рождения и даты поступления, а также текущий средний бал успеваемости. У структуры присутствует конструктор, инициализирующий списком все поля.
Восновной программе (метод Main) создан массив из 30 элементов структуры Stud. Вручную инициализированы поля нулевого элемента – имя, группа и дата рождения. Ниже высчитан возраст как разница между годом рождения и текущей датой. Если вычитание полученного года из текущей даты даѐт дату меньшую, чем дата рождения, то значения возраста уменьшается на единицу. Имя и возраст выводятся с помощью строки формата. Далее приводится инициализация первого элемента с помощью конструктора. Заметьте, что необходимо указать значения для всех полей.
Структуры при массовом использовании позволяют экономить оперативную память, повышать эффективность и производительность программ.
10.2.ПЕРЕЧИСЛЕНИЯ
Перечисление – множество именованных целочисленных констант, объявляется
с помощью ключевого слова enum. Формат записи:
108
enum имя {список};
где имя – имя типа перечисления, список – список идентификаторов, разделяемых запятыми. По сути, создаѐтся список констант, имеющих целый порядковый номер, который можно получить с помощью явного приведения типов: (int)идентификатор_списка. Элементы списка можно использовать в условных операторах if, для управления оператором выбора switch или оператором цикла for. При доступе к членам перечисления указывается имя их типа, точка и имя члена перечисления.
using System; class P10_2
{
enum Colors
{
Black, Blue, Green, Cyan, Red, Magenta, Brown, White, Gray, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta, Yellow, LtWhite
}
static void Main()
{
string[] NColors = {"Чёрный", "Синий", "Зелёный", "Циан",
"Красный", "Малиновый","Коричневый", "Белый", "Серый", "Св.Синий", "Св.Зелёный", "Св.Циан", "Св.Красный", "Св.Малиновый", "Жёлтый", "Ярк.Берый"};
for (Colors i=Colors.Black; i<=Colors.LtWhite; ++i) Console.WriteLine("{0,2} {1,10} {2,12}",
(int)i, i, NColors[(int)i] );
}
}
В программе P10_2 приводится пример перечисления Colors. В программе задан строковый массив с описанием цветов. В цикле, где счѐтчиком цикла является переменная i перечислимого типа Colors, выводится на консоль список порядкового номера цвета, имя текущего элемента списка перечисления и элемент строкового массива в качестве описания текущего цвета. В строке формата кроме номера параметра через запятую указывается размер поля, что формирует таблицу. Так как размер поля положительный, выравнивание в поле производится по правому краю. Замените размер поля у первого и второго параметров отрицательными значениями, запустите и сравните результаты.
По умолчанию номер каждого следующего элемента списка перечисления больше предыдущего на единицу. Нумерация начинается с нуля. Внутри списка у любого элемента можно указать через равно целое число – номер больший, чем номер по умолчанию.
Следующая запись начнѐт нумерацию с двух, а не с нуля:
enum Colors
{
109
Black = 2, Blue, Green, Cyan, Red, Magenta, Brown, White, Gray, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta,
Yellow, LtWhite
}
все последующие после Black элементы будут также иметь номер на единицу больше предыдущего.
Задавать номер элемента можно также и внутри списка:
enum Colors
{
Black, Blue, Green, Cyan, Red, Magenta, Brown, White, Gray = 31, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta, Yellow, LtWhite
}
Если номер элемента White равен семи, то номер элемента Gray равен 31 и, соответственно, все последующие за ним элементы имеют номер, на единицу больше предыдущего.
Опробуйте инициализацию номера элемента списка перечисления, предварительно убрав из оператора вывода последний параметр – элемент строкового массива, так как выход индекса из диапазона элементов массива приведѐт к ошибке.
10.3. КОЛЛЕКЦИИ
При создании реальных проектов возникают ситуации, когда невозможно предсказать количество элементов массива, набор постоянно меняется, в том числе меняя взаимное расположение элементов. Для решения этой проблемы используют коллекции, поддерживающие динамические массивы, связные списки, стеки, очереди и т.д.
В.NET Framework поддерживаются пять типов коллекций:
необобщѐнные;
специальные;
с поразрядной организацией;
обобщѐнные;
параллельные.
Необобщѐнные коллекции (в пространстве имѐн System.Collections) реализуют такие классы как динамический массив (ArrayList) – массив с динамическим увеличением размера до нужного значения, очередь (Queue) – коллекция, обслуживающая объекты по принципу «первым поступил – первым обслужен», стек (Stack) – неуниверсальная коллекция, обслуживающая объекты по принципу «последним пришѐл – первым ушѐл», словари – коллекции пар «ключ-значение». Необобщѐнные коллекции оперируют данными типа object (хранят ссылки), позволяют хранить данные любого типа, в том числе разнотипные в одной коллекции.
Специальные коллекции (System.Collections.Specialized) оперируют данными конкретного типа или же делают это каким то особым образом. Примером могут служить коллекции строк StringCollection.
110