2.2 Массив символов
Некоторые алгоритмы обработки символьной информации могут оперировать массивом символов, а, значит, им доступны возможности класса Array, приведенные в работе 7. Рассмотрим это на конкретном примере.
Пример 2. Дана строка символов s (вводится с клавиатуры). Напечатать в алфавитном порядке: какие строчные русские буквы встречаются в этой строке.
Одним из вариантом решения данной задачи может быть такой. Опишем дополнительную строку p, где будет представлен весь русский алфавит строчными буквами, как массив символов. Данный массив, также как и массив символов s, получен в программе (лист.2) путем преобразования строки в массив методом ToCharArray класса System.String (табл. 2). Естественно длина такого массива будет определяться числом 33. Анализ введенного массива s в этом случае может быть организован с помощью двух вложенных циклов.
В предложенной программе внешний цикл перебирает посимвольно буквы русского алфавита из массива р, и для его построения используется цикл с параметром. Конечное значение параметра этого цикла вычисляется в заголовке цикла с помощью функции Length(p), хотя можно было просто записать его значение явно, равное 33.
Внутренний цикл — это цикл с постусловием. Параметром его является переменная j, определяющая индекс анализируемого элемента массива s и увеличивающая свое значение в цикле с шагом +1, тем самым, обеспечивая просмотр всех его элементов (от первого до последнего). Если найден элемент массива s, совпадающий с рассматриваемой буквой алфавита, определенной во внешнем цикле, то выполняются печать этого элемента и принудительное завершение внутреннего цикла процедурой break. Вот почему дублирование символов в массиве s не обнаруживается.
После прерывания выполнения внутреннего цикла внешний цикл начинает работать со следующим элементом массива-алфавита, и для него все повторяется сначала.
Листинг 2
using System;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
char[] p = "абвгдежзийклмнопрстуфхцчшщъыьэюя".ToCharArray();
Console.WriteLine();
char[] s = "мама мыла раму".ToCharArray();
for (int i = 0; i < p.Length; ++i)
{
int j = 1;
do
{
if (p[i] == s[j])
{
Console.Write(" " + s[j]);
break;
}
j++;
}
while (j < s.Length);
}
Console.Read();
}
}
}
2.3 Тип String
Тип string предназначен для определения и поддержки символьных строк. Самый простой способ создать объект типа string - использовать строковый литерал:
string str = "С#-строки - это мощная сила.";
Создать строку можно несколькими способами:
string s; //инициализация отложена
string t = “программа”; //инициализация строковым литералом
string ц= new string(‘*‘,10); //конструктор создает строку из 10 символов
char[] a = {‘0’,’0’,’0’}; //массив для инициализации строки
string v = new string(a); //создание из массива символов
Последовательность символов, составляющих строку, изменить нельзя. Это связано с тем, что строки типа string относятся к так называемым неизменяемым типам данных. Поэтому обращаться к отдельному элементу строки по индексу (например, s[i]) можно только для получения значения, но не для его изменения.
Хотя это кажется серьезным недостатком, на самом деле это не так. Это ограничение позволяет С# эффективно использовать строки. Если понадобится строка, которая должна содержать изменения уже существующей строки, то потребуется создать новую строку. Поскольку неиспользуемые строковые объекты автоматически утилизируются системой сбора мусора.
При описании строковой переменной память под нее отводится по максимуму. При работе же с переменной может использоваться лишь часть этой памяти, реально занятая символами строки в данный момент.
Для строк определены следующие операции:
присваивание (=);
проверка на равенство (==); (Строки равны, если имеют одинаковое количество символов и совпадают посимвольно)
проверка на неравенство (!=);
обращение по индексу ([ ]);
сцепление (конкатенация) строк (+).
Пример 3. Дан массив слов. Составить программу, которая вводит исходный массив, затем вводит поочередно различные слова и проверяет, имеются ли такие слова в исходном массиве.
Сформулированная задача в данной постановке подобна многим другим, осуществляющим обработку элементов одномерного массива. Такие программы были рассмотрены в лабораторной работе 8. Основное отличие данной задачи заключается в том, что в этом случае поиск требуемого элемента должен производиться не в числовом массиве, а в массиве слов.
Программа представлена на листинге 3. Ее исполнительная часть содержит вложенные циклы.
Наличие внешнего цикла объясняется тем, что пользователю предоставляется возможность поиска не одного, а нескольких слов в массиве, содержащем ks слов. Чтобы предоставить пользователю неограниченную свободу в поиске, внешний цикл организован с помощью цикла с постусловием, работа которого завершается при введении для поиска слова «конец».
Внутренний цикл представляет собой также цикл с постусловием, в котором просматриваются поочередно слова массива, начиная с первого элемента. В том случае, если будет найден элемент массива, совпадающий с введенным во внешнем цикле словом, формируется признак pr=true и завершается работа внутреннего цикла. Пользователь переходит к поиску следующего слова. По поиску каждого слова выдается сообщение о том найдено ли оно или нет.
Листинг 3
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{ int ks,n=15;
bool pr;
string s;
string[] sl=new string[n];
Console.WriteLine("Введите количество слов в массиве: ks");
ks = Convert.ToInt32(Console.ReadLine());
for (int k=1; k<ks; k++)
{
Console.WriteLine("Введите слово массива");
sl[k]=Console.ReadLine();
}
do
{
Console.WriteLine("Введите новое слово");
s = Console.ReadLine();
pr = false;
int j = 0;
do
{
if (sl[j] == s) pr = true;
j++;
}
while ((pr == false) && (j < ks));
if (pr) Console.WriteLine("Да, такое слово есть");
else Console.WriteLine("Такого слова нет");
}
while (s != "конец");
}
}
}
Результаты работы программы:
Для облегчения работы со строками в языке С# существует специальный класс System.String.
Основные методы и свойства класса System.String, позволяющие выполнять со строками практически любые действия, представлены в (табл.2).
Таблица 2 - Основные элементы класса System.String
|
Название |
Вид |
Описание |
1 |
Compare |
Статический метод |
Сравнение двух строк в лексикографическом (алфавитном) порядке. Разные реализации метода позволяют сравнивать строки и подстроки с учетом и без учета регистра и особенностей национального представления дат и т. д. |
2 |
CompareOrdinal |
Статический метод |
Сравнение двух строк по кодам символов. Разные реализации метода позволяют сравнивать строки и подстроки |
3 |
CompareTo |
Метод |
Сравнение текущего экземпляра строки с другой строкой |
4 |
Concat |
Статический метод |
Конкатенация строк. Метод допускает сцепление произвольного числа строк |
5 |
Copy |
Статический метод |
Создание копии строки |
6 |
Empty |
Статическое поле |
Пустая строка (только для чтения) |
7 |
Format |
Статический метод |
Форматирование в соответствии с заданными спецификаторами формата |
8 |
IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAny |
Методы |
Определение индексов первого и последнего вхождения заданной подстроки или любого символа из заданного набора |
9 |
Insert |
Метод |
Вставка подстроки в заданную позицию |
10 |
Intern, IsInterned |
Статические методы |
Возвращает ссылку на строку, если такая уже существует. Если строки нет, Intern добавляет строку во внутренний пул, IsIntern возвращает null |
11 |
Join |
Статический метод |
Слияние массива строк в единую строку. Между элементами массива вставляются разделители (см. далее) |
12 |
Length |
Свойство |
Длина строки (количество символов) |
13 |
PadLeft, PadRight |
Методы |
Выравнивание строки по левому или правому краю путем вставки нужного числа пробелов в начале или в конце строки |
14 |
Remove |
Метод |
Удаление подстроки из заданной позиции |
15 |
Replace |
Метод |
Замена всех вхождений заданной подстроки или символа новой подстрокой или символом |
16 |
Split |
Метод |
Разделение строки на элементы, используя заданные разделители. Результаты помещаются в массив строк |
17 |
StartsWith, EndsWith |
Методы |
Возвращает true или false в зависимости от того, начинается или заканчивается строка заданной подстрокой |
18 |
Substring |
Метод |
Выделение подстроки, начиная с заданной позиции |
19 |
ToCharArray |
Метод |
Преобразование строки в массив символов |
20 |
ToLower, ToUpper |
Методы |
Преобразование символов строки к нижнему или верхнему регистру |
21 |
Trim, TrimStart, TrimEnd |
Методы |
Удаление пробелов в начале и конце строки или только с одного ее конца (обратные по отношению к методам PadLeft и PadRight действия) |
Рассмотрим еще один специальный пример, где используем некоторые методы этого класса.
Пример 4.
Листинг 4 – Использование методов класса System.String
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{ int ks=5;
string s,s1;
string[] sl=new string[ks];
for (int k=1; k<ks; k++)
{
Console.WriteLine("Введите слово массива");
sl[k]=Console.ReadLine();
}
s = string.Join(":", sl);
Console.WriteLine(s);
s1 = s.Replace(":",",");
Console.WriteLine(s1);
s = s1.Substring(1);
Console.WriteLine(s);
s1 = s.ToUpper();
Console.WriteLine(s1);
}
}
}
Результаты работы программы:
Данная программа демонстрирует использование ряда методов класса System.String. В ней сначала вводится произвольная строка, а затем осуществляется четыре последовательных вызова различных методов класса System.String.
В операторе s = string.Join(":", sl); вызывается статический метод Join (он вызывается через имя класса) слияния массива строк sl в единую строку s, помещая между словами в строке разделитель «:».
В операторе s1=s.Replace(":",","); вызывается метод Replace, осуществляющий замену всех вхождений символа":" новым символом, в нашем случае ",", и присваивание полученного результата строке s1.
В операторе s = s1.Substring(1); вызывается метод Substring, который возвращает подстроку из строки s1, начиная с первой позиции, отбрасывая первый символ «:» и присваивая результат строке s.
В операторе s1 = s.ToUpper(); вызывает метод ToUpper, выполняющий преобразование символов строки к верхнему регистру. Результат присваивается строке s1.
Пример 5. Дана последовательность, состоящая из 10 слов. Напечатать все различные слова, указав для каждого из них число его вхождений в последовательность.
Листинг 5 – К примеру 5
using System;
namespace primer
{
class Program
{
static void Main(string[] args)
{/*CompareOrdinal---Сравнение двух строк по кодам символов.
* Разные реализации метода позволяют сравнивать строки и подстроки
* CompareTo----Сравнение текущего экземпляра строки с другой строкой
* 12. Дана последовательность,
* состоящая из 10 слов.
* Напечатать все различные слова,
* указав для каждого из них число его вхождений в последовательность.
*/
int col = 0;
int ks = 10;
string[] sl = new string[ks];
Console.WriteLine("Введите 10 слов ");
for (int k = 0; k < ks; k++)
{
sl[k] = Console.ReadLine();
}
Console.WriteLine("Количество вхождений");
for (int i = 0; i < ks; i++)
{
col = 0;
for (int j = 0; j < ks; j++)
{
if (String.Compare(sl[i], sl[j]) == 0) col++;
}
Console.WriteLine(sl[i] + " Количество вхождений слова в последовательность " + col);
}
}
}
}
Результат работы программы:
