2011-01-29 99 views
0

我现在有下面的循环:在do {} while()循环中对逻辑运算符(多组条件)进行分组?

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位,但必须弄清楚如何正确地做到这一点。

让我知道是否需要更多信息。

谢谢!

+0

很难理解你实际需要完成什么。你能否描述一般问题(而不是循环方面的问题)可能解决你的问题潜伏在不同的抽象层次上(听起来更奇怪):) – Lu4 2011-01-29 10:03:00

回答

1

你不应该使用复合循环条件,一个好的做法是使用循环时容易出现一般条件,当循环体中有'break'时应该离开它。

你可以使用一些这样的事:

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
  1. 只要你有一个有效的布尔表达式,你可以做到这一点没有问题。这是很容易测试的非常

  2. 要使用Char.IsLetterOrDigit,您需要遍历字符串中的每个字符并对其进行测试。

+0

你可以使用LINQ代替循环:currentWord.All(c => Char.IsLetterOrDigit(c)) – 2011-01-29 09:26:23

0

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

您应该使用string.Split代替linq – 2011-01-29 09:31:31

+0

的开销,您在哪里看到开销? – khlr 2011-01-29 15:44:03

+0

秒和trith线,使用LINQ时,最好不要使用它在所有(至少在这里) – 2011-01-30 08:16:30

0

说到文本选择,您应该使用正则表达式。这是非常强大和快速的文本查询框架。它能够完成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); 
      } 
     } 
    } 
} 
1

如果你的目标是找到的第一个错误,你可以跳过while循环并执行以下操作:

var firstError = tokens.Where(t => t.All(Char.IsLetterOrDigit) && !_spellChecker.CheckWord(t)).FirstOrDefault(); 
0

Q1。绝对。只要确保你的分组是正确分开的。

Q2。出于性能和清晰度,我会用正则表达式来清洁您的输入队列前:

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,因为我认为这是比较慢......此外,随着正则表达式在开始的时候,你应该有照顾不是字符或数字的条目。

编辑添加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,如果你只是想知道是否存在拼写错误的。