[SOLVED] Как проще найти одинаковое в двух выражениях?

smartwisard

Client
Регистрация
17.01.2017
Сообщения
824
Благодарностей
83
Баллы
28
А точнее как превратить
Не раздумывайте, спрашивайте подробности!
Не раздумывайте, задавайте вопросы!
Не раздумывайте, пишите!
в
Не раздумывайте, {спрашивайте подробности!|задавайте вопросы!|пишите!}



?

I call it ZennoLab's BackWards Spinner.
 
Последнее редактирование:

arhip1985

Client
Регистрация
31.10.2011
Сообщения
2 994
Благодарностей
787
Баллы
113
если бы знать - что все предложения подобного рода - т.е. нагенерены по одинаковому правилу, то можно было бы просто по разделителю разделить
но вряд ли задача такая и скорее надо прочесть смысл
на сегодня это вопрос звучит - как повернуть время вспять, потому что - сначала делается словарь - а потом текст генерится, а тут надо из текста - сделать словарь смыслов - уметь их сравнивать - группировать по общему смыслу и грамматике
интересно было бы посмотреть - у кого какие мысли на этот счёт
 

gevolushn

Известная личность
Регистрация
25.03.2019
Сообщения
518
Благодарностей
269
Баллы
63
А точнее как превратить
Не раздумывайте, спрашивайте подробности!
Не раздумывайте, задавайте нам вопросы!
в
Не раздумывайте, {спрашивайте подробности|задавайте нам вопросы}!
?
Берете строку с предложением, заносите ее в массив символов. Потом берете вторую строку, заносите в другой массив символов. Сравниваете эти два массива, пока один из них не закончится. Как только символы разнятся, заносите символы каждого массива в отдельную переменную. А потом две переменные делаете спинтаксом. Как-то так. Сейчас попробую на коде написать.
 
  • Спасибо
Реакции: Dorian_Gray

gevolushn

Известная личность
Регистрация
25.03.2019
Сообщения
518
Благодарностей
269
Баллы
63
Если ТС добавит как именно у него хранятся данные и в каком формате, то можно доработать код.

Код:
//предложения для спинаткса
string text1 = "Не раздумывайте, спрашивайте подробности!";
string text2 = "Не раздумывайте, задавайте нам вопросы!";

//переменные для результата
string text1_result = "", text2_result = "";

//массивы символов предложений
char[] text1_array = text1.ToCharArray();
char[] text2_array = text2.ToCharArray();

//счетчик для цикла
int i = 0;

//проверка какой массив больше
if (text1_array.Length >= text2_array.Length){

    //цикл для сверки
    for (i = 0; i < text2_array.Length; i++){
        if (text1_array[i] != text2_array[i]){
            text1_result += text1_array[i].ToString();
            text2_result += text2_array[i].ToString();
        }
    }

    if (text1_array.Length != text2_array.Length){
        for (i = i; i < text1_array.Length; i++){
            text1_result += text1_array[i].ToString();
        }
    }
}

else{
    //цикл для сверки
    for (i = 0; i < text1_array.Length; i++){
        if (text1_array[i] != text2_array[i]){
            text1_result += text1_array[i].ToString();
            text2_result += text2_array[i].ToString();
        }
    }

    if (text1_array.Length != text2_array.Length){
        for (i = i; i < text2_array.Length; i++){
            text2_result += text2_array[i].ToString();
        }
    }
}

string result = "{" + text1_result + "|" + text2_result + "}";
return result;
Навскидку накалякал.
2.png
 
  • Спасибо
Реакции: arhip1985 и doc

arhip1985

Client
Регистрация
31.10.2011
Сообщения
2 994
Благодарностей
787
Баллы
113
если известно, что одинаковое всегда в начале - а не в середине или в конце - то отличный вариант
 

smartwisard

Client
Регистрация
17.01.2017
Сообщения
824
Благодарностей
83
Баллы
28
Не могу определить, в каком направлении развивать шаблончик дальше!

