/// <summary> /// готовит структуру слов в массива для решения /// </summary> /// <param name="s1">строка, число слов</param> /// <returns>структура из двух массивов</returns> public static OneStr Prepare(string s1) { OneStr res = new OneStr(); // (?) нафиг использовать регулярки, когда у строки есть аналогичный метод? string[] t3 = Regex.Split(s1, "\\)"); string[] wrds = new string[t3.Length - 1]; int[] nums = new int[t3.Length - 1]; for (int i = 0; i < t3.Length - 1; i++) { string t4 = t3[i]; string[] t5 = Regex.Split(t4, "\\("); wrds[i] = t5[0]; int rr = 0; // (?) а если в скобках не число - то запишется 0, что тогда будет с дальнейшей обработкой? // (?) substring длинны 0 нельзя получить, словим эксепшн // (?) по идее надо вернуть пустую структуру, или генерировать эксепшн здесь, а выше его обрабатывать Int32.TryParse(t5[1], out rr); nums[i] = rr; } // собрать данные в структуры по одной на строку res.num = nums; res.str = wrds; return(res); }
/// <summary> /// готовит набор вероятных слов /// </summary> /// <param name="d">структура расчлененки</param> /// <returns>массив слов</returns> private string[] Transposition(OneStr d) { if (d.num.Length == 0) { return(new string[0]); } int words = d.str.Length; // d. = .str[], .num[] // перебирать все варианты, проверять орфографию каждого int[] cur = new int[words]; // текущие координаты int[] sta = new int[words]; // длинна слов int total = 1; for (int i = 0; i < words; i++) { cur[i] = 0; sta[i] = d.str[i].Length - d.num[i]; // максимальное начало строки, с нуля 0..ххх total = total * (sta[i] + 1); } string[] allwrds = new string[total]; int curwrd = 0; while (cur[words - 1] <= sta[words - 1]) { string r2 = ""; for (int i = 0; i < words; i++) { r2 = r2 + d.str[i].Substring(cur[i], d.num[i]); } allwrds[curwrd] = r2; curwrd++; cur[0]++; for (int i = 0; i < words - 1; i++) { if (cur[i] > sta[i]) { cur[i] = 0; cur[i + 1]++; } } }//while return(allwrds); }
} // струкрура данных для одной строчки расчлененок /// <summary> /// решает одну расчлененку, это уже отдельный поток /// </summary> /// <param name="s1">строка в формате "строитель(3)блеф(2)картон(2)</param> /// <param name="slov">количество слов</param> /// <returns></returns> private List <string> ProcessOne(string s1, int slov) { List <string> res = new List <string>(); if (s1.Trim().Length == 0) { return(res); } OneStr os = Prepare(s1); string[] wrds = Transposition(os); List <string> wrds2 = Spaces(wrds, slov); SpellChecker sc = new SpellChecker(); res = sc.Check(wrds2); Answer.Add(OT, 3, res, -1); return(res); }
/// <summary> /// готовит структуру слов в массива для решения /// </summary> /// <param name="s1">строка, число слов</param> /// <returns>структура из двух массивов</returns> private OneStr Prepare(string s1) { OneStr res = new OneStr(); string[] t3 = Regex.Split(s1, "\\)"); string[] wrds = new string[t3.Length - 1]; int[] nums = new int[t3.Length - 1]; for (int i = 0; i < t3.Length - 1; i++) { string t4 = t3[i]; string[] t5 = Regex.Split(t4, "\\("); wrds[i] = t5[0]; int rr = 0; Int32.TryParse(t5[1], out rr); nums[i] = rr; } // собрать данные в структуры по одной на строку res.num = nums; res.str = wrds; return(res); }
/// <summary> /// готовит строку для запроса /// </summary> /// <param name="d">структура расчлененки</param> /// <returns>часть скуль запроса</returns> public static string GetSqlStr(OneStr d) { // для пустых структур - выходим if (d.num.Length == 0) { return(""); } // количество слов int words = d.str.Length; // d. = .str[], .num[] // текущие координаты int[] cur = new int[words]; // длинна слов int[] sta = new int[words]; // всего вариантов int total = 1; int common_len = 0; for (int i = 0; i < words; i++) { // для каждого слова - начальный счетчик его части = 0 cur[i] = 0; // максимальное начало подстроки sta[i] = d.str[i].Length - d.num[i]; // максимальное начало строки, с нуля 0..ххх // счетчик количества вариантов total = total * (sta[i] + 1); common_len += d.num[i]; } Console.WriteLine("total = " + total.ToString()); // "SELECT * FROM Words INNER JOIN // (SELECT a1 || a2 || a3 tst FROM //string res = "SELECT tst wrd FROM (SELECT a1 "; string res = "SELECT * FROM (SELECT a1"; for (int i = 1; i < words; i++) { res = res + " || a" + (i + 1).ToString(); } res = res + " tst FROM "; // подготовка частей слов List <string[]> parts = new List <string[]>(words); for (int i = 0; i < words; i++) { // для каждого слова его подстроки храним в отдельном массиве string[] parts_one = new string[sta[i] + 1]; for (int j = 0; j <= sta[i]; j++) { parts_one[j] = d.str[i].Substring(j, d.num[i]); } // собираем все массивы в один список массивов parts.Add(parts_one); } // (SELECT 'ло' a1 UNION SELECT 'лъ') p1 res = res + "(SELECT '" + parts[0][0] + "' a1 "; for (int i = 1; i < parts[0].Length; i++) { res = res + " UNION SELECT '" + parts[0][i] + "'"; } res = res + ") p1 "; for (int w = 1; w < words; w++) { // CROSS JOIN (SELECT 'па' a2 UNION SELECT 'йй') p2 // CROSS JOIN (SELECT 'хх' a3 UNION SELECT 'та') p3 res = res + "CROSS JOIN (SELECT '" + parts[w][0] + "' a" + (w + 1).ToString() + " "; for (int i = 1; i < parts[w].Length; i++) { res = res + " UNION SELECT '" + parts[w][i] + "'"; } res = res + ") p" + (w + 1).ToString() + " "; } // ) pp ON pp.tst=Words.wrd"; //res = res + ") "; res = res + ") pp INNER JOIN Words ww ON pp.tst = ww.wrd";// WHERE Words.len = " + common_len.ToString(); //res = res + ") pp INNER JOIN Words ww ON pp.tst = ww.wrd"; //res = res + ") pp INNER JOIN (SELECT * FROM Words WHERE len = " + common_len + ") ww ON pp.tst = ww.wrd"; return(res); }