Группировка логических операторов (несколько наборов условий) в цикле do {} while ()? - PullRequest
0 голосов
/ 29 января 2011

В настоящее время у меня есть следующий цикл:

do {
       checkedWord = articleWords.Dequeue().TrimEnd('?', '.', ',', '!');
       correct = _spellChecker.CheckWord(checkedWord);
   } while (correct && articleWords.Count > 0);

Я ставлю в очередь слова из массива, который был выделен из текстового поля с ' ' в качестве разделителя.Цикл работает нормально, за исключением того, что я не хочу, чтобы какие-либо пустые записи "" или что-то не буквенно-цифровое, чтобы остановить цикл.В настоящее время, если между словами больше одного пробела, цикл заканчивается, и он продолжает получать предложения слов от проверки орфографии.

Если я сделаю while (correct && articleWords.Count > 0 || checkedWord == "");, он пропустит все пустые записи очереди, нопо-прежнему зависает в таких вещах, как новые строки - поэтому, если текстовое поле, из которого оно загружается, содержит пару абзацев, оно облажается на новой строке, разделяющей их.Я также пробовал while (correct && articleWords.Count > 0 || !Char.IsLetterOrDigit(checkedWord, 0));, но это также не работает.

Вопрос 1 : Можно ли сгруппировать такие условия, как (statement1 == true && count > 0) || (statement1 == false && Char.IsLetterOrDigit(char))?- Это означает, что все условия в первой группе должны быть выполнены ИЛИ все условия во втором наборе должны быть.

Вопрос 2 : я хочу, чтобы цикл продолжался до тех пор, покаобнаружена фактическая орфографическая ошибка, и она игнорирует такие вещи, как пустые записи в очереди, а также все, что не является буквенно-цифровым символом в начале строки.

Я подозреваю, что я близок сChar.IsLetterOrDigit бит, но нужно выяснить, как это сделать правильно.

Дайте мне знать, если потребуется дополнительная информация.

Спасибо!

Ответы [ 6 ]

1 голос
/ 29 января 2011

Если ваша цель - найти первую ошибку, вы можете пропустить цикл while и сделать следующее:

var firstError = tokens.Where(t => t.All(Char.IsLetterOrDigit) && !_spellChecker.CheckWord(t)).FirstOrDefault();
1 голос
/ 29 января 2011

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

Вы можете использовать что-то вроде этого:

public void Test()
{
    var separators = new[] { ' ', '\t', '\r', '\x00a0', '\x0085', '?', ',', '.', '!' };

    var input = "Test  string, news112!  news \n next, line! error in error word";          
    var tokens = new Queue<string>(input.Split(separators, StringSplitOptions.RemoveEmptyEntries));

    string currentWord = null;

    while (tokens.Any())
    {
        currentWord = tokens.Dequeue();
        if (currentWord.All(c => Char.IsLetterOrDigit(c)))
        {
            if (!CheckSpell(currentWord))
            {
                break;
            }
        }
    }
}

public bool CheckSpell(string word)
{
    return word != null && word.Length > 0 && word[0] != 'e';
}
0 голосов
/ 29 января 2011

Q1.Абсолютно.Просто убедитесь, что ваши группировки правильно разделены.

Q2.Для производительности и ясности я бы использовал REGEX для очистки вашего ввода перед очередью:

using System.Text.RegularExpressions;
...
string input = GetArticle(); // or however you get your input

input = Regex.Replace(input, @"[^0-9\w\s]", string.Empty);

// not sure what your separators but you can always
// reduce multiple spaces to a single space and just split
// on the single space
var articleWords = new Queue<string>(input.Split( ... ));

do {
     checkedWord = articleWords.Dequeue();

     // put your conditional grouping here if you want
     if(!_spellChecker.CheckWord(checkedWord)) {
          // only update "correct" if necessary - writes are more expensive =)
          // although with the "break" below you shouldn't need "correct" anymore
          // correct = false;

          // in case you want to raise an event - it's cleaner =)
          OnSpellingError(checkWord);

          // if you want to stop looping because of the error
          break;
     }
}
while(articleWords.Count > 0);

Я бы не использовал Char.IsLetterOrDigit, так как я думаю, что это будет медленнее ... кроме того, с REGEX вВ начале вы должны были позаботиться о записях, которые не являются символами или цифрами.

РЕДАКТИРОВАТЬ Добавление ответа LINQ

Подумав, я думаю, вы просто пытаетесьчтобы найти орфографические ошибки, так как насчет этого?

using System.Text.RegularExpressions;
...
string input = GetArticle(); // or however you get your input

// clean up words from punctuation
input = Regex.Replace(input, @"[^0-9\w\s]", string.Empty);

// trim whitespace
input = Regex.Replace(c, @"\s+", @" ");

var errors = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).All(w => !_spellChecker.CheckWord(w));

Тогда вы можете просто делать с ошибками все, что захотите =) Или вы можете просто использовать .Any, если вы просто хотите узнать, существует лиорфографическая ошибка вообще.

0 голосов
/ 29 января 2011

Когда речь идет о выделении текста, вы должны использовать регулярные выражения.Это очень мощный и быстрый фреймворк для текстовых запросов.Он способен выполнять свою работу со сложностью O (n).Это помогает вам, потому что вам не нужно думать, как вы будете выбирать текстовые значения, вы просто указываете, что вам нужно

Попробуйте этот код.Часть шаблона @ "\ w +" означает, что я хочу выбрать все группы буквенно-цифровых символов, длина которых> 1. Если бы я хотел выбрать все слова, начинающиеся с буквы 't', я бы написал @ "t \ w +",

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "The quick brown fox jumps over the lazy dog";

            Regex regex = new Regex(@"\w+", RegexOptions.Compiled);


            for (Match match = regex.Match(str); match.Success; match = match.NextMatch())
            {
                Console.WriteLine(match.Value);
            }
        }
    }
}
0 голосов
/ 29 января 2011

Q1: Конечно, можно группировать такие условия.

Q2: Как насчет этого?

string[] articleWords = textBoxText.Split(' ');
articleWords = articleWords.Select(a => a.Trim()).ToArray();    // remove all whitespaces (blanks, linebreaks)
articleWords = articleWords.Where(a => !string.IsNullOrEmpty(a)).ToArray(); // remove empty strings

bool correct = false;
bool spellingErrorFound = false;
for (int i = 0; i < articleWords.Length; i++)
{
    string checkedWord = articleWords[i].TrimEnd('?', '.', ',', '!');
    correct = _spellChecker.CheckWord(checkedWord);

    if (!correct)
        spellingErrorFound = true;
}
0 голосов
/ 29 января 2011
  1. Пока у вас есть допустимое логическое выражение, вы можете делать это без проблем. Это то, что очень легко проверить.

  2. Чтобы использовать Char.IsLetterOrDigit, вам нужно перебрать каждый символ в строке и проверить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...