1 (изменено: Phoenixxx_Czar, 2021-04-04 06:30:19)

Тема: AHK: Метод SIFT3, добавить поддержку русских символов

Мне нужно узнать разницу между двумя строками, я взял код отсюда: https://autohotkey.com/board/topic/5498 … algorithm/.
Но я заметил, что есть разница между русскими и англ буквами, точнее разница между регистром.

stringDiff(string1, string2, maxOffset = 5)
{
	if (string1 = string2)
		return (string1 == string2 ? 0/1 : 0.2/StrLen(string1))
	if (string1 = "" OR string2 = "")
		return (string1 = string2 ? 0/1 : 1/1)

	StringSplit, n, string1
	StringSplit, m, string2

	ni := 1, mi := 1, lcs := 0
	While((ni <= n0) AND (mi <= m0)) 
	{
		if (n%ni% == m%mi%)
			EnvAdd, lcs, 1
		else if (n%ni% = m%mi%)
			EnvAdd, lcs, 0.8
		else
		{
			Loop, %maxOffset%	
			{
				oi := ni + A_Index, pi := mi + A_Index
				if ((n%oi% = m%mi%) AND (oi <= n0))
				{
					ni := oi, lcs += (n%oi% == m%mi% ? 1 : 0.8)
					Break
				}
				if ((n%ni% = m%pi%) AND (pi <= m0))
				{
					mi := pi, lcs += (n%ni% == m%pi% ? 1 : 0.8)
					Break
				}
			}
		}
		EnvAdd, ni, 1
		EnvAdd, mi, 1
	}
	return ((n0 + m0)/2 - lcs) / (n0 > m0 ? n0 : m0)
}

msgbox, % stringDiff("AHK", "AhK")
msgbox, % stringDiff("АХК", "АхК")

Что можно придумать? Я так понимаю дело в "=" и "==", оно работает только на англ буквы (как "i" в регулярных выражениях).

В идеале иметь возможность включать/выключать поддержку регистра (то есть, чтобы буквы в разном регистре считались за разные, а не за 0.8).

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

2

Re: AHK: Метод SIFT3, добавить поддержку русских символов

Добавьте первой строчкой

StringCaseSense, Locale
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Метод SIFT3, добавить поддержку русских символов

Да, это сработало, а как теперь можно сделать по умному отключение независимость регистра?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

4

Re: AHK: Метод SIFT3, добавить поддержку русских символов

Попробуйте ввести дополнительный параметр, который будет регулировать, что будет применяться, == или =.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5 (изменено: Phoenixxx_Czar, 2021-04-04 09:11:30)

Re: AHK: Метод SIFT3, добавить поддержку русских символов

Мне непонятно значение 0.2 в первом ифе, что оно значит.. фиг поймешь.
Вроде работает как нужно.. Но как это можно нормально записать?

stringDiff(string1, string2, ignoreRegister := 1, maxOffset = 5)
{
	StringCaseSense, Locale

	if (ignoreRegister && string1 = string2)
		return (string1 == string2 ? 0 : 0.2 / StrLen(string1))
	if (string1 = "" || string2 = "")
		return (string1 = string2 ? 0 : 1)

	StringSplit, n, string1
	StringSplit, m, string2

	ni := 1, mi := 1, lcs := 0
	While((ni <= n0 && mi <= m0))
	{
		if (n%ni% == m%mi%)
			EnvAdd, lcs, 1
		else if (ignoreRegister && n%ni% = m%mi%)
			EnvAdd, lcs, 0.8
		else
		{
			Loop, %maxOffset%	
			{
				oi := ni + A_Index, pi := mi + A_Index
				if (n%oi% = m%mi% && oi <= n0)
				{
					ni := oi, lcs += (n%oi% == m%mi% ? 1 : (ignoreRegister ? 0.8 : 0))
					Break
				}
				if ((n%ni% = m%pi% && pi <= m0))
				{
					mi := pi, lcs += (n%ni% == m%pi% ? 1 : (ignoreRegister ? 0.8 : 0))
					Break
				}
			}
		}
		EnvAdd, ni, 1
		EnvAdd, mi, 1
	}
	return ((n0 + m0)/2 - lcs) / (n0 > m0 ? n0 : m0)
}

strings := [["AHK", "AHK"], ["AHK", "AhK"], ["Тест", "Тест"], ["Тест", "ТЕСТ"], ["Тест", "ТеСт"]]

out := ""
loop, 2
{
	ingnoreRegister := A_Index - 1
	out .= (A_Index == 2 ? "`n" : "") "Ingore register: " ingnoreRegister "`n"
	
	for k, v in strings
	{
		out .= v[1] " - " v[2] "`t" stringDiff(v[1], v[2], ingnoreRegister) "`n"
	}
}

msgbox, % out
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

6

Re: AHK: Метод SIFT3, добавить поддержку русских символов

Если работает, то и так нормально, разбираться не особо интересно. Хотите лучше понять — читайте про алгоритм Левенштейна.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder