Сравнение строк в C: все тонкости и нюансы
C - один из самых популярных языков программирования в мире. Работа со строками - важная часть любой программы на C. В этой статье мы подробно разберем все аспекты сравнения строк в C: от базовых функций до сложных алгоритмов и оптимизаций. Узнаете, как правильно выбрать подход, избежать типичных ошибок и написать эффективный код для сравнения строк. Погружаемся в увлекательный мир строк в C!
Базовые функции сравнения строк в C
Одним из основных способов сравнения строк в C является использование встроенных библиотечных функций. Рассмотрим самые популярные из них.
Функция strcmp()
Эта функция определена в заголовочном файле string.h и является основным способом сравнения строк в C.
Синтаксис выглядит так:
int strcmp(const char *str1, const char *str2);
strcmp сравнивает две строки посимвольно, сравнивая коды символов. Возвращает 0, если строки одинаковы, положительное число, если str1 > str2, и отрицательное, если str1 < str2.
char str1[] = "hello"; char str2[] = "hello"; int result = strcmp(str1, str2); // 0 char str3[] = "apple"; char str4[] = "banana"; result = strcmp(str3, str4); // отрицательное число
Таким образом strcmp удобно использовать для сравнения слов в лексикографическом порядке.
Другие функции сравнения
Помимо strcmp(), есть и другие полезные функции:
- strncmp() - сравнивает первые n символов строк
- strcoll() - сравнивает строки с учетом правил локали
- memcmp() - сравнивает определенное количество байт в памяти
Эти функции полезны в специфических случаях, например при сравнении подстрок или строк на разных языках.
Сравнение строк без функций
Сравнить строки в C можно и без использования специальных функций. Рассмотрим два распространенных способа.
Посимвольное сравнение в цикле
Можно написать простой цикл, который будет сравнивать символы строк:
int compareStrings(char *str1, char *str2) { int i = 0; while(str1[i] != '\0' && str2[i] != '\0') { if(str1[i] < str2[i]) return -1; if(str1[i] > str2[i]) return 1; i++; } return 0; }
Этот подход прост в реализации, но менее эффективен при работе с большими строками.
Использование указателей
Другой вариант - сравнивать строки при помощи указателей:
int stringCmp(char *str1, char *str2) { while(*str1 && *str2) { if(*str1 != *str2) return *str1 - *str2; str1++; str2++; } return 0; }
Здесь мы получаем символы по указателям и сравниваем их коды.
Оптимизация сравнения строк
При работе с очень большими строками стандартные функции могут работать неэффективно. Давайте рассмотрим способы оптимизации.
Хеширование строк
Один из подходов - вычислить хеш-коды строк и сравнить их. Это значительно быстрее прямого сравнения символов.
unsigned long hash(char *str) { unsigned long hash = 5381; int c; while (c = *str++) hash = ((hash << 5) + hash) + c; return hash; } bool stringEquals(char *s1, char *s2) { return hash(s1) == hash(s2); }
Главный минус - возможность коллизий хешей.
Алгоритм Кнута-Морриса-Пратта
Этот алгоритм использует заранее построенную таблицу частичного совпадения, чтобы пропускать символы в строке. Это позволяет достичь линейной сложности алгоритма.
int KMPSearch(char *txt, char *pat) { int n = strlen(txt); int m = strlen(pat); // создаем таблицу префиксов int lps[m]; computeLPSArray(pat, m, lps); int i = 0; int j = 0; while (i < n) { if (pat[j] == txt[i]) { j++; i++; } if (j == m) { return i-j; } // несовпадение, используем таблицу else if (i < n && pat[j] != txt[i]) { if (j != 0) j = lps[j-1]; else i = i+1; } } return -1; }
Типичные ошибки при сравнении строк
Рассмотрим распространенные ошибки, которые встречаются при сравнении строк в Си.
Неверная обработка результата функций
Например, если перепутать порядок сравнения:
if(strcmp(str1, str2) > 0) { // на самом деле надо наоборот }
Или неправильно интерпретировать 0 как равенство строк.
Проблемы с регистром символов
По умолчанию Си чувствителен к регистру. Нужно явно преобразовывать символы:
for(int i = 0; str[i]; i++) str[i] = tolower(str[i]);
Неизвестная кодировка
Строки в Си обычно в ASCII. При работе с Unicode нужно использовать специальные функции mbscmp().
Мы рассмотрели различные способы сравнения строк в Си - от простых встроенных функций до сложных алгоритмов. Для оптимального решения нужно учитывать особенности данных и задачи. Тщательное тестирование поможет избежать типичных ошибок.