А мой незаконченный шаблончик делает следующее:
1. То, что я собрал ручками, кладёт в список Сырьё, разделитель точка (в каждую строку кладётся одно предложение).
2. Берёт первое слово какой-нибудь строки в переменную Word.
3. Отделяет подсписок, содержащий это слово. Если строк не больше 1, кладёт её в список Итоги. Если строк больше 1, начинает обрабатывать подсписок.
4. Из подсписка удаляет две строки в Variable1 вставляет { и в Varibale2 вставляет |
Word {...
Word |...
5. Делает так
Если предложения ... всегда одинаковы в начале - сравнивать посимвольно до тех пор, когда символы перестанут совпадать. с места несовпадения выделять подстроки и объединять их в конструкцию спинтакса.
6. Обрабатывает весь подсписок и повторяет 2.

Т.е. в список Итоги строки сырья объединены по одинаковому началу, например
Не раздумывайте, {спрашивайте подробности!|задавайте вопросы!|пишите!}

Шаблончик BackWards Spinner Laboratoria приложил к ветке многоуважаемого doc.
В каком направлении развивать шаблончик?
 
Последнее редактирование:

gevolushn

Известная личность
Регистрация
25.03.2019
Сообщения
518
Благодарностей
269
Баллы
63
Доделал я все-таки сниппет. Не мастак писать комментарии, но надеюсь кому надо, тот разберется.
C#:
var list1 = project.Lists["Список"];//список, где лежат предложения
var list2 = project.Lists["Список2"];//список для результата
List <string> spintax = new List <string>();//временный список
/*----------------------------------------------------------------------------------------------------------------------*/
char[] array1;//массив символов для предложения, с которым сравниваем другие предложения
char[] array2;//массив символов для предложения, которое будет сравнивать
/*----------------------------------------------------------------------------------------------------------------------*/
string result1 = "";//промежуточная переменные для записи первого словесного совпадения
string result2 = "";//промежуточная переменные для конца предложения
/*----------------------------------------------------------------------------------------------------------------------*/
bool start = false;//логическая переменная для проверки было уже совпадение или нет
/*----------------------------------------------------------------------------------------------------------------------*/
int i = 0, j = i + 1, k = 0, l = 0;//счетчики для циклов
/*----------------------------------------------------------------------------------------------------------------------*/
int count = list1.Count;//количество строк в списке с предложениями
/*----------------------------------------------------------------------------------------------------------------------*/
//Цикл для поиска спинтакса. Берется строка из списка по порядку за основу и сверяется с следующими строками для на схожесть
for (i = 0; i < count; i++){
    result1 = "";
    array1 = list1[i].ToCharArray();
    /*----------------------------------------------------------------------------------------------------------------------*/
    //Цикл для поиска по списку совпадений. Берем слудющие строки по порядку и сверям с "основной" строкой
    for (j = i + 1; j < count; j++){
        /*----------------------------------------------------------------------------------------------------------------------*/
        //если строка последняя и у нее нет совпадений, то просто заносим ее в итоговый список как есть
        try{
            /*----------------------------------------------------------------------------------------------------------------------*/
            //если два предложения одинаковы, то удаляем последнее
            while (list1[i] == list1[j]){
                list1.RemoveAt(j);
            }
            /*----------------------------------------------------------------------------------------------------------------------*/
            array2 = list1[j].ToCharArray();
        }
        catch{
            break;
        }
        /*----------------------------------------------------------------------------------------------------------------------*/
        //ищем совпадения до тех пор, пока символы не будут разными, а также записываем начало предложений первый раз
        if (result1 == ""){
            try{
                for (k = 0;; k++){
                    if (array1[k] != array2[k]){
                        break;
                    }
                    result1 += array1[k].ToString();
                }
            }
            catch{
                result2 = "";
                continue;
            }
        }
        /*----------------------------------------------------------------------------------------------------------------------*/
        //ищем совпадения до тех пор, пока символы не будут разными все последующие разы
        else{
            array1 = result1.ToCharArray();
            try{
                for (k = 0; k < array1.Length; k++){
                    if (array1[k] != array2[k]){
                        start = true;
                        break;
                    }
                }
            }
            catch{
                result2 = "";
                continue;
            }
        }
        /*----------------------------------------------------------------------------------------------------------------------*/
        //если нет совпадения, то двигаемся к следуюущей строке
        if (result1 == "" || start){
            start = false;
            continue;
        }
        /*----------------------------------------------------------------------------------------------------------------------*/
        //в другом случае запоминаем конец предложений
        else{
            /*----------------------------------------------------------------------------------------------------------------------*/
            //если не было еще совпадений, то записываем второую часть основного предложения во вторую переменную 
            if (spintax.Count == 0){
                for (l = k; l < array1.Length; l++){
                    result2 += array1[l].ToString();
                }
                spintax.Add(result2);
                result2 = "";
            }
            /*----------------------------------------------------------------------------------------------------------------------*/
            //цикл для второго предложения
            for (l = k; l < array2.Length; l++){
                result2 += array2[l].ToString();//дописываем вторую часть предложения
            }
            spintax.Add(result2);
            result2 = "";
            /*----------------------------------------------------------------------------------------------------------------------*/
            //удаляем строку, которая совпала
            list1.RemoveAt(j);
            j--;
        }
        /*----------------------------------------------------------------------------------------------------------------------*/
        //обновляем количество строк в списке
        count = list1.Count;
    }
    /*----------------------------------------------------------------------------------------------------------------------*/
    //добавляем в итоговый список готовый спинтакс
    if (spintax.Count != 0){
        list2.Add(result1 + "{" + String.Join("|", spintax.ToArray()) + "}");
    }
    /*----------------------------------------------------------------------------------------------------------------------*/
    //если не нашло совпадений, то записываем строку как есть
    else{
        list2.Add(list1[i]);
    }
    /*----------------------------------------------------------------------------------------------------------------------*/
    //очищаем список совпадений
    spintax.Clear();
    /*----------------------------------------------------------------------------------------------------------------------*/
    //обновляем количество строк в списке
    count = list1.Count;
}
Из такого списка:
1.png

Получился такой
2.png

P.S. Единственное что не добавил, так это повторный проход по списку, если еще есть другие, более мелкие совпадения по предложениям.
P.S.S. Его еще нужно дорабатывать и дорабатывать.
 
Последнее редактирование:

smartwisard

Client
Регистрация
17.01.2017
Сообщения
824
Благодарностей
83
Баллы
28
Я придумал второй способ, но не совсем Spintax. Способ попроще, цель вроде как достигаю.
Вот есть у меня исходное объявление. Хочу я из него сделать много разных. Поступаю так:
1) собираю много подобных объявлений, при сборе определяю длину текста.
2) самые длинные кладу в список. Все собранные объявления в один длиннющий список построчно {или|и} от заглавной буквы до точки.
Готов список "Сырьё".
3) беру из исходного объявления {предложение|строку} и пытаюсь заменить это {предложение|строку}:
беру из него самое длинное слово, по нему выделяю из списка подсписок.
Беру второе по длине слово, в подсписке оставляю содержащие его строки. Можно проверить и третьим словом, вдруг по нему подсписок выделится...
4) получаю несколько предложений, которые меня устроят, скорее всего.
 
