Сравниение строк
От: hsc Украина  
Дата: 27.07.17 13:24
Оценка:
С++, Windows, VS2012. Есть пары строк, например "Amélie" и "Amelie", "Ёлка" и "Елка" и т. п. Строки приходят из двух разных источников. Надо сравнивать строки считая что é=e, Ё=Е и т.д.

Нужна функция
  bool my_compare(const std::wstring& s1, const std::wstring& s2);


которая вернёт
для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false

Возможно заказчик составит список какие именно символы считать эквивалентами, но вдруг есть какое-то универсальное решение?
Отредактировано 27.07.2017 13:38 hsc . Предыдущая версия .
Re: Сравниение строк
От: TimurSPB Интернет  
Дата: 27.07.17 13:28
Оценка: -1
hsc>С++, Windows, VS2012. Есть пары строк, например "Amélie" и "Amelie", "Ёлка" и "Елка" и т. п. Строки приходят из двух разных источников. Надо сравнивать строки считая что é=e, Ё=Е и т.д. Возможно заказчик составит список какие именно символы считать эквивалентами, но вдруг есть какое-то универсальное решение?

https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0 — универсальное.
Make flame.politics Great Again!
Re[2]: Сравниение строк
От: hsc Украина  
Дата: 27.07.17 13:37
Оценка:
Здравствуйте, TimurSPB, Вы писали:

hsc>>С++, Windows, VS2012. Есть пары строк, например "Amélie" и "Amelie", "Ёлка" и "Елка" и т. п. Строки приходят из двух разных источников. Надо сравнивать строки считая что é=e, Ё=Е и т.д. Возможно заказчик составит список какие именно символы считать эквивалентами, но вдруг есть какое-то универсальное решение?


TSP>https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0 — универсальное.


Эээээ.... Уточню задачу. Мне надо написать функцию
  bool my_compare(const std::wstring& s1, const std::wstring& s2);

которая вернёт
для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false
Re: Сравниение строк
От: Zhendos  
Дата: 27.07.17 14:02
Оценка:
Здравствуйте, hsc, Вы писали:

hsc>С++, Windows, VS2012. Есть пары строк, например "Amélie" и "Amelie", "Ёлка" и "Елка" и т. п. Строки приходят из двух разных источников. Надо сравнивать строки считая что é=e, Ё=Е и т.д.


hsc>Нужна функция

hsc>
hsc>  bool my_compare(const std::wstring& s1, const std::wstring& s2);
hsc>


hsc>которая вернёт

hsc>для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
hsc>для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false

hsc>Возможно заказчик составит список какие именно символы считать эквивалентами, но вдруг есть какое-то универсальное решение?


Я думаю стоит покапать в сторону нормализация юникода и связанных с этим,
например можно преобразовать "Amélie" в "Ame'lie", а потом пройтись циклом
и удалить эти добавочные символы.
Re[3]: Сравниение строк
От: TimurSPB Интернет  
Дата: 27.07.17 14:03
Оценка: 2 (1)
hsc>для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
hsc>для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false

Тогда загоняем обе строки в транслит и сравниваем результаты.
Это может сделать ICU http://userguide.icu-project.org/transforms/general#TOC-Using-Transliterators
Make flame.politics Great Again!
Re[2]: Сравниение строк
От: hsc Украина  
Дата: 27.07.17 14:13
Оценка:
Z>Я думаю стоит покапать в сторону нормализация юникода и связанных с этим,
Z>например можно преобразовать "Amélie" в "Ame'lie", а потом пройтись циклом
Z>и удалить эти добавочные символы.

Копал, есть такое. WinAPI NormalizeString. Но как отличить добавочные символы от основных?
Re[3]: Сравниение строк
От: Zhendos  
Дата: 27.07.17 14:20
Оценка: 2 (1)
Здравствуйте, hsc, Вы писали:

Z>>Я думаю стоит покапать в сторону нормализация юникода и связанных с этим,

Z>>например можно преобразовать "Amélie" в "Ame'lie", а потом пройтись циклом
Z>>и удалить эти добавочные символы.

hsc>Копал, есть такое. WinAPI NormalizeString. Но как отличить добавочные символы от основных?


Не уверен что она подойдет, вот так с помощью icu можно сделать:

https://stackoverflow.com/questions/2992066/code-to-strip-diacritical-marks-using-icu
Re[4]: Сравниение строк
От: hsc Украина  
Дата: 27.07.17 14:32
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Здравствуйте, hsc, Вы писали:


Z>>>Я думаю стоит покапать в сторону нормализация юникода и связанных с этим,

Z>>>например можно преобразовать "Amélie" в "Ame'lie", а потом пройтись циклом
Z>>>и удалить эти добавочные символы.

hsc>>Копал, есть такое. WinAPI NormalizeString. Но как отличить добавочные символы от основных?


Z>Не уверен что она подойдет, вот так с помощью icu можно сделать:


