3

Имеется код, представляющий из себя словарь и цикл. Принцип работы прост: вводится слово из словаря с ОДНОЙ ошибкой, а благодаря циклу выводится правильное написание данного слова из того же словаря. Так вот проблема как раз в том, что слово проверятся если в нем допущена лишь одна ошибка, и если длина слова совпадает с длиной правильного варианта его написания (например, слово програма с одной "м" не будет засчитано за ошибку). Прошу помочь сделать так, чтоб программа так же исправляла слова с более чем одной ошибкой, а так же исправляла слова, длина которых не идентична длине правильной вариации написания данного слова. Вот сам код:

class Program
{
    static void Main(string[] args)
    {
        string[] slovar = {"Здравствуйте","вот","моя","программа",
 "предназначенная","для","проверки","орфографии","в",
 "тексте","состоящем","из","заданного","набора","слов",
 "шла","Саша","по","шоссе","так","же","дабы","словарь","казался","больше","добавим","ещё","парочку"};
    Console.WriteLine("Введите слово из словаря(с ошибкой):");
    string s = Console.ReadLine();

    var closestWords = slovar
        .Select(x => new { orig = s, dict = x, Distance = Diff(x, s) })
        .GroupBy(x => x.Distance)
        .OrderBy(x => x.Key)
        .Take(1)
        .SelectMany(x => x.Select(z => z.dict))
        .ToArray();

    Console.WriteLine("Вы ввели {s}");
    Console.WriteLine("Самые близкие слова {string.Join(" ,", closestWords)}");

    Console.ReadLine();
}

}

2 Answers2

3

Вообще, для получения разницы строк есть алгоритмы, такие как расстояние Левенштейна. Такой алгоритм относительно легко позволяет найти разнницу между строками (да и между чем угодно другим, что можно сравнить).

Пример нахождения расстояния между строками

private static int Diff(string original, string actual)
{
    var board = new int[original.Length + 1, actual.Length + 1];
    for (var i = 0; i < board.GetLength(0); i++) board[i, 0] = i;
    for (var i = 0; i < board.GetLength(1); i++) board[0, i] = i;
for (var i = 1; i &lt; board.GetLength(0); i++)
{
    for (var j = 1; j &lt; board.GetLength(1); j++)
    {
        var stringsEquals = original[i - 1] == actual[j - 1];
        var add = (stringsEquals ? 0 : 1);
        board[i, j] = Math.Min(board[i - 1, j - 1] + add * 2, Math.Min(board[i - 1, j] + 1, board[i, j - 1] + 1));
    }
}
return board[original.Length, actual.Length];

}

Ваша код можно обновить так

string[] slovar = {"Здравствуйте","вот","моя","программа",
     "предназначенная","для","проверки","орфографии","в",
     "тексте","состоящем","из","заданного","набора","слов",
     "шла","Саша","по","шоссе","так","же","дабы","словарь","казался","больше","добавим","ещё","парочку"};

Console.WriteLine("Введите слово из словаря(с ошибкой):"); string s = Console.ReadLine();

var closestWords = slovar .Select(x => new { orig = s, dict = x, Distance = Diff(x, s)}) .GroupBy(x=>x.Distance) .OrderBy(x=>x.Key) .Take(1)
.SelectMany(x=>x.Select(z=>z.dict)) .ToArray();

Console.WriteLine($"Вы ввели {s}"); Console.WriteLine($"Самые близкие слова {string.Join(" ,", closestWords)}");

Console.ReadLine();

Проверка

Введите слово из словаря(с ошибкой):
Вы ввели Зраствуй
Самые близкие слова Здравствуйте

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

Как пример о чем я говорю,

Введите слово из словаря(с ошибкой):
Вы ввели Здрасти
Самые близкие слова Здравствуйте, из, дабы
tym32167
  • 32,857
0
using System;

using System.Linq;

namespace disa { class Program { static void Main(string[] args) { string[] slovar = {"Здравствуйте","вот","моя","программа", "предназначенная","для","проверки","орфографии","в", "тексте","состоящем","из","заданного","набора","слов", "шла","Саша","по","шоссе","так","же","дабы","словарь","казался","больше","добавим","ещё","парочку"};

        Console.WriteLine("Введите слово из словаря(с ошибкой):");
        string s = Console.ReadLine();
    var closestWords = slovar
        .Select(x =&gt; new { orig = s, dict = x, Distance = Diff(x, s) })
        .GroupBy(x =&gt; x.Distance)
        .OrderBy(x =&gt; x.Key)
        .Take(1)
        .SelectMany(x =&gt; x.Select(z =&gt; z.dict))
        .ToArray();

    Console.WriteLine(&quot;Вы ввели {s}&quot;);
    Console.WriteLine(&quot;Самые близкие слова {string.Join(&quot; ,&quot;, closestWords)}&quot;);

    Console.ReadLine();
}

}

}