с# помогите с кодом на сравнение текстов

b1zar

Client
Регистрация
29.06.2019
Сообщения
107
Благодарностей
66
Баллы
28
Вот для моих нужд понабилось сравнение двух текстов по шинглу, тему нашел, код рабочий, но он берет текста из файлов и сравнивает их между собой, а я хочу сделать из переменной и сравнение 2 текстов с родительским текстом.
Вот оригинальный кусок кода:

Общий код
Код:
namespace ZennoLab.OwnCode
{
    /// <summary>
    /// A simple class of the common code
    /// </summary>
    public class CommonCode
    {
        /// <summary>
        /// Lock this object to mark part of code for single thread execution
        /// </summary>
        public static object SyncObject = new object();
       
        public double checkSimilarity(string textin, string textout)
        {
              string text1 = GetText(textin);
            string text2 = GetText(textout);
            int length = 3;
             
            var nGramma1 = GetNGrammas(text1, length);
            var nGramma2 = GetNGrammas(text2, length);

            String.Concat(nGramma1.Count(), "\r\n");
            String.Concat(nGramma2.Count(), "\r\n");
            double result = CalcJk(nGramma1,  nGramma2);
            return result;
   
        }

        static private string GetText(string path)
        {
            var reader = new StreamReader(path, System.Text.Encoding.UTF8);

            return reader.ReadToEnd().ToLower();
        }

        static private IEnumerable<string> ToGrammasFormat(string text)
        {
            var grammInput = text
                .Split(new char[] {'.', '!', '?', '(', ')', '[', ']', '{', '}'}, StringSplitOptions.RemoveEmptyEntries)
                .Select(x => Regex.Replace(x, @"\P{L}+", " ", RegexOptions.Compiled).Trim());   
                                       
            return grammInput;
        }

        static private IEnumerable<Tuple<string, int>> GetNGrammas(string text, int length)
        {
            var grammInput = ToGrammasFormat(text);

            var nGramma = grammInput
                .Where(line => line.Split(' ').Length >= length)               
                .SelectMany(sentence => sentence
                    .Split(' ')
                    .Select((word, index) =>
                        sentence
                            .Split(' ').Skip(index))
                            .Where(subline => subline.Count() >= length)
                            .Select(subline => String.Join(" ",subline.Take(length)).Trim()))
                .GroupBy(gramma => gramma)
                .Select(group => Tuple.Create(group.Key, group.Count()));

            return nGramma;
        }

        static private double CalcJk(IEnumerable<Tuple<string, int>> grammas1, IEnumerable<Tuple<string, int>> grammas2)
        {
            var totalGrammas = grammas1.Select(gramma => Tuple.Create(gramma.Item1, gramma.Item2, 0))
                .Concat(grammas2.Select(gramma => Tuple.Create(gramma.Item1, 0, gramma.Item2)))
                .GroupBy(gramma => gramma.Item1)
                .Select(group => Tuple.Create(group.First().Item1, group.First().Item2, group.Last().Item3));

            double common = 0, total = 0;
            foreach (Tuple<string, int, int> tGramma in totalGrammas)
            {
                common += Math.Min(tGramma.Item2, tGramma.Item3);
                total += Math.Max(tGramma.Item2, tGramma.Item3);
            }

            return common/total;
        }
    }
}
Снипет
Код:
IZennoList texts = project.Lists["Texts"];
var resultList = "";
int similarIndexBound = Convert.ToInt32(project.Variables["similarIndexBound"].Value);

List<string> textsCheck = new List<string>(texts);

int count1 = texts.Count;
int count2 = textsCheck.Count;
int totalIteration = count1 * count2;
int iteration = 0;

foreach (string textin in textsCheck)
{
    foreach (string textout in texts)
    {
        iteration++;
        if (textin == textout) { continue; }
        CommonCode similarity = new CommonCode();
        double result = similarity.checkSimilarity(textin, textout);
        result *= 100;
        int similarityIndex = (int)result;
        if (similarityIndex > similarIndexBound)
        {
            project.Variables["Result"].Value = textin+";"+textout+";"+similarityIndex;
        }
        project.SendInfoToLog("", "Итерация "+Convert.ToString(iteration)+", всего итераций: "+totalIteration, true);
    }
}
в этом снипете я почти не чего не трогал, за исключением переменной Result, теперь она отправляет не файл, как было, а в переменную.

Подскажите как мне сделать проверку на схожесть 2 текстов из переменной, знаний по c# не так много, но до этого хватало разобраться, а вот этот код для меня темный лес, пол дня убил, а результат не получил.
 
  • Спасибо
Реакции: sahha

eliadsonet

Client
Регистрация
25.05.2012
Сообщения
122
Благодарностей
48
Баллы
28
  • Спасибо
