• Главная
  • Карта сайта
Не найдено

НОУ ІНТУЇТ | лекція | Символи і рядки

  1. Загальний погляд
  2. клас char
  3. Клас char [] - масив символів
  4. Чи існує в C # рядки типу char *

Анотація: Ця лекція присвячена роботі з текстовою інформацією. Розглядаються різні типи даних, що застосовуються при роботі з текстами - char, string, stringBuilder. Детально обговорюються класичні алгоритми пошуку і сортування строкових даних.

Проект до даної лекції Ви можете завантажити тут .

Загальний погляд

Рядках не пощастило. Зі зрозумілих причин в перших мовах програмування строковому типу приділялося набагато менше уваги, ніж арифметичному типу або масивів. Тому в різних мовах рядки представлені по-різному і стандарт на строковий тип склався відносно недавно. Коли говорять про строковому типі, то зазвичай розрізняють тип, що представляє:

  • окремі символи, найчастіше його називають типом char;
  • рядки постійної довжини, часто вони представляються масивом символів;
  • рядки змінної довжини - це, як правило, тип string, що відповідає сучасному уявленню про строковому типі.

Символьний тип char, що представляє окремий випадок рядків довжиною 1, корисний у багатьох завданнях. Основні операції над рядками - це розбір і складання. При їх виконанні доводиться найчастіше доходити до кожного символу рядка. У мові Паскаль, де був введений тип char, сам строковий тип розглядався, як char [] - масив символів. При такому підході отримання i-го символу рядка стає такою ж простою операцією, як і отримання i-го елемента масиву, отже, ефективно реалізуються звичайні операції над рядками - визначення входження одного рядка в іншу, виділення підрядка, заміна символів рядка. Однак зауважте, уявлення рядки масивом символів добре тільки для рядків постійної довжини. Масив не пристосований до зміни його розмірів, вставки або видалення символів (подстрок).

Найбільш часто використовуваним строковим типом є тип, зазвичай званий string, який задає рядки змінної довжини. Над цим типом допускаються операції пошуку входження одного рядка в іншу, операції вставки, заміни та видалення подстрок.

Тип string в мові C # допускає подвійну інтерпретацію. З одного боку, значення змінної типу string можна розглядати, як неподільне значення - скаляр - рядок тексту. З іншого боку, це значення можна інтерпретувати, як масив з n елементів, де n - це довжина рядка. Кожен такий елемент задає окремий символ і належить символьному типу char.

string s1 = "рок", s2 = "око" ,; char ch1, ch2, ch3; ch1 = s1 [0]; ch2 = s1 [1]; ch3 = s1 [2]; string s3 = s1 + s2;

Цей приклад демонструє, як можна працювати з окремими символами рядка і як можна працювати зі скалярним поданням рядки.

клас char

У C # є символьний клас char, заснований на класі System.Char і використовує двухбайтное кодування Unicode представлення символів. Для цього типу в мові визначені символьні константи - символьні літерали. Константу можна задавати:

  • символом, укладеними в одинарні лапки;
  • escape-послідовністю;
  • Unicode-послідовністю, яка задає Unicode код символу.

Ось кілька прикладів оголошення символьних змінних і роботи з ними:

/// <summary> /// Символи, коди, рядки /// </ summary> public void TestChar () {char ch1 = 'A', ch2 = '\ x5A', ch3 = '\ u0058'; char ch = new Char (); int code; string s; ch = ch1; // перетворення символьного типу в тип int code = ch; ch1 = (char) (code +1); // перетворення символьного типу в рядок // s = ch; s = ch1.ToString () + ch2.ToString () + ch3.ToString (); Console.WriteLine ( "s = {0}, ch = {1}, code = {2}", s, ch, code); } // TestChar

Три символьні змінні ініціалізовані константами, значення яких задані трьома різними способами. Мінлива ch оголошується в об'єктному стилі, використовуючи new і виклик конструктора класу. Тип char, як і всі типи C #, є класом. Цей клас успадковує властивості і методи класу object і має велике число власних методів.

