Перейти к содержимому

Какая функция корректно сравнивает две подстроки

  • автор:

Как в C# правильно сравнивать строки

В обоих случаях результат True , хотя String является классом и оператор == должен был сравнить ссылки. IlDasm показал, что создаются 2 переменные и сравниваются согласно методам Equals и == (op_Equality)

 IL_0000: nop IL_0001: ldstr "s" IL_0006: stloc.0 IL_0007: ldstr "s" IL_000c: stloc.1 IL_000d: ldstr "eq: " IL_0012: ldloc.0 IL_0013: ldloc.1 IL_0014: callvirt instance bool [mscorlib]System.String::Equals(string) IL_0019: box [mscorlib]System.Boolean IL_001e: call string [mscorlib]System.String::Concat(object, object) IL_0023: call void [mscorlib]System.Console::WriteLine(string) IL_0028: nop IL_0029: ldstr "==: " IL_002e: ldloc.0 IL_002f: ldloc.1 IL_0030: call bool [mscorlib]System.String::op_Equality(string, string) IL_0035: box [mscorlib]System.Boolean IL_003a: call string [mscorlib]System.String::Concat(object, object) 

Отслеживать
задан 31 янв 2017 в 20:56
Vadim Prokopchuk Vadim Prokopchuk
2,732 2 2 золотых знака 17 17 серебряных знаков 41 41 бронзовый знак

Оператор == сравнивает лишь ссылки (и тем самым j,sxyj бесполезен) лишь в Java. В C#, в отличие от Java, есть перегрузка операторов.

31 янв 2017 в 21:41

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

В C# правильно сравнивать строки и через == , и через Equals . Но более предпочтительным будет сравнивать через == .

Почему так?

Метод Equals подразумевает сравнение значений объектов ссылочного типа, он объявлен как virtual и для строк он перегружен и сравнивает их, как и предполагается, по значению. В Ваших классах Вы должны давать свою реализацию для него. Иначе он будет вести себя как ReferenceEquals и для ссылок, которые указывают не на один объект будет давать false , хоть они и будут равны по значению.

Оператор == для строк представляют свою реализацию, отличную от стандартной для всех других объектов ссылочного типа. Если сравниваемые ссылки имеют тип System.String , то он сначала сравнит указывают ли ссылки на один тот же объект и если нет, то будет сравнивать две ссылки типа System.String по значению.

Но маленькое замечание, если мы сравниваем объект типа System.String ( string ) с объектом типа System.Object (object), который указывает на строку, они будут сравниваться по значениям.

string str = "str"; object obj = "str"; bool result = str.Equals(obj); 

result будет равен true , так как obj приведётся к типу string , потому что метод Equals мы вызвали у строки (объекта типа string ).

Но если мы сравниваем объект типа System.Object (object), который указывает на строку, с объектом типа System.String ( string ) они будут сравниваться по ссылке.

string str = "str"; object obj = "str"; bool result = obj.Equals(str); 

result будет равен false , так как str приведётся к типу object , потому что метод Equals мы вызвали у объекта типа object .

Поэтому в данном случае важно привести object к типу string

Какая функция корректно сравнивает две подстроки

Где верно происходит вывод данных в консоль?%%QUESTION%% %%QUESTION%% Console.write(«Hi»);%%ANSWER%% сonsole.log(«Hi»);%%ANSWER%% print(«Hi»);%%ANSWER%% Console.WriteLine(«Hi»); %%%%%%NEXT__ONE Какие типы переменных существуют?%%QUESTION%% %%QUESTION%% int, char, bool, string%%ANSWER%% int, char, bool, float, double%%ANSWER%% int, char, bool, float, double, uint, short%%ANSWER%% Ни один из них%%ANSWER%% Все перечисленные %%%%%%NEXT__ONE Где правильно создана переменная?%%QUESTION%% %%QUESTION%% x = 0;%%ANSWER%% $x = 10;%%ANSWER%% int num = «1»;%%ANSWER%% float big_num = 23.2234;%%ANSWER%% char symbol = ‘A’; %%%%%%NEXT__ONE При каком условии результат будет равен значению true?%%QUESTION%%

int a = 1, b = 5; bool some = false;

static int num = 0; public static void Main (string[] args) < testFunc(num); testFunc(num); >public static void testFunc (int num)

%%QUESTION%% 00%%ANSWER%% 12%%ANSWER%% Ошибку в коде%%ANSWER%% 01%%ANSWER%% 11 %%%%%%NEXT__ONE Что покажет код ниже?%%QUESTION%%

namespace ProjectOne < class MainClass < static int num = 0; public static void Main (string[] args) < testFunc(num); testFunc(num); >public static void testFunc (int num) < MainClass.num++; Console.Write(MainClass.num); >> >

%%QUESTION%% 00%%ANSWER%% 11%%ANSWER%% Ошибку в коде%%ANSWER%% 01%%ANSWER%% 12 %%%%%%NEXT__ONE Какая функция корректно сравнивает две подстроки?%%QUESTION%% %%QUESTION%% String.Check(«hi», «hello»);%%ANSWER%% String.Equal(«hi», «hello»);%%ANSWER%% String.Match(«hi», «hello»);%%ANSWER%% String.Compare(«hi», «hello»); %%%%%%NEXT__ONE Для чего можно использовать язык C#?%%QUESTION%% %%QUESTION%% Для создания веб сайтов%%ANSWER%% Для создания программ под ПК%%ANSWER%% Для написания игр%%ANSWER%% Для создания лишь игр и программ%%ANSWER%% Всё перечисленное

Полиномиальные хеши и их применение

Здравствуй, хабр. Сегодня я напишу, как можно использовать полиномиальные хеши (далее просто хеши) при решении различных алгоритмических задач.

Введение

Начнем с определения. Пусть у нас есть строка s0..n-1. Полиномиальным хешем этой строки называется число h = hash(s0..n-1) = s0 + ps1 + p 2 s2 +… + p n-1 sn-1, где p — некоторое натуральное число (позже будет сказано, какое именно), а si — код i-ого символа строки s (почти во всех современных языках он записывается s[i] ).

Хеши обладают тем свойством, что у одинаковых строк хеши обязательно равны. Поэтому основная операция, которую позволяют выполнять хеши — быстрое сравнение двух подстрок на равенство. Конечно, чтобы сравнить 2 строки, мы можем написать подобную функцию (будем считать, что длины строк s и t совпадают и равны n):

boolean equals(char[] s, char[] t) < for (int i = 0; i < n; i++) if (s[i] != t[i]) < return false; >> return true; > 

Однако в худшем случае эта функция обязана проверить все символы, что дает асимптотику O(n).

Сравнение строк с помощью хешей

Теперь посмотрим, как справляются с этой задачей хеши. Так как хеш — это всего лишь число, для их сравнения нам потребуется O(1) времени. Правда, для того, чтобы посчитать хеш одной подстроки наивным способом, требуется O(n) времени. Поэтому потребуется немного повозиться с математическими формулами и научиться находить за O(n) хеши сразу всех подстрок. Давайте сравним подстроки sL..R и tX..Y (одинаковой длины). Пользуясь определением хеша, мы можем записать:

Проведем небольшие преобразования в левой части (в правой части все будет происходить аналогично). Запишем хеш подстроки s0..R, он нам понадобится:

Разобьем это выражение на две части…

… и вынесем из второй скобки множитель p L :

Выражение в первой скобке есть не что иное, как хеш подстроки s0..L-1, а во второй — хеш нужной нам подстроки sL..R. Итак, мы получили, что:

Отсюда вытекает следующая формула для hash(sL..R):

Аналогично, для второй нашей подстроки будет выполнено равенство hash(tX..Y) = (1 / p X )(hash(t0..Y) — hash(t0..X-1)).

Внимательно глядя на эти формулы, можно заметить, что для вычисления хеша любой подстроки нам необходимо знать лишь хеши префиксов этой строки s0..0, s0..1, . s0..n-2, s0..n-1. А, так как хеш каждого следующего префикса выражается через хеш предыдущего, их несложно посчитать линейным проходом по строке. Все сразу за O(n) времени. Степени числа p тоже надо заранее предпросчитать и сохранить в массиве.

// сохраняем в массиве степени числа p, которые нам могут понадобиться pow[0] = 1; for (int i = 1; i // считаем хеши префиксов строки s hs[0] = s[0]; for (int i = 1; i < n; i++) < hs[i] = hs[i - 1] + pow[i] * s[i]; >// считаем хеши префиксов строки t ht[0] = t[0]; for (int i = 1; i