Реакции: Meteorburn

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 472
Благодарностей
575
Баллы
113
C#:
namespace ZennoLab.OwnCode
{
    public static class TemplateTools
    {
        public static double TextSimilarity(string textin, string textout)
        {
            int length = 3;
            
            var nGramma1 = GetNGrammas(textin, length);
            var nGramma2 = GetNGrammas(textout, length);

            String.Concat(nGramma1.Count(), "\r\n");
            String.Concat(nGramma2.Count(), "\r\n");
            double result = CalcJk(nGramma1,  nGramma2);
            return result;

        }

        static private IEnumerable<string> ToGrammasFormat(string text)
        {
            var grammInput = text
                .Split(new char[] {'.', '!', '?', '(', ')', '[', ']', '{', '}'}, StringSplitOptions.RemoveEmptyEntries)
                .Select(x => Regex.Replace(x, @"\P{L}+", " ", RegexOptions.Compiled).Trim());
                                      
            return grammInput;
        }

        static private IEnumerable<Tuple<string, int>> GetNGrammas(string text, int length)
        {
            var grammInput = ToGrammasFormat(text);

            var nGramma = grammInput
                .Where(line => line.Split(' ').Length >= length)           
                .SelectMany(sentence => sentence
                .Split(' ')
                    .Select((word, index) =>
                        sentence
                        .Split(' ').Skip(index))
                        .Where(subline => subline.Count() >= length)
                            .Select(subline => String.Join(" ",subline.Take(length)).Trim()))
                .GroupBy(gramma => gramma)
            .Select(group => Tuple.Create(group.Key, group.Count()));

            return nGramma;
        }

        static private double CalcJk(IEnumerable<Tuple<string, int>> grammas1, IEnumerable<Tuple<string, int>> grammas2)
        {
            var totalGrammas = grammas1.Select(gramma => Tuple.Create(gramma.Item1, gramma.Item2, 0))
            .Concat(grammas2.Select(gramma => Tuple.Create(gramma.Item1, 0, gramma.Item2)))
            .GroupBy(gramma => gramma.Item1)
            .Select(group => Tuple.Create(group.First().Item1, group.First().Item2, group.Last().Item3));

            double common = 0, total = 0;
            foreach (Tuple<string, int, int> tGramma in totalGrammas)
            {
                common += Math.Min(tGramma.Item2, tGramma.Item3);
                total += Math.Max(tGramma.Item2, tGramma.Item3);
            }

            return common/total;
        }
    }
}

C#:
// текст 1 из переменной
string textin= project.Variables["textin"].Value;

// текст 2 из переменной
string textout = project.Variables["textout"].Value;

// результат сравнения
double result = TemplateTools.TextSimilarity(textin, textout);

// возвращение результата
return result;
 
Последнее редактирование:

Igorii

Client
Регистрация
21.02.2015
Сообщения
371
Благодарностей
297
Баллы
63
Спасибо! Что то ошибку выдаёт:
Компиляция кода проекта Ошибка при компиляции общего кода "CS0708" ""TextSimilarity": невозможно объявить члены экземпляров в статическом классе". [Строка: 39; Cтолбец: 23]

В общий код добавил, Переменные textin, textout создал, текст в них положил. Что не так?
 

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 472
Благодарностей
575
Баллы
113
Спасибо! Что то ошибку выдаёт:
Компиляция кода проекта Ошибка при компиляции общего кода "CS0708" ""TextSimilarity": невозможно объявить члены экземпляров в статическом классе". [Строка: 39; Cтолбец: 23]

В общий код добавил, Переменные textin, textout создал, текст в них положил. Что не так?
исправил общий код
 
  • Спасибо
Реакции: Igorii

termit

Client
Регистрация
19.06.2010
Сообщения
52
Благодарностей
8
Баллы
8
@Meteorburn подскажите, пожалуйста, как можно внедрить ваш код в шаблон? Пробовал просто создать по C# кубику с кодом из этих блоков, выходит ошибка при выполнении.

Видимо имеет значение порядок выполнения строк кода, который вы написали. Я пробовал различные варианты, но в итоге получаю только ошибку.

Допустим у меня есть переменные textin и textout с текстом в шаблоне, следующим шагом мне ставить кубик с кодом, который идёт после namespace ZennoLab.OwnCode? Или сперва нужно выполнить эти строки?

C#:
// текст 1 из переменной
string textin= project.Variables["textin"].Value;

// текст 2 из переменной
string textout = project.Variables["textout"].Value;

// результат сравнения
double result = TemplateTools.TextSimilarity(textin, textout);

// возвращение результата
return result;
Что нужно сделать, чтобы код сработал в шаблоне? Буду очень благодарен за пояснение.
 

volody00

Client
Регистрация
06.09.2016
Сообщения
918
Благодарностей
953
Баллы
93

termit

Client
Регистрация
19.06.2010
Сообщения
52
Благодарностей
8
Баллы
8
@volody00 Спасибо большое! :ay:
 

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