Чи існують перетворення між класом char і іншими класами? Явні або неявні перетворення між класами char і string відсутні, але, завдяки методу ToString, змінні типу char стандартним чином перетворюються в тип string. Оскільки у кожного символу є свій код, існують неявні перетворення типу char в цілочисельні типи, починаючи з типу ushort. Зворотні перетворення цілочисельних типів в тип char також існують, але вони вже явні.

В результаті роботи процедури TestChar рядок s, отримана зчепленням трьох символів, перетворених в рядки, має значення BZX, змінна ch дорівнює A в латинському алфавіті, а її код - змінна code - 65. Хоча перетворення символу в код і назад прості, корисно мати процедури, що виконують взаємно-зворотні операції, - отримання за кодом символу і отримання символу за його кодом:

/// <summary> /// Код символу /// </ summary> /// <param name = "sym"> символ </ param> /// <returns> його код </ returns> public static int SayCode (char sym) {return sym; } // SayCode /// <summary> /// Символ /// </ summary> /// <param name = "code"> Код символу </ param> /// <returns> символ </ returns> public static char SaySym (int code) {return (char) code; } // SaySym

У першій процедурі перетворення до цілого типу виконується неявно. У другій - перетворення явне.

Говорячи про символи та їх кодуванні, слід пам'ятати, що для символів алфавітів природних мов (латиниці, кирилиці) застосовується щільна кодування. Це означає, що оскільки буква z в латиниці слід за буквою y, код z на одиницю більше коду y. Тільки буква "Е" в кирилиці не підкоряється цьому правилу. Для цифр також використовується щільна кодування, і їх коди передують кодами букв. Заголовні букви в кодуванні передують рядковим. Ряд символів сприймаються як керуючі, виконуючи при їх появі певним чином впливати. До подібних відносяться такі символи, як "новий рядок" (new line), "повернення каретки" (carriage return), "дзвінок". Ці символи не мають видимого образу, а їх коди задаються escape послідовностями ( '\ n', '\ r'). Оскільки алфавіт, що задається Unicode-кодуванням, містить більше 65000 символів, більшість кодів зарезервовано і їм поки що не відповідають реальні символи. Розглянемо приклад, який демонструє коди деяких символів.

// <summary> /// Перетворення код <-> символ /// </ summary> public void SymToFromCode () {char sym1 = '0', sym2 = 'a', sym3 = 'A', sym4 = '\ r ', sym5 =' а ', sym6 =' а '; PrintCode (sym1); PrintCode (sym2); PrintCode (sym3); PrintCode (sym4); PrintCode (sym5); PrintCode (sym6); int code1 = 13, code2 = 122, code3 = 1071, code4 = 70000; PrintSym (code1); PrintSym (code2); PrintSym (code3); PrintSym (code4); }

Процедури друку PrintCode і PrintSym досить прості, так що код їх не наводиться. Результат роботи цього методу показаний на Мал. 7.1 .


Мал. 7.1. Символи та їх коди

Клас char, як і всі класи в C #, успадковує властивості і методи батьківського класу object. Але у нього є і власні методи і властивості, і їх чимало. Наведу зведення цих методів.

Таблиця 7.1. Статичні методи і властивості класу char Метод Опис GetNumericValue Повертає числове значення символу, якщо він є цифрою, і (-1) в іншому випадку. GetUnicodeCategory Всі символи розділені на категорії. Метод повертає Unicode категорію символу. Нижче наведено приклад. IsControl Повертає true, якщо символ є керуючим. IsDigit Повертає true, якщо символ є десяткової цифрою. IsLetter Повертає true, якщо символ є літерою. IsLetterOrDigit Повертає true, якщо символ є буквою або цифрою. IsLower Повертає true, якщо символ заданий в нижньому регістрі. IsNumber Повертає true, якщо символ є числом (десяткового або шістнадцятковій цифрою). IsPunctuation Повертає true, якщо символ є знаком пунктуації. IsSeparator Повертає true, якщо символ є роздільником. IsSurrogate Деякі символи Unicode з кодом в інтервалі [0x1000, 0x10FFF] представляються двома 16-бітними "сурогатними" символами. Метод повертає true, якщо символ є сурогатним. IsUpper Повертає true, якщо символ заданий в верхньому регістрі. IsWhiteSpace Повертає true, якщо символ є "білим пробілом". До білих прогалин, крім пробілу, відносяться і інші символи, наприклад, символ кінця рядка і символ перекладу каретки. Parse Перетворює рядок в символ. Природно, рядок повинен складатися з одного символу, інакше виникне помилка. ToLower Приводить символ до нижнього регістру. ToUpper Приводить символ до верхнього регістру. MaxValue, MinValue Властивості, які повертають символи з максимальним і мінімальним кодом. Повертаються символи не мають видимого образу.

Більшість статичних методів перевантажені. Вони можуть застосовуватися як до окремого символу, так і до рядка, для якої вказується номер символу для застосування методу. Основну групу складають методи Is, вкрай корисні при розборі рядка. Наведу приклади, в яких використовуються багато з перерахованих методів:

/// <summary> /// Властивості символів /// </ summary> public void TestCharMethods () {Console.WriteLine ( "Метод GetUnicodeCategory:"); System.Globalization.UnicodeCategory cat1, cat2; cat1 = char.GetUnicodeCategory ( 'A'); cat2 = char.GetUnicodeCategory ( ';'); Console.WriteLine ( " 'A' - category {0}", cat1); Console.WriteLine ( " ';' - category {0}", cat2); Console.WriteLine ( "Метод IsLetter:"); Console.WriteLine ( " 'z' - IsLetter - {0}", char.IsLetter ( 'z')); Console.WriteLine ( " 'Я' - IsLetter - {0}", char.IsLetter ( 'Я')); Console.WriteLine ( "Метод IsLetterOrDigit:"); Console.WriteLine ( " '7' - IsLetterOrDigit - {0}", char.IsLetterOrDigit ( '7')); Console.WriteLine ( " 'Я' - IsLetterOrDigit - {0}", char.IsLetterOrDigit ( 'Я')); Console.WriteLine ( "Метод IsControl:"); Console.WriteLine ( " ';' - IsControl - {0}", char.IsControl ( ';')); Console.WriteLine (@ " '\ r' - IsControl - {0}", char.IsControl ( '\ r')); Console.WriteLine ( "Метод IsSeparator:"); Console.WriteLine ( " '' - IsSeparator - {0}", char.IsSeparator ( '')); Console.WriteLine ( " ';' - IsSeparator - {0}", char.IsSeparator ( ';')); Console.WriteLine ( "Метод IsWhiteSpace:"); Console.WriteLine ( " '' - IsWhiteSpace - {0}", char.IsWhiteSpace ( '')); Console.WriteLine (@ " '\ r' - IsWhiteSpace - {0}", char.IsWhiteSpace ( '\ r')); } // TestCharMethods

Ось як виглядають результати консольного виведення, породженого виконанням методу.


Мал. 7.2. властивості символів

Зверніть увагу: літерними символами є як символи латиниці, так і кирилиці, символ повернення каретки відноситься до білих прогалин і до керуючих символів, а символ крапки з комою до розділювачам не відноситься.

Крім статичних методів, у класу char є і динамічні методи. Більшість з них - це методи батьківського класу object, успадковані і перевизначені в класі char. З власних динамічних методів варто відзначити метод CompareTo, що дозволяє проводити порівняння символів. Він відрізняється від методу Equal тим, що для незбіжних символів видає "відстань" між символами відповідно до їх впорядкованістю в кодуванні Unicode.

Клас char [] - масив символів

У мові C # визначено клас char [], і його можна використовувати для подання рядків постійної довжини, як це робиться в С ++. Більш того, оскільки масиви в C # динамічні, розширюється клас задач, в яких можна використовувати масиви символів для подання рядків. Так що має сенс розібратися, наскільки добре C # підтримує роботу з таким поданням рядків.

Масив char [] - це звичайний масив, елементи якого є символами. Масив символів можна перетворити в рядок, можна виконати і зворотне перетворення. У класу string є конструктор, якому в якості аргументів можна передати масив символів. У класу string є динамічний метод ToCharArray, що перетворює рядок в масив символів.

Клас char [], як і всякий клас-масив в C #, є спадкоємцем не тільки класу object, а й класу Array. Деякі методи класу Array можна розглядати як операції над рядками. Наприклад, метод Copy дає можливість виділяти і замінювати подстроку в тілі рядки. Методи IndexOf, LastIndexOf дозволяють визначити індекси першого і останнього входження в рядок деякого символу. На жаль, їх не можна використовувати для більш цікавою операції - знаходження індексу входження підрядка в рядок. При необхідності таку процедуру можна написати самому. Ось як вона виглядає:

int IndexOfStr (char [] s1, char [] s2) {// повертає індекс першого входження підрядка s2 в рядок s1 int i = 0, j = 0, n = s1.Length-s2.Length; bool found = false; while ((i <= n) &&! found) {j = Array.IndexOf (s1, s2 [0], i); if (j <= n) {found = true; int k = 0; while ((k <s2.Length) && found) {found = char.Equals (s1 [k + j], s2 [k]); k ++; }} I = j + 1; } If (found) return (j); else return (-1); } // IndexOfStr

У реалізації використовується метод IndexOf класу Array, що дозволяє знайти початок збігу рядків, після чого перевіряється збіг інших символів. Реалізований тут алгоритм є найочевиднішим, але не найефективнішим.

А тепер розглянемо метод, який тестує перетворення рядків і масивів символів.

/// <summary> /// Рядки і масиви символів /// </ summary> public void TestCharArray () {const string STROKA = "Рядок"; const string HAS = "містить підрядок"; const string NO = "не"; string source = "Петроград", pattern = "радий"; char [] sour = source.ToCharArray (); char [] pat = pattern.ToCharArray (); int first = SymAndStr.IndexOfStr (sour, pat); if (first> = 0) Console.WriteLine (STROKA + source + HAS + pattern); else Console.WriteLine (STROKA + source + NO + HAS + pattern); string word = new string (sour, first - 1, 4); Console.WriteLine (word); }

Чи існує в C # рядки типу char *

У мові C # покажчики допускаються в блоках, позначених небезпечні. Теоретично в таких блоках можна оголосити змінну типу char *, розглядаючи її як рядок. У C # рядки типу char * використовувати не рекомендується.

Чи існують перетворення між класом char і іншими класами?
Провайдеры:
  • 08.09.2015

    Batyevka.NET предоставляет услуги доступа к сети Интернет на территории Соломенского района г. Киева.Наша миссия —... 
    Читать полностью

  • 08.09.2015
    IPNET

    Компания IPNET — это крупнейший оператор и технологический лидер на рынке телекоммуникаций Киева. Мы предоставляем... 
    Читать полностью

  • 08.09.2015
    Boryspil.Net

    Интернет-провайдер «Boryspil.net» начал свою работу в 2008 году и на данный момент является одним из крупнейших поставщиков... 
    Читать полностью

  • 08.09.2015
    4OKNET

    Наша компания работает в сфере телекоммуникационных услуг, а именно — предоставлении доступа в сеть интернет.Уже... 
    Читать полностью

  • 08.09.2015
    Телегруп

    ДП «Телегруп-Украина» – IT-компания с 15-летним опытом работы на рынке телекоммуникационных услуг, а также официальный... 
    Читать полностью

  • 08.09.2015
    Софтлинк

    Высокая скоростьМы являемся участником Украинского центра обмена трафиком (UA — IX) с включением 10 Гбит / сек... 
    Читать полностью