Z>https://stackoverflow.com/questions/2992066/code-to-strip-diacritical-marks-using-icu


Оно! Спасибо!
Re[5]: Сравниение строк
От: uzhas Ниоткуда  
Дата: 27.07.17 16:42
Оценка:
Здравствуйте, hsc, Вы писали:

Z>>https://stackoverflow.com/questions/2992066/code-to-strip-diacritical-marks-using-icu


hsc>Оно! Спасибо!


этот подход справится с буквой Ё ?
из вики:

Официального и общепринятого термина для выносного элемента, присутствующего в букве «ё», нет. Традиционное языкознание и педагогика использовали слово «двоеточие»[К 3], в последние же сто лет чаще всего обходятся менее формальным выражением «две точки»[К 4], либо вообще стараются избегать отдельного упоминания этого элемента[К 5]. Использование иноязычных терминов (умлаут, трема, диерезис или диалитика) применительно к данной ситуации считается некорректным, так как это диакритические знаки и прежде всего обозначают определённую фонетическую функцию, хотя, например, А. А. Реформатский их использовал[3].

Re[6]: Сравниение строк
От: Кодт Россия  
Дата: 28.07.17 10:58
Оценка:
Здравствуйте, uzhas, Вы писали:

U>этот подход справится с буквой Ё ?


Ладно ё = е с умлаутом. Причём по правилам (или обычаям?) русского языка допускается писать е вместо ё.
А ещё ведь есть й = и с бревисом.
(Кстати, некоторые япплочные программы любят вместо привычного всем композитного "й" подставлять "и" + "комбинаторный бревис").

Всегда ли нормализация й до и будет безболезненна? Ладно йод/иод, биткойн/биткоин, андройд/андроид.
Перекуём баги на фичи!
Re[7]: Сравниение строк
От: uzhas Ниоткуда  
Дата: 28.07.17 12:32
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Ладно ё = е с умлаутом.

ась? склоняешься к тому, что сработает?
Re[2]: Сравниение строк
От: Pzz Россия https://github.com/alexpevzner
Дата: 29.07.17 09:55
Оценка:
Здравствуйте, TimurSPB, Вы писали:

TSP>https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0 — универсальное.


Ему нужна функция, которая считает эквиавалентными символы с почти одинаковым написанием, а не сравнивает строки с учетом возможных опечаток.
Re: Сравниение строк
От: bnk СССР http://unmanagedvisio.com/
Дата: 30.07.17 17:54
Оценка: +2
Здравствуйте, hsc, Вы писали:

hsc>С++, Windows, VS2012. Есть пары строк, например "Amélie" и "Amelie", "Ёлка" и "Елка" и т. п. Строки приходят из двух разных источников. Надо сравнивать строки считая что é=e, Ё=Е и т.д.


hsc>Нужна функция

hsc>
hsc>  bool my_compare(const std::wstring& s1, const std::wstring& s2);
hsc>


hsc>которая вернёт

hsc>для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
hsc>для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false

hsc>Возможно заказчик составит список какие именно символы считать эквивалентами, но вдруг есть какое-то универсальное решение?


Если тебя только европейские языки интересуют, то букв с умляутами (или диакритических) немного — можно тупо в таблицу выписать (транслит)
Если ICU сильно тяжелая, и не нужна 200% корректность, можешь сюда глянуть:

  Код
static class Translit
{
    static Dictionary<Char, string> _translitMap = new Dictionary<char, string>();

    public static string TranslitString(string name)
    {
        var result = new StringBuilder();

        if (Char.IsDigit(name[0]))
            result.Append("_");

        for (int i = 0; i < name.Length; ++i)
            result.Append(TranslitChar(name[i]));

        return result.ToString();
    }

    const string _validChars =
        "._1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";

    const string _stringSrc =
        "а|б|в|г|д|е|ё|ж|з|и|й|к|л|м|н|о|п|р|с|т|у|ф|х|ц|ч|ш|щ|ъ|ы|ь|э|ю|я|А|Б|В|Г|Д|Е|Ё|Ж|З|И|Й|К|Л|М|Н|О|П|Р|С|Т|У|Ф|Х|Ц|Ч|Ш|Щ|Ъ|Ы|Ь|Э|Ю|Я|" +
        "á|ä|č|ď|é|ě|í|ľ|ĺ|ň|ó|ô|ř|ŕ|š|ť|ú|ů|ý|ž|Á|Ä|Č|Ď|É|Ě|Í|Ľ|Ĺ|Ň|Ó|Ô|Ř|Ŕ|Š|Ť|Ú|Ů|Ý|Ž|ß|" +
        "À|Á|Â|Ã|Ä|Å|" +
        "È|É|Ê|Ë|" +
        "Ì|Í|Î|Ï|" +
        "Ò|Ó|Ô|Õ|Ö|" +
        "Ù|Ú|Û|Ü|" +
        "Ý|Ç|Ć|Ĉ|" +
        "à|á|â|ã|ä|å|" +
        "è|é|ê|ë|" +
        "ì|í|î|ï|" +
        "ò|ó|ô|õ|ö|" +
        "ù|ú|û|ü|" +
        "ý|ç|ć|ĉ";

