Сравнение строк.
Библиотека <cstring> предлагает пользователю готовые функции, выполняющие сравнение строк. Далее будут рассмотрены функции, выполняющие посимвольное сравнение двух строк и возвращающие разность кодов первых несовпадающих символов.
Функция strcmp.
Функция strcmp имеет прототип:
- 0 , если str1 > str2
Эта функция производит сравнение, различая прописные и строчные буквы
В результате, на экран будет выведено: 32. Т.к. код символа l = 108, а код символа L = 76. 108-76=32.
Функция stricmp.
Функция stricmp имеет тот же прототип как и функция strcmp. Отличие этих двух функций лишь в том, что stricmp не различает регистр символов. Т.е. для предыдущего примера на экран выведется 0.
Функция strncmp.
Эта функция сравнивает num первых символов строк, на которые указывают указатели str1 и str2. Пример: Результатом работы будет 0, т.к. вторые символы не различаются.
в C# быстрый способ сравнения строк
это правда? И это хорошая практика для сравнения больших длин строк перед сравнением фактических строк?
9 ответов
string оператор s equals проверяет длину перед сравнением символов. Таким образом, вы не сохраните сравнение содержимого с этим трюком. Вы может все равно сохраните несколько циклов процессора, потому что ваша проверка длины предполагает, что строки не являются нулевыми, в то время как BCL должен проверить это. Поэтому, если длины не равны большую часть времени, вы закоротите несколько инструкций.
Я могу просто ошибаться здесь, хотя. Может быть, оператор получает inlined и чеки оптимизировано. Кто знает наверняка? (Тот, кто измеряет.)
Если вы заботитесь о сохранении каждого цикла, вы можете, вероятно, следует использовать другую стратегию в первую очередь. Возможно, управляемый код даже не является правильным выбором. Учитывая это, я рекомендую использовать более короткую форму и не использовать дополнительную проверку.
строку.Оператор Равенства или == внутренне называет string.Equals , Так что используйте string.Equals или == предусмотренных рамках. Он уже достаточно оптимизирован.
сначала сравните ссылки, затем длину, а затем фактические символы.
вы можете найти исходный код здесь
сравните 10000 строк с 10000 другими строками одинаковой длины (256)
время (s1 == s2): 32536889 тиков
время (s1.Длина == С2.Длина) & & (s1 == s2): 37380529 тиков
сравните 10000 строк с 10000 другими строками случайной длины max 256
время (s1 == s2): 27223517 тиков
время (s1.Длина == С2.Длина) & & (s1 == s2): 23419529 клещи!—1—>
сравните 10000 строк с 10000 другими строками случайной длины min 256 max 512
время (s1 == s2): 28904898 тиков
время (s1.Длина == С2.Длина) & & (s1 == s2): 25442710 тиков
что я нахожу ошеломляющим, так это то, что сравнение 10000 строк одинаковой длины займет больше времени, чем сравнение того же объема данных, который больше.
все эти испытания были сделаны с точно такими же данными.
согласно ILSpy, строка == оператор определяется как:
, который определяется как
Я предполагаю, что сначала a == b на самом деле является проверкой равенства ссылок (ILSpy просто отображает его как == ), иначе это был бы бесконечно рекурсивный метод.
это означает, что == уже проверяет длину строк, прежде чем фактически сравнивать их символы.
в завершенных строках имеет смысл просто начать сравнение символов, так как вы не можете вычислить длину строки без итерации всех символов в любом случае, и сравнение, вероятно, рано выйдет.
С длиной подсчитанных строк, сравнение длины должно быть сделано в первую очередь,если вы тестируете для байтового равенства. Вы даже не можете начать доступ к символьным данным без получения длины, так как один может быть нулевой длины.
Если вы выполняйте реляционное сравнение, зная, что длины разные, не говорит вам, должен ли результат быть положительным или отрицательным. И в сравнении с культурой равные строки не подразумевают равной длины. Поэтому для обоих из них вам нужно просто сравнить данные.
Если operator==(string, string) просто делегирует реляционное сравнение, вы не ожидали бы, что для сравнения длин. Таким образом, проверка длины перед выполнением сравнения может быть полезной. Но похоже, что фреймворк делает начните с проверки длины.
для вундеркиндов среди нас, вот страница который отлично справляется с бенчмаркингом многочисленные способы сравнения строк.
в двух словах, самый быстрый метод, по-видимому, является CompareOrdinal:
второй лучший способ-использовать словарь или Hashset с «ключом» в качестве строки, которую вы хотите сравнить.
делает для интересного чтения.
Я бы сказал, что первый быстрее является результатом string1.Length == string2.Length ложно. Благодаря короткому замыканию Evalution (SCE) фактическое сравнение между строками затем не производится, что может сэкономить ваше время.
Если строки равны, однако, первый медленнее, так как он сначала проверит длину, а затем сделает то же самое, что и второй.
Итак, как я и обещал, я написал короткий код с секундомером — вы можете скопировать вставить его и попробовать на разных строках и увидеть различия
- когда я проверил некоторые строки (короткие и длинные), я увидел, что все результаты почти одинаковы. Таким образом, первый if (с проверкой длины) медленнее в 2/3.
- и у вас есть метод Equals в классе Object, просто использовать это 🙂
- вы можете попробовать и дать нам результаты тоже 🙂
Если вы ожидаете, что строки будут отличаться по длине в большинстве случаев, вы можете сравнить их длины и затем сравните сами строки с помощью string.Compare . Я получил почти 50% улучшение производительности, делая это:
в этом случае я ожидаю, что строки будут отличаться почти все время, я думаю, str1.Длина намного дешевле, чем сравнение фактических строк. Если они равны по размеру, я сравниваю их.
редактировать: Забудь, что я сказал. Просто используйте == и быть счастливым.
Обучение C#
Работая с этим сайтом, Вы даете согласие на использование файлов Cookie.
Класс String для работы со строками
Инициализация строк
Для инициализации символьных строк используются строковые литералы, то есть последовательности символов, заключенные в двойные кавычки. Кроме символов строковый литерал может содержать Escape-последовательности – специальные символы, которые начинаются с обратного слеша ( \ ), после которого следует обозначение символа.
Перечень основных Escape-последовательностей приведен в таблице
| Escape-последовательность | Значение |
|---|---|
| \a | Звонок (предупреждение) |
| \b | Удаление предыдущего символа |
| \f | Перевод страницы |
| \n | Новая строка |
| \r | Возврат каретки |
| \t | Горизонтальная табуляция |
| \v | Вертикальная табуляция |
| \’ | Одиночная кавычка |
| \» | Двойная кавычка |
| \\ | Обратный слеш |
| \? | Вопросительный знак |
| \xhhhh | Символ Юникода в шестнадцатеричном формате, где hhhh – собственно код символа |
| \udddd | Символ Юникода (dddd) |
Escape-последовательности используются, например, для перевода строки или отступа в виде символа табуляции.
Если необходимо задать строку без Escape-последовательностей, то можно применить буквальный строковый литерал, обозначаемый префиксом @ , после которого размещается неизменяемая последовательность символов в двойных кавычках. Такой литерал может размещаться в коде на нескольких строчках, и это размещение сохранится при выводе.
Примеры инициализации объектов типа string .

