Нечёткое сравнение строк: пойми меня, если сможешь
Содержание:
Операторы сравнения
Операторы сравнения – это операторы, которые сравнивают значения и возвращают 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