Казалось бы, мы теперь во всеоружии и умеем сравнивать 2 любые подстроки за O(1). Но не все так просто: математические формулы нуждаются в некоторой доработке. К примеру, подобный код:

if ((hs[R] - hs[L - 1]) / pow[L] == (ht[Y] - ht[X - 1]) / pow[X])
    Замечание первое: L (или X) может оказаться равным нулю, и при вычислении hs[L — 1] произойдет выход за границы массива. Однако если L равно нулю, то интересующий нас хеш подстроки sL..R хранится в точности в hs[R] . Поэтому правильнее вместо hs[L — 1] писать так:
L == 0 ? 0 : hs[L - 1]
if ((hs[R] - (L == 0 ? 0 : hs[L - 1])) * pow[X] == (ht[Y] - (X == 0 ? 0 : ht[X - 1])) * pow[L])
Задачи, решаемые с помощью хешей
1. Сравнение подстрок

Первое, и главное, применение, как уже было сказано, это быстрое сравнение двух подстрок — на нем основываются все остальные алгоритмы с хешами. Код в прошлом разделе довольно громоздкий, поэтому я напишу более удобный код, который будет использоваться в дальнейшем.
Следующая функция вычисляет хеш подстроки sL..R, умноженный на p L :

long getHash(long[] h, int L, int R) < long result = h[R]; if (L >0) result -= h[L - 1]; return result; > 

Теперь сравнение двух подстрок мы выполняем следующей строчкой:

if (getHash(hs, L, R) * pow[X] == getHash(ht, X, Y) * pow[L])

Умножение на степени числа p можно назвать «приведением к одной степени». Первый хеш был умножен на p L , а второй — на p X — значит, чтобы сравнение происходило корректно, их надо домножить на недостающий множитель.
Примечание: имеет смысл сначала проверить, совпадают ли длины подстрок. Если нет, то строки в принципе не могут быть равны, и тогда можно не проверять вышезаписанное условие.

2. Поиск подстроки в строке за O(n + m)

Хеши позволяют искать подстроку в строке за асимптотически минимальное время. Это делает так называемый алгоритм Рабина-Карпа.
Пусть есть строка s длины n, в которой мы хотим найти все вхождения строки t длины m. Найдем хеш строки t (всей строки целиком) и хеши всех префиксов строки s, а затем будем двигаться по строке s окном длины m, сравнивая подстроки si..i+m-1.
Код:

// считаем хеш строки t long ht = t[0]; for (int i = 1; i < m; i++) < ht += pow[i] * t[i]; >// проверяем все позиции for (int i = 0; i + m > 
3. Нахождение z-функции за O(n log n)

Z-функцией строки s называется массив z, i-ый элемент которого равен наидлиннейшему префиксу подстроки, начинающейся с позиции i в строке s, который одновременно является и префиксом всей строки s. Значение z-функции в нулевой позиции будем считать равным длине строки s, хотя некоторые источники принимают его за ноль (но это не критично).

Конечно, есть алгоритм нахождения z-функции за O(n). Но когда его не знаешь или не помнишь (а алгоритм довольно громоздкий), на помощь приходят хеши.

Идея следующая: для каждого i = 0, 1, . n-1 будем искать zi бинарным поиском, т.е. на каждой итерации сокращая интервал возможных значений вдвое. Это корректно, потому что равенство s0..k-1 = si..i+k-1 обязательно выполняется для всех k, меньших zi, и обязательно не выполняется для больших k.

int[] z = new int[n]; for (int i = 0; i < n; i++) < int left = 1, right = n - i; // текущий интервал значений while (left else < // если не совпадают, надо проверить меньшие значения right = middle - 1; >> > 
4. Поиск лексикографически минимального циклического сдвига строки за O(n log n).

Существует алгоритм Дюваля, который позволяет решать эту задачу за O(n), однако я знаю некоторых довольно сильных олимпиадных программистов, которые так и не разобрались в нем. Пока они будут в нем разбираться, мы снова применим хеши.