Кроме того, при формировании строк очень часто используется перегруженный оператор + , который осуществляет слияние строк:

Класс string содержит ряд конструкторов для инициализации строк, которые позволяют сформировать строку из массива символов типа char или его части.
Также можно сформировать строку из последовательности одинаковых символов.

Основным свойством любой строки является свойство Length , которое позволяет получить количество символов в строке.
По сути строка представляет собой массив символов, обратиться к каждому из которых можно с использованием индекса этого элемента.

Кроме того, класс String обладает рядом методов, основные из которых будут рассмотрены ниже.
Сравнение и копирование строк
Метод Compare() является статическим методом класса String и позволяет посимвольно сравнить две строки или подстроки. Возвращаемое значение метода равно 0 в случае равенства строк. Пример использования этого метода:

Статический метод Copy() позволяет создать копию строки, указанной в качестве аргумента.
Для проверки, содержат ли строки одинаковые последовательности символов, может использоваться метод Equals() , имеющий как статический, так и нестатический вариант использования. Пример использования методов:

Изменение регистра букв в строке
Для изменения регистра букв, используемых в строке, можно использовать методы ToUpper() и ToLower() , приводящие все буквы строки соответственно в верхнему или нижнему регистру.

Работа с подстрокой в строке
Для формирования подстроки может использоваться метод Substring() , который формирует подстроку начиная с заданной позиции или начиная с заданной позиции указанной длины.