Последнее редактирование:

smartwisard

Client
Регистрация
17.01.2017
Сообщения
824
Благодарностей
83
Баллы
28
Вот думаю упростить себе техзадание:
пусть шаблон находит одинаковые слова в двух текстах:


кухонный гарнитур. Столешница из искусственного камня. Возможность изготовления столешниц с влитой мойкой. Изготовим различные формы и размеры. Цена от изготовителя. Невероятная палитра цветов. Цена рассчитывается в зависимости от формы, толщины, размера, спецэффектов и др. В объявлении указана примерная цена за кв. м. Уточняйте подробности у консультантов салона.


кухонный гарнитур. Столешница из искусственного камня. Изготовим по вашим размерам. Цена производителя. Различная палитра. Возможность изготовления с влитой мойкой. Цена в зависимости от размера, формы, и т.п. Указана примерная цена за кв. м. Подробности у консультантов.
 

Sergodjan

Administrator
Команда форума
Регистрация
05.09.2012
Сообщения
20 567
Благодарностей
9 184
Баллы
113
Вот думаю упростить себе техзадание:
пусть шаблон находит одинаковые слова в двух текстах:


кухонный гарнитур. Столешница из искусственного камня. Возможность изготовления столешниц с влитой мойкой. Изготовим различные формы и размеры. Цена от изготовителя. Невероятная палитра цветов. Цена рассчитывается в зависимости от формы, толщины, размера, спецэффектов и др. В объявлении указана примерная цена за кв. м. Уточняйте подробности у консультантов салона.


кухонный гарнитур. Столешница из искусственного камня. Изготовим по вашим размерам. Цена производителя. Различная палитра. Возможность изготовления с влитой мойкой. Цена в зависимости от размера, формы, и т.п. Указана примерная цена за кв. м. Подробности у консультантов.
Алгоритм можно выстроить такой:
- первый текст очистить от знаков препинаний и переносов строк
- поместить его в список с разделителем {-String.Space-}
- в цикле брать строку из спсика с удалением с помощью экшена Операции над списком
- проверять на вхождение во втором списке с помощью экшена Обработка текста - Regex
- с помощью экшена IF проверять, найдено вхождение или нет, если найдено можно помещать строку в отд. список (список одинаковых слов)
- повторять цикл до момента, пока не будет обнулен список слов, выход по красному выходу из экшена Операции над списком
 

smartwisard

Client
Регистрация
17.01.2017
Сообщения
824
Благодарностей
83
Баллы
28
Алгоритм можно выстроить такой:
- первый текст очистить от знаков препинаний и переносов строк
- поместить его в список с разделителем {-String.Space-}
- в цикле брать строку из спсика с удалением с помощью экшена Операции над списком
- проверять на вхождение во втором списке с помощью экшена Обработка текста - Regex
- с помощью экшена IF проверять, найдено вхождение или нет, если найдено можно помещать строку в отд. список (список одинаковых слов)
- повторять цикл до момента, пока не будет обнулен список слов, выход по красному выходу из экшена Операции над списком
Отлично.
Перед наполнением списка ещё можно использовать лемматизатор. Но не обязательно.
Не сильно помешает сортировать список для красоты.
 

Кто просматривает тему: (Всего: 2, Пользователи: 0, Гости: 2)