Нечёткое сравнение строк: пойми меня, если сможешь
Содержание:
Операторы сравнения
Операторы сравнения – это операторы, которые сравнивают значения и возвращают true или false. При сравнении строк в Bash вы можете использовать следующие операторы:
- string1 = string2 и string1 == string2- Оператор равенства возвращает true, если операнды равны.
- Используйте =оператор с test командой [.
- Используйте ==оператор с командой [[ для сопоставления с образцом.
- string1 != string2 – Оператор неравенства возвращает true, если операнды не равны.
- string1 =~ regex- Оператор регулярного выражения возвращает true, если левый операнд соответствует расширенному регулярному выражению справа.
- string1 > string2 – Оператор «больше чем» возвращает истину, если левый операнд больше правого, отсортированного по лексикографическому (алфавитному) порядку.
- string1 < string2 – Оператор less than возвращает true, если правый операнд больше правого, отсортированного по лексикографическому (алфавитному) порядку.
- -z string – Истина, если длина строки равна нулю.
- -n string – Истина, если длина строки не равна нулю.
Ниже следует отметить несколько моментов при сравнении строк:
- Пустое пространство должно быть использовано между бинарным оператором и операндами.
- Всегда используйте двойные кавычки вокруг имен переменных, чтобы избежать каких-либо проблем с разделением слов или сбоев.
- Bash не разделяет переменные по «типу», переменные обрабатываются как целое число или строка в зависимости от контекста.
Кодировка
Стандартной кодировкой .NET для символов и строк является UTF-16, а для потокового ввода-вывода — UTF-8.
Класс является базовым классом для типов, инкапсулирующих кодировки текста. Создать экземпляр можно с помощью статического метода , передав ему стандартное имя IANA:
C#
Encoding utf8 = Encoding.GetEncoding («utf-8»);
Encoding chinese = Encoding.GetEncoding («GB18030»);
|
1 2 |
Encoding utf8=Encoding.GetEncoding(«utf-8»); Encoding chinese=Encoding.GetEncoding(«GB18030»); |
Экземпляры наиболее распространенных кодировок также могут быть получены через статические свойства :
C#
Encoding.UTF8
Encoding.Unicode // utf-16
Encoding.UTF32
Encoding.ASCII
|
1 2 3 4 |
Encoding.UTF8 Encoding.Unicode // utf-16 Encoding.UTF32 Encoding.ASCII |
Статический метод возвращает список всех поддерживаемых кодировок:
C#
foreach (EncodingInfo info in Encoding.GetEncodings())
Console.WriteLine (info.Name);
|
1 2 |
foreach(EncodingInfo info inEncoding.GetEncodings()) Console.WriteLine(info.Name); |
Также экземпляр можно создать с помощью конструктора. В этом случае можно задать дополнительные параметры, передав необходимые аргументы.
Другие решения
Ты не работаешь со строками. Вы работаете с указателями. указатель на символ (). Это не строка. Если он завершен нулем, то некоторые функции C будут лечить это как строка, но в основном это просто указатель.
Поэтому, когда вы сравниваете его с массивом char, массив также распадается на указатель, и затем компилятор пытается найти ,
Такой оператор существует. Требуется два указателя и возврат если они указывают на один и тот же адрес. Таким образом, компилятор вызывает это, и ваш код ломается.
Если вы хотите сделать сравнение строк, вы должны указать компилятору, с которым вы хотите иметь дело строки, не указатели.
C способ сделать это состоит в том, чтобы использовать функция:
Это вернет ноль, если две строки равный. (Будет возвращено значение больше нуля, если левая сторона лексикографически больше правой стороны, а значение меньше нуля в противном случае.)
Поэтому для сравнения на равенство нужно сделать одно из следующих:
Тем не менее, C ++ имеет очень полезный учебный класс. Если мы используем это, ваш код становится немного проще. Конечно, мы можем создавать строки из обоих аргументов, но нам нужно сделать это только с одним из них:
Теперь компилятор встречает сравнение между строкой и указателем на символ. Он может справиться с этим, потому что указатель на символ может быть неявно преобразован в строку, что дает сравнение строк / строк. И они ведут себя именно так, как вы ожидаете.
16
«Дев» не является это лайк , Таким образом, вы действительно сравниваете адреса памяти. Быть тем указатель на символ, это один символ (точнее, первый символ указанной последовательности символов). Вы не можете сравнить char с указателем char, поэтому это не сработало.
Поскольку это помечено как c ++, было бы целесообразно использовать вместо указателей на символы, которые заставят == работать как положено. (Вам просто нужно сделать вместо ,
Ваше мнение об этой программе ниже
когда вы должны думать о вводе чего-либо в массив & затем используйте функции strcmp, как в приведенной выше программе … ознакомьтесь с измененной программой ниже
изменить на строку, за исключением того, что он читает только 1 вход и выбрасывает остальные
может понадобиться два для циклов и два указателя
Declaration
Following is the declaration for std::string.
Member types
| member type | definition |
|---|---|
| value_type | char |
| traits_type | char_traits<char> |
| allocator_type | allocator<char> |
| reference | char& |
| const_reference | const char& |
| pointer | char* |
| const_pointer | const char* |
| iterator | a random access iterator to char (convertible to const_iterator) |
| const_iterator | a random access iterator to const char |
| reverse_iterator | reverse_iterator<iterator> |
| const_reverse_iterator | reverse_iterator<const_iterator> |
| difference_type | ptrdiff_t |
| size_type | size_t |
Member functions
| Sr.No. | Member function & description |
|---|---|
| 1 |
(constructor)
It constructs string object. |
| 2 |
(destructor)
It is a string destructor. |
| 3 |
operator=
It is a string assignment. |
Iterators
| Sr.No. | Iterator & description |
|---|---|
| 1 |
begin
It returns iterator to beginning. |
| 2 |
end
It returns iterator to end. |
| 3 |
rbegin
It returns reverse iterator to reverse beginning. |
| 4 |
rend
It returns reverse iterator to reverse end. |
| 5 |
cbegin
It returns const_iterator to beginning. |
| 6 |
cend
It returns a const_iterator pointing to the past-the-end character of the string. |
| 7 |
crbegin
It returns const_reverse_iterator to reverse beginning. |
| 8 |
crend
It returns const_reverse_iterator to reverse end. |
Capacity
| Sr.No. | Capacity & description |
|---|---|
| 1 |
size
It returns length of string. |
| 2 |
length
It returns length of string. |
| 3 |
max_size
It returns maximum size of string. |
| 4 |
resize
It resizes string. |
| 5 |
capacity
It returns size of allocated storage. |
| 6 |
reserve
It requests a change in capacity. |
| 7 |
clear
It clears the string. |
| 8 |
empty
It is used to test if string is empty. |
| 9 |
shrink_to_fit
It is used to shrink to fit. |
Capacity
| Sr.No. | Element acce & description |
|---|---|
| 1 |
operator[]
It is used to get character of string. |
| 2 |
at
It is used to get character in string. |
| 3 |
back
It is used to access last character. |
| 4 |
front
It is used to access first character. |
Modifiers
| Sr.No. | Modifier & description |
|---|---|
| 1 |
operator+=
It appends to string. |
| 2 |
append
It appends to string. |
| 3 |
push_back
It appends a character to string. |
| 4 |
assign
It is used to assign the content to string. |
| 5 |
insert
It is used to inset the value to string. |
| 6 |
erase
It is used to erase characters from string. |
| 7 |
replace
It is used to replace portion of string. |
| 8 |
swap
It is used to swap string values. |
| 9 |
pop_back
It is used to delete last character. |
String operations
| Sr.No. | String operation & description |
|---|---|
| 1 |
c_str
It is used to get C string equivalent. |
| 2 |
data
It is used to get string data. |
| 3 |
get_allocator
It is used to get an allocator. |
| 4 |
copy
It is used to copy sequence of characters from string. |
| 5 |
find
It is used to find content in string. |
| 6 |
rfind
It is used to find last occurrence of content in string. |
| 7 |
find_first_of
It is used to find character in string. |
| 8 |
find_last_of
It is used to find character in string from the end. |
| 9 |
find_first_not_of
It is used to find absence of character in string. |
| 10 |
find_last_not_of
It is used to find non-matching character in string from the end. |
| 11 |
substr
It is used to generate substring. |
| 12 |
compare
It is used to compare strings. |
Previous Page
Print Page
Next Page
Поиск в строке и перечисление
Строковой индексатор возвращает символ с указанной позицией:
C#
Console.Write («word»); // r
| 1 | Console.Write(«word»2);// r |
реализует интерфейс , поэтому по символам строки можно проходить с помощью :
C#
foreach (char c in «123») Console.Write (c + «,»); // 1,2,3,
| 1 | foreach(charcin»123″)Console.Write(c+»,»);// 1,2,3, |
Простейшими методами для выполнения поиска в строке являются , , и , все они возвращают или :
C#
Console.WriteLine («quick brown fox«.Contains («brown»)); // True
Console.WriteLine («quick brown fox».EndsWith («fox»)); // True
|
1 2 |
Console.WriteLine(«quick brown fox».Contains(«brown»));// True Console.WriteLine(«quick brown fox».EndsWith(«fox»));// True |
Метод возвращает позицию первого вхождения заданного символа или подстроки (или если символ или подстрока не найдены):
C#
Console.WriteLine («abcde».IndexOf(«cd»)); // 2
| 1 | Console.WriteLine(«abcde».IndexOf(«cd»));// 2 |
Методы , и перегружены и могут принимать или объект , чтобы управлять чувствительность к регистру и культуре:
C#
«abcdef».StartsWith(«abc», StringComparison.InvariantCultureIgnoreCase)
| 1 | «abcdef».StartsWith(«abc»,StringComparison.InvariantCultureIgnoreCase) |
Метод также может принимать — индекс, с которого должен начинаться поиск.
Метод похож на , но ищет начиная с конца строки.
Метод возвращает позицию первого вхождения любого символа из набора, а метод делает тоже самое в обратном направлении:
C#
Console.Write («ab,cd ef».IndexOfAny (new char[] {‘ ‘, ‘,’} )); // 2
Console.Write («pas5w0rd».IndexOfAny («0123456789».ToCharArray() )); // 3
|
1 2 |
Console.Write(«ab,cd ef».IndexOfAny(newchar{‘ ‘,’,’}));// 2 Console.Write(«pas5w0rd».IndexOfAny(«0123456789».ToCharArray()));// 3 |
Новые возможности операторов
A x < y(x <=> y) < 0== <=>== <
| Равенство | Упорядочение | |
| Базовые | == | <=> |
| Производные | != | <, >, <=, >= |
Обращение базовых операторов
int
a == 10a.operator==(10)10 == aoperator==intA10 == aoperator==(A, int)operator==(int, A)10 == aa.operator==(10)int
a <=> 42a.operator<=>(42)42<=> <=> operator<=>operator==42 <=>operator<=>(A, int)operator<=>(int, A)42 <=>a a.operator<=>(42)0 <=> a.operator<=>(42)10 == aoperator==(int, A)42 <=> aoperator<=>(int, A)
Переписывание производных операторов
A
a != 17operator!=!= ==a!= 17operator!=operator==operator==a != 17!(a == 17)17 !=!a.operator==(17)a < 9operator<operator<=>a @ b @ (a <=> b) @ 0a.operator<=>(9) < 09 <= a0 <= a.operator<=>(9)ТОЛЬКО БАЗОВЫЕ ОПЕРАТОРЫ: В своём типе определяйте только базовые операторы (== и <=>).std::sub_match
Особые правила поиска кандидатов
a @ boperator@ operator@@@ @ operator@@ один-единственный
x != yx.operator!=(y)!x.operator==(y)!y.operator==(x)y.operator!=(x) x.operator!=(y) !x.operator==(y)!y.operator==(x)operator@@x < y(x <=> y) < 0x <=> yvoid booloperator== bool
d1 < d2#1 #2#2d1 < d2(d1 <=> d2) < 0void #1
Краткий обзор правил
- Обращение доступно только для базовых операторов
- Переписываться могут только производные операторы (через соответствующие базовые)
- При поиске кандидатов за один проход ищутся все операторы с данным именем, а также все их обращённые и переписанные версии
- Если наилучший кандидат является переписанной или обращённой версией и при этом такая замена является недопустимой, программа считается некорректной.
ТОЛЬКО БАЗОВЫЕ ОПЕРАТОРЫ
| Исходная операция | Вариант 1 | Вариант 2 |
| a == b | b == a | |
| a != b | !(a == b) | !(b == a) |
| a <=> b | 0 <=> (b <=> a) | |
| a < b | (a <=> b) < 0 | (b <=> a) > 0 |
| a <= b | (a <=> b) <= 0 | (b <=> a) >= 0 |
| a > b | (a <=> b) > 0 | (b <=> a) < 0 |
| a >= b | (a <=> b) >= 0 | (b <=> a) <= 0 |
a < b 0 < (b <=> a)
Похожесть двух строк
Задача: есть две строки, требуется вычислить степень их похожести числом от 0 до 100
В FuzzyWuzzy для этого есть несколько функций, отличающихся подходом к сравнению и вниманием к деталям. Не забудем импортировать:
from fuzzywuzzy import fuzz
Функция – простое посимвольное сравнение. Рейтинг 100 только если строки полностью равны, любое различие уменьшает рейтинг, будь то знаки препинания, регистр букв, порядок слов и так далее:
>>> fuzz.ratio("я люблю спать", "я люблю спать")
100
>>> fuzz.ratio("я люблю спать", "Я люблю cпать!")
81
>>> fuzz.ratio("я люблю спать", "я люблю есть")
88
Обратите внимание, что рейтинг второго примера ниже, чем у третьего, хотя по смыслу должно быть наоборот. Следующая функция решает эту проблему
Теперь акцент именно на сами слова, игнорируя регистр букв, порядок слов и даже знаки препинания по краям строки
Следующая функция решает эту проблему. Теперь акцент именно на сами слова, игнорируя регистр букв, порядок слов и даже знаки препинания по краям строки.
>>> fuzz.token_sort_ratio("я люблю спать", "я люблю есть")
56
>>> fuzz.token_sort_ratio("я люблю спать", "Я люблю спать!")
100
>>> fuzz.token_sort_ratio("я люблю спать", "спать люблю я...")
100
>>> fuzz.token_sort_ratio("Мал да удал", "удал да МАЛ")
100
>>> fuzz.token_sort_ratio("Мал да удал", "Да Мал Удал")
100
Однако, смысл пословицы немного изменился, а рейтинг остался на уровне полного совпадения.
Функция пошла еще дальше: она игнорирует повторяющиеся слова, учитывает только уникальные.
>>> fuzz.token_set_ratio("я люблю спать", "люблю я спать, спать, спать...")
100
>>> fuzz.token_set_ratio("я люблю спать", "люблю я спать, спать и спать...")
100
>>> fuzz.token_set_ratio("я люблю спать", "но надо работать")
28
# повторы в token_sort_ratio роняют рейтинг!
>>> fuzz.token_sort_ratio("я люблю спать", "люблю я спать, спать и спать.")
65
# но вот это странно:
>>> fuzz.token_set_ratio("я люблю спать", "люблю я спать, но надо работать")
100
>>> fuzz.token_set_ratio("я люблю спать", "люблю я спать, люблю я есть")
100
Последние два примера вернули 100, хотя добавлены новые слова, и это странно. Тут следует вспомнить о , которая ведет себя также. А именно, проверяет вхождение одной строки в другую. Лишние слова игнорируются, главное – оценить, чтобы ядро было одно и тоже.
>>> fuzz.partial_ratio("одно я знаю точно", "одно я знаю")
100
>>> fuzz.partial_ratio("одно я знаю точно", "одно я знаю!")
92
>>> fuzz.partial_ratio("одно я знаю точно", "я знаю")
100
Еще еще более навороченный метод , который работает ближе к человеческой логике, комбинируя несколько методов в один алгоритм в определенными весами (отсюда и название WRatio = Weighted Ratio).
>>> fuzz.WRatio("я люблю спать", "люблю Я СПАТЬ!")
95
>>> fuzz.WRatio("я люблю спать", "люблю Я СПАТЬ и есть")
86
>>> fuzz.WRatio("я люблю спать", "!!СПАТЬ ЛЮБЛЮ Я!!")
95
Нечеткий поиск
Задача: найти в списке строк одну или несколько наиболее похожих на поисковый запрос.
Импортируем подмодуль и применим или :
from fuzzywuzzy import process
strings =
process.extract("Прив", strings, limit=3)
#
process.extractOne("Прив", strings)
# ('привет', 90)
Удаление дубликатов
Очень полезная функция для обработки данных. Представьте, что вам досталась 1С база номенклатуры запчастей, там полный бардак, и вам нужно поудалять лишние повторяющиеся позиции товара, но где-то пробелы лишние, где-то буква перепутана и тому подобное. Тут пригодится .
Первый аргумент – исходный список, второй – порог исключения (70 по умолчанию), третий – алгоритм сравнения (token_set_ratio по умолчанию).
Пример:
arr = print(list(process.dedupe(arr))) #
FuzzyWuzzy можно применять совместно с Pandas. Например так (без особых подробностей):
def get_ratio(row):
name = row['Last/Business Name']
return fuzz.token_sort_ratio(name, "Alaska Sea Pilot PAC Fund")
df
Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway
230