- Contains(подстрока) – проверяет, содержит ли данная строка подстроку, указанную в качестве аргумента, возвращает логическое значение true или false .
- IndexOf(подстрока) – возвращает индекс первого вхождения подстроки в данную строку. Если вхождений нет, возвращается -1.
- LastIndexOf(подстрока) – возвращает индекс последнего вхождения подстроки в данную строку. Если вхождений нет, возвращается -1.
- Replace(подстрока1, подстрока2) – заменяет все вхождения подстроки1 подстрокой2.
- StartsWith(подстрока) – проверяет, совпадает ли начало строки с указанной подстрокой.
- EndsWith(подстрока) – проверяет, совпадает ли конец строки с указанной подстрокой.

Удаление и добавление подстрок
- Remove(Позиция, ЧислоСимволов) — удаляет заданное число символов из строки начиная с указанной позиции. Если число символов не указано, то строка завершится на указанной позиции.
- Insert(Позиция, подстрока) – вставляет подстроку в строку начиная с указанной позиции.

Разделение и объединение строк
Для разделения строки на подстроки и сохранения их в массив используется метод Split() , в качестве аргумента которому передается символ-разделитель. По умолчанию в качестве символа разделителя используется пробел.
Для объединения строк в единую строку используется статический метод Join() , в качестве аргументов которому передаются строка-разделитель и массив строк, которые необходимо объединить через указанный разделитель.
Рассмотрим пример – посчитать количество слов во введенной строке.
Разделим строку на слова, посчитаем количество слов. Затем выведем массив слов и объединим слова снова в единую строку, используя в качестве разделителя строку " | " .

Однако если слова разделяются не одним, а несколькими пробелами, то количество элементов в массиве s2 будет больше, чем количество слов:

Метод Split() содержит перегрузку, позволяющую указать, что пустые строки из формируемого массива следует удалить – опция StringSplitOptions .RemoveEmptyEntries . Однако в этом случае в качестве разделителя необходимо указать массив символов или строк.

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

Форматирование объектов
Класс String содержит статический метод Format( String , Object ) , который позволяет перевести указанный объект в строковое представление в соответствии с форматом, указанным в форме строки в качестве первого аргумента. Однако различные типы значений имеют различные форматы представления, и это – тема для отдельной статьи.
Закрепить использование строк Вы можете в разделе Строки курса Алгоритмика
Автор: Вставская Елена Владимировна
Начинаем практику по языку C#
Чтобы стать хорошим программистом — нужно писать программы. На нашем сайте очень много практических упражнений.
После заполнения формы ты будешь подписан на рассылку «C# Вебинары и Видеоуроки», у тебя появится доступ к видеоурокам и консольным задачам.
Несколько раз в неделю тебе будут приходить письма — приглашения на вебинары, информация об акциях и скидках, полезная информация по C#.
Ты в любой момент сможешь отписаться от рассылки.
Основатель проекта
Волосатов Евгений
formulist@gmail.com Рекламодателям
Вебинары C#
+ Бесплатно, каждую субботу
+ Создание программ с нуля
+ Решение консольных задач
Видео-уроки
+ 300 практических видеоуроков
+ 400 интерактивных задач
+ Видео-решения и разбор
Миссия
Погружение в язык C#
Мотивация к изучению языка
Прокачка навыков программирования