    const string _stringDst =
        "a|b|v|g|d|e|yo|zh|z|i|j|k|l|m|n|o|p|r|s|t|u|f|h|c|ch|sh|sh||y||e|yu|ya|A|B|V|G|D|E|Yo|Zh|Z|I|J|K|L|M|N|O|P|R|S|T|U|F|H|C|Ch|Sh|Sh||Y||E|Yu|Ya|" +
        "a|a|c|d|e|e|i|l|l|n|o|o|r|r|s|t|u|u|y|z|A|A|C|D|E|E|I|L|L|N|O|O|R|R|S|T|U|U|Y|Z|ss|" +
        "A|A|A|A|A|A|" +
        "E|E|E|E|" +
        "I|I|I|I|" +
        "O|O|O|O|O|" +
        "U|U|U|U|" +
        "Y|C|C|C|" +
        "a|a|a|a|a|a|" +
        "e|e|e|e|" +
        "i|i|i|i|" +
        "o|o|o|o|o|" +
        "u|u|u|u|" +
        "y|c|c|c";

    static string TranslitChar(Char ch)
    {
        if (_validChars.IndexOf(ch) >= 0)
            return ch.ToString();

        string result;
        if (_translitMap.TryGetValue(ch, out result))
            return result;

        return "_";
    }

    static Translit()
    {
        var src = _stringSrc.Split('|');
        var dst = _stringDst.Split('|');

        for (int i = 0; i < src.Length; ++i)
            _translitMap[src[i][0]] = dst[i];
    }
};
Re: Сравниение строк
От: cr8  
Дата: 30.07.17 18:50
Оценка:
Здравствуйте, hsc, Вы писали:

hsc>Нужна функция

hsc>
hsc>  bool my_compare(const std::wstring& s1, const std::wstring& s2);
hsc>


hsc>которая вернёт

hsc>для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
hsc>для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false

Операция сравнения строк с учетом локали называется collate. В стандартном С++ можно глянуть тут:

http://en.cppreference.com/w/cpp/locale/collate

В WinAPI можно покопаться здесь:

NormalizeString
https://msdn.microsoft.com/en-us/library/windows/desktop/dd319093(v=vs.85).aspx

CompareStringEx
https://msdn.microsoft.com/en-us/library/windows/desktop/dd317761(v=vs.85).aspx
Re[7]: Сравниение строк
От: MasterZiv СССР  
Дата: 31.07.17 14:58
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, uzhas, Вы писали= е с умлаутом. Причём по правилам (или обычаям?) русского языка допускается писать е вместо ё.

К>А ещё ведь есть й = и с бревисом.
К>(Кстати, некоторые япплочные программы любят вместо привычного всем композитного "й" подставлять "и" + "комбинаторный бревис").

К>Всегда ли нормализация й до и будет безболезненна? Ладно йод/иод, биткойн/биткоин, андройд/андроид.


Да ладно, Е и Ё и И и Й -- это всё разные буквы!
Re[3]: Сравниение строк
От: Kostya.  
Дата: 07.08.17 13:21
Оценка: -1
Здравствуйте, hsc, Вы писали:

hsc>Здравствуйте, TimurSPB, Вы писали:


hsc>>>С++, Windows, VS2012. Есть пары строк, например "Amélie" и "Amelie", "Ёлка" и "Елка" и т. п. Строки приходят из двух разных источников. Надо сравнивать строки считая что é=e, Ё=Е и т.д. Возможно заказчик составит список какие именно символы считать эквивалентами, но вдруг есть какое-то универсальное решение?


TSP>>https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0 — универсальное.


hsc>Эээээ.... Уточню задачу. Мне надо написать функцию

hsc>
hsc>  bool my_compare(const std::wstring& s1, const std::wstring& s2);
hsc>

hsc>которая вернёт
hsc>для пар "Amélie" и "Amelie", "Ёлка" и "Елка" — true
hsc>для пар "Amolie" и "Amelie", "Oлка" и "Елка" — false


Расстояние Левенштейна прекрасно подходит для этой цели
Re[8]: Сравниение строк
От: pagid Россия  
Дата: 08.08.17 09:44
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Да ладно, Е и Ё и И и Й -- это всё разные буквы!

Буквы разные, но Ё заменять буквой Е можно, а Й заменять И нельзя
Re[9]: Сравниение строк
От: uzhas Ниоткуда  
Дата: 08.08.17 15:15
Оценка:
Здравствуйте, pagid, Вы писали:

MZ>>Да ладно, Е и Ё и И и Й -- это всё разные буквы!

P>а Й заменять И нельзя

смотрим, улыбаемся и машем: https://ru.wikipedia.org/wiki/%D0%98%D0%BE%D0%B4
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.