Алгоритм следующий. Сначала примем саму строку s за лучший (лексикографически минимальный) ответ. Затем для каждого циклического сдвига с помощью бинарного поиска найдем длину максимального общего префикса этого сдвига и текущего лучшего ответа. После этого достаточно сравнить следующие за этим префиксом символы и, если надо, обновить ответ.
Еще заметим, что для удобства здесь рекомендуется приписать строку s к самой себе — не придется делать операции взятия по модулю при обращениям к символам строки s. Будем считать, что это уже сделано.

int bestPos = 0; for (int i = 1; i < n; i++) < int left = 1, right = n, length = 0; // находим length - длину максимального общего префикса while (left else < right = middle - 1; >> // сравниваем следующий за общим префиксом символ и обновляем ответ // если длина этого префикса равна n, // то текущий циклический сдвиг совпадает с минимальным, // и ответ обновлять не нужно if (length < n && s[i + length] < s[bestPos + length]) < bestPos = i; >> 

Примечание: по сути, внутри цикла for написан компаратор, сравнивающий лексикографически два циклических сдвига. Используя его, можно за O(n log 2 n) отсортировать все циклические сдвиги.

5. Поиск всех палиндромов в строке за O(n log n).

Опять же, существует решение этой задачи за O(n). И опять мы будем решать ее с помощью хешей.

Подстрока sL..R называется палиндромом, если sL = sR, sL+1 = sR-1, и т.д. Если выражаться русским языком, то это означает, что она читается одинаково как слева направо, так и справа налево.

Возможно, вы уже знаете или догадались, при чем тут хеши. Помимо массива h[] , содержащего хеши для подстрок s0..0, s0..1, . s0..n-2, s0..n-1, посчитаем второй массив rh[] (для «перевернутой» строки), который будем обходить справа налево. Он будет содержать соответственно хеши s0..n-1, s1..n-1, . sn-2..n-1, sn-1..n-1:

rh[n - 1] = s[n - 1]; for (int i = n - 2, j = 1; i >= 0; i--, j++)

Должно уже быть понятно, как за O(1) определять, является ли строка палиндромом. Я напишу функцию getRevHash(), аналогичную getHash(), а потом приведу необходимое условие сравнения. Вы можете самостоятельно убедиться в правильности этого выражения, проделав математические выкладки, подобные тем, что приводились в начале статьи.

long getRevHash(long[] rh, int L, int R) < long result = rh[L]; if (R < n - 1) result -= rh[R + 1]; return result; >boolean isPalindrome(long[] h, long[] rh, long[] pow, int L, int R)

Теперь рассмотрим позицию i в строке. Пусть существует палиндром нечетной длины d с центром в позиции i (в случае четной длины — с центром между позициями i-1 и i). Если обрезать с его краев по одному символу, он останется палиндромом. И так можно продолжать, пока его длина не станет равной нулю.
Таким образом, нам достаточно для каждой позиции хранить 2 значения: сколько существует палиндромов нечетной длины с центром в позиции i, и сколько существует палиндромов четной длины с центром между позициями i-1 и i. Обратите внимание, что эти 2 значения абсолютно независимы друг от друга, и обрабатывать их надо отдельно.

Применим, как и ранее, бинарный поиск:

int[] oddCount = new int[n]; for (int i = 0; i < n; i++) < int left = 1, right = min(i + 1, n - i); while (left else < right = middle - 1; >> > int[] evenCount = new int[n]; for (int i = 0; i < n; i++) < int left = 1, right = min(i, n - i); while (left else < right = middle - 1; >> > 

Теперь можно, к примеру, найти общее количество всех палиндромов в строке, или длину максимального палиндрома. Длина максимального нечетного палиндрома с центром в позиции i считается как 2 * oddCount[i] — 1 , а максимального четного палиндрома — 2 * evenCount[i] .
Еще раз напомню, что нужно быть внимательнее с палиндромами четной и нечетной длины — как правило, их надо обрабатывать независимо друг от друга.

Хеши в матрицах

Наконец, рассмотрим более изощренные применения хешей. Теперь наше пространство будет двумерным, и сравнивать мы будем подматрицы. К счастью, хеши очень хорошо обобщаются на двумерный случай (трехмерных и более я не встречал).

Теперь вместо числа p и массива pow у нас будут два различных числа p, q и два массива pow1 , pow2 : по одному числу и по одному массиву в каждом направлении: по вертикали и горизонтали.

Хешем матрицы a0..n-1, 0..m-1 будем называть сумму по всем i = 0, . n-1, j = 0. m-1 величин p i q j aij.

Теперь научимся считать хеши подматриц, содержащих левый верхний элемент a00. Очевидно, что hash(a0..0, 0..0) = a00. Почти так же очевидно, что для всех j = 1. m-1 hash(a0..0, 0..j) = hash(a0..0, 0..j-1) + q j a0j, для всех i = 1. n-1 hash(a0..i, 0..0) = hash(a0..i-1, 0..0) + p i ai0. Это напрямую вытекает из одномерного случая.

Как посчитать хеш подматрицы a0..i, 0..j? Можно догадаться, что hash(a0..i, 0..j) = hash(a0..i-1, 0..j) + hash(a0..i, 0..j-1) — hash(a0..i-1, 0..j-1) + p i q j aij. Эту формулу можно получить из следующих соображений: сложим все слагаемые (хеш, напомню, это сумма нескольких слагаемых), составляющие хеш подматриц a0..i-1, 0..j и a0..i, 0..j-1. При этом мы два раза учли слагаемые, составляющие подматрицу a0..i-1, 0..j-1, так что вычтем их, чтобы они учитывались один раз. Теперь не хватает только элемента aij, умноженного на соответствующие степени p и q.

Примерно из тех же соображений, что и в первой части статьи (вы уже заметили причастность формулы включений-исключений?) строится функция для вычисления хеша произвольной подматрицы ax1..x2, y1..y2:

long getMatrixHash(long[][] h, int x1, int x2, int y1, int y2) < long result = h[x2][y2]; if (x1 >0) result -= h[x1 - 1][y2]; if (y1 > 0) result -= h[x2][y1 - 1]; if (x1 > 0 && y1 > 0) result += h[x1 - 1][y1 - 1]; return result; > 

Эта функция возвращает хеш подматрицы ax1..x2, y1..y2, умноженный на величину p x1 q y1 .

А сравнение двух подматриц aax1..ax2, ay1..ay2 и abx1..bx2, by1..by2 выполняется с помощью следующего выражения:

if (getMatrixHash(h, ax1, ax2, ay1, ay2) * pow1[bx1] * pow2[by1] == getMatrixHash(h, bx1, bx2, by1, by2) * pow1[ax1] * pow2[ay1])

Хешами также можно решать задачи, связанные с нахождением самой большой симметричной подматрицы и похожие на них. Причем я не знаю сравнимых с хешами по скорости и простоте алгоритмов, выполняющих эту работу. Здесь используются те же принципы, что и при поиске палиндромов в одномерном случае (т.е. считать «реверснутые» хеши справа налево и снизу вверх, проводить бинпоиск отдельно для подматриц четной и нечетной длины). Предлагаю попробовать решить эту задачу самостоятельно — эта статья вам поможет!

Заключение

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

  • алгоритмы
  • олимпиадные задачи
  • хеширование
  • строки
  • поиск подстроки в строке
  • сравнение строк

Сравнение строк в .NET

Платформа .NET обеспечивает несколько методов для сравнения значений строк. В таблице ниже перечислены и описаны методы сравнения значений.

Имя метода Использовать
String.Compare Сравнивает значения двух строк. Возвращает целочисленное значение.
String.CompareOrdinal Сравнивает две строки без учета локального языка и региональных параметров. Возвращает целочисленное значение.
String.CompareTo Сравнивает текущий строковый объект с другой строкой. Возвращает целочисленное значение.
String.StartsWith Определяет, начинается ли строка с переданной строки. Возвращает логическое значение.
String.EndsWith Определяет, заканчивается ли строка переданной строкой. Возвращает логическое значение.
String.Contains Определяет, встречается ли символ или строка в другой строке. Возвращает логическое значение.
String.Equals Определяет, совпадают ли две строки. Возвращает логическое значение.
String.IndexOf Возвращает индекс позиции символа или строки начиная с начала проверяемой строки. Возвращает целочисленное значение.
String.LastIndexOf Возвращает индекс позиции символа или строки начиная с конца проверяемой строки. Возвращает целочисленное значение.

Метод Compare

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

Возвращаемое значение Условие
Отрицательное целое число Первая строка предшествует второй в порядке сортировки.

Метод String.Compare в основном предназначен для использования при упорядочивании или сортировке строк. Не следует использовать метод String.Compare для проверки на равенство (то есть для явного поиска возвращаемого значения 0 без учета того, является ли одна строка меньше или больше другой). Для определения равенства двух строк используйте метод String.Equals(String, String, StringComparison) .

В примере ниже метод String.Compare используется для определения относительных значений двух строк.

String^ string1 = "Hello World!"; Console::WriteLine(String::Compare(string1, "Hello World?")); 
string string1 = "Hello World!"; Console.WriteLine(String.Compare(string1, "Hello World?")); 
Dim string1 As String = "Hello World!" Console.WriteLine(String.Compare(string1, "Hello World?")) 

Этот пример выводит на консоль значение -1 .

В предыдущем примере по умолчанию учитывается язык и региональные параметры. Для сравнения строк без учета языка и региональных параметров используйте перегрузку метода String.Compare , которая позволяет указать язык и региональные параметры с помощью параметра culture . См. пример, демонстрирующий использование метода String.Compare для сравнения строк без учета языка и региональных параметров.

Метод CompareOrdinal

Метод String.CompareOrdinal сравнивает два строковых объекта без учета локального языка и региональных параметров. Возвращаемые этим методом значения идентичны значениям, возвращаемым методом Compare в предыдущей таблице.

Метод String.CompareOrdinal в основном предназначен для использования при упорядочивании или сортировке строк. Не следует использовать метод String.CompareOrdinal для проверки на равенство (то есть для явного поиска возвращаемого значения 0 без учета того, является ли одна строка меньше или больше другой). Для определения равенства двух строк используйте метод String.Equals(String, String, StringComparison) .

В примере ниже метод CompareOrdinal используется для сравнения значений двух строк.

String^ string1 = "Hello World!"; Console::WriteLine(String::CompareOrdinal(string1, "hello world!")); 
string string1 = "Hello World!"; Console.WriteLine(String.CompareOrdinal(string1, "hello world!")); 
Dim string1 As String = "Hello World!" Console.WriteLine(String.CompareOrdinal(string1, "hello world!")) 

Этот пример выводит на консоль значение -32 .

Метод CompareTo

Метод String.CompareTo сравнивает строку, которую инкапсулирует текущий строковый объект, с другой строкой или объектом. Возвращаемые этим методом значения идентичны значениям, возвращаемым методом String.Compare в предыдущей таблице.

Метод String.CompareTo в основном предназначен для использования при упорядочивании или сортировке строк. Не следует использовать метод String.CompareTo для проверки на равенство (то есть для явного поиска возвращаемого значения 0 без учета того, является ли одна строка меньше или больше другой). Для определения равенства двух строк используйте метод String.Equals(String, String, StringComparison) .

В примере ниже метод String.CompareTo используется для сравнения объекта string1 с объектом string2 .

String^ string1 = "Hello World"; String^ string2 = "Hello World!"; int MyInt = string1->CompareTo(string2); Console::WriteLine( MyInt ); 
string string1 = "Hello World"; string string2 = "Hello World!"; int MyInt = string1.CompareTo(string2); Console.WriteLine( MyInt ); 
Dim string1 As String = "Hello World" Dim string2 As String = "Hello World!" Dim MyInt As Integer = string1.CompareTo(string2) Console.WriteLine(MyInt) 

Этот пример выводит на консоль значение -1 .

Все перегрузки метода String.CompareTo по умолчанию выполняют сравнение с учетом языка и региональных параметров и регистра. У этого метода нет перегрузок, позволяющих выполнять сравнение без учета языка и региональных параметров. В целях повышения ясности кода рекомендуется использовать вместо него метод String.Compare , указывая CultureInfo.CurrentCulture для операций с учетом языка и региональных параметров и CultureInfo.InvariantCulture для операций без учета языка и региональных параметров. Примеры, демонстрирующие использование метода String.Compare для сравнения с учетом и без учета языка и региональных параметров, см. в разделе Сравнение строк без учета языка и региональных параметров.

Метод Equals

С помощью метода String.Equals можно легко определить идентичность двух строк. Этот метод учитывает регистр и возвращает логическое значение true или false . Метод можно вызывать из существующего класса, как показано в следующем примере. В примере ниже метод Equals используется для определения того, содержит ли строковый объект фразу «Hello World».

String^ string1 = "Hello World"; Console::WriteLine(string1->Equals("Hello World")); 
string string1 = "Hello World"; Console.WriteLine(string1.Equals("Hello World")); 
Dim string1 As String = "Hello World" Console.WriteLine(string1.Equals("Hello World")) 

Этот пример выводит на консоль значение True .

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

String^ string1 = "Hello World"; String^ string2 = "Hello World"; Console::WriteLine(String::Equals(string1, string2)); 
string string1 = "Hello World"; string string2 = "Hello World"; Console.WriteLine(String.Equals(string1, string2)); 
Dim string1 As String = "Hello World" Dim string2 As String = "Hello World" Console.WriteLine(String.Equals(string1, string2)) 

Этот пример выводит на консоль значение True .

Методы StartsWith и EndsWith

Метод String.StartsWith можно использовать для определения того, начинается ли строковый объект с тех же символов, которые включает другая строка. Этот метод учитывает регистр и возвращает значение true , если текущий строковый объект начинается с переданной строки, и значение false в противном случае. В примере ниже этот метод используется для определения того, начинается ли строковый объект со слова «Hello».

String^ string1 = "Hello World"; Console::WriteLine(string1->StartsWith("Hello")); 
string string1 = "Hello World"; Console.WriteLine(string1.StartsWith("Hello")); 
Dim string1 As String = "Hello World!" Console.WriteLine(string1.StartsWith("Hello")) 

Этот пример выводит на консоль значение True .

Метод String.EndsWith сравнивает переданную строку с символами, находящимися в конце текущего строкового объекта. Он также возвращает логическое значение. В примере ниже конец строки проверяется с помощью метода EndsWith .

String^ string1 = "Hello World"; Console::WriteLine(string1->EndsWith("Hello")); 
string string1 = "Hello World"; Console.WriteLine(string1.EndsWith("Hello")); 
Dim string1 As String = "Hello World!" Console.WriteLine(string1.EndsWith("Hello")) 

Этот пример выводит на консоль значение False .

Методы IndexOf и LastIndexOf

С помощью метода String.IndexOf можно определить позицию первого вхождения конкретного символа в строку. Этот метод учитывает регистр и начинает отсчет с начала строки. Он возвращает позицию переданного символа, используя отсчитываемый от нуля индекс. Если символ не удается найти, возвращается значение –1.

В примере ниже метод IndexOf используется для поиска первого вхождения символа » l » в строку.

String^ string1 = "Hello World"; Console::WriteLine(string1->IndexOf('l')); 
string string1 = "Hello World"; Console.WriteLine(string1.IndexOf('l')); 
Dim string1 As String = "Hello World!" Console.WriteLine(string1.IndexOf("l")) 

Этот пример выводит на консоль значение 2 .

Метод String.LastIndexOf аналогичен методу String.IndexOf за исключением того, что он возвращает позицию последнего вхождения конкретного символа в строку. Он учитывает регистр и использует отсчитываемый от нуля индекс.

В примере ниже метод LastIndexOf используется для поиска последнего вхождения символа » l » в строку.

String^ string1 = "Hello World"; Console::WriteLine(string1->LastIndexOf('l')); 
string string1 = "Hello World"; Console.WriteLine(string1.LastIndexOf('l')); 
Dim string1 As String = "Hello World!" Console.WriteLine(string1.LastIndexOf("l")) 

Этот пример выводит на консоль значение 9 .

Оба метода полезно использовать в сочетании с методом String.Remove . Для получения позиции символа используется метод IndexOf или LastIndexOf , после чего эта позиция передается методу Remove для удаления символа или начинающегося с него слова.

См. также

  • Рекомендации по использованию строк в .NET
  • Базовые операции со строками
  • Выполнение строковых операций, не зависящих от языка и региональных параметров
  • Таблицы сортировки весов, используемые платформа .NET Framework и .NET Core 1.0–3.1 в Windows
  • Таблица элементов сортировки Юникода по умолчанию — используется .NET 5 на всех платформах и .NET Core в Linux и macOS

Совместная работа с нами на GitHub

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *