2009-10-27 39 views
7

Estoy buscando una buena clase o función de recuento de palabras. Cuando copio y pego algo de Internet y lo comparo con mi algoritmo de conteo de palabras personalizado y MS Word, siempre está apagado un poco más de 10%. Creo que eso es demasiado. Entonces, ¿saben ustedes de un algoritmo preciso de conteo de palabras en C#.Algoritmo de recuento de palabras en C#

+1

¿Su algoritmo es constantemente demasiado alto o demasiado bajo? ¿O varía? – Larsenal

+1

¿Está contando solo palabras, o es lo que está pegando también marcado? – joshperry

+2

¿Por qué está utilizando el recuento de palabras de MS Word como su punto de referencia para la precisión? Las diferencias sutiles en lo que cuenta como una "palabra" pueden resultar en diferencias significativas en el conteo de palabras. 10% no es una sorpresa allí. Lo que estás viendo es probablemente perfectamente exacto, pero simplemente ligeramente diferente. –

Respuesta

6

Cadena.Separación por caracteres predefinidos. Use signos de puntuación, espacios (elimine espacio múltiple) y cualquier otro carácter que determine que es "división de palabras"

¿Qué ha intentado?

Vi que el usuario anterior se conectó a los enlaces, pero aquí hay algunos ejemplos de cómo usar expresiones regulares o coincidencias de caracteres. Espero que ayude, y nadie se hace daño X)

String.Split Method (Char[])

Word counter in C#

C# Word Count

+0

no para enlaces, más bien, para googlear los enlaces obvios sin ningún valor añadido traído en – zvolkov

+0

bien, punto tomado. –

+1

@astander No olvides la opción _StringSplitOptions.RemoveEmptyEntries_ en -_Split_; de lo contrario, "word1, word2" o "word1? Word2" se contarán como 3 palabras. –

8

Como @astander sugiere, se puede hacer un String.split de la siguiente manera:

string[] a = s.Split(
    new char[] { ' ', ',', ';', '.', '!', '"', '(', ')', '?' }, 
    StringSplitOptions.RemoveEmptyEntries); 

Al pasar una serie de caracteres, puede dividir en múltiples separaciones de palabras. Eliminar las entradas vacías evitará que cuente palabras que no sean palabras.

+3

Esto es genial, pero también debe tener en cuenta las nuevas líneas. Si escribe una palabra, presione enter, escriba una palabra, presione enter, devolverá un conteo de 0. Una de las sobrecargas para Split() permite una matriz de cadenas, por lo que podría cambiar esta matriz a cadenas de caracteres y agregue Environment.Newline (o "\ r \ n" y \ n "). –

+2

A menos que su entrada contenga un formato muy limitado, probablemente necesite una red más ancha: considere soportes rizados y angulosos, guiones (aunque esto puede producir falsos positivos) y otros signos de puntuación. –

1

También debe verificar newlines, tabs y non-breaking spaces. Encuentro que es mejor copiar el texto fuente en un StringBuilder y reemplazar todas las líneas nuevas, pestañas y caracteres que terminan con espacios. Luego divide la cadena en función de los espacios.

1

acabo de tener el mismo problema en ClipFlair, en el que necesitaba para calcular WPM (palabras por minuto) para la película de subtítulos, por lo que se le ocurrió la siguiente:

Se puede definir estática método de extensión en una clase estática y luego agregue una cláusula using al espacio de nombres de esa clase estática en cualquier clase que necesite usar este método de extensión. El método de extensión se invoca usando s.WordCount(), donde s es una cadena (un identificador [Variable/constante] o literal)

public static int WordCount(this string s) 
{ 
    int last = s.Length-1; 

    int count = 0; 
    for (int i = 0; i <= last; i++) 
    { 
    if (char.IsLetterOrDigit(s[i]) && 
     ((i==last) || char.IsWhiteSpace(s[i+1]) || char.IsPunctuation(s[i+1]))) 
     count++; 
    } 
    return count; 
} 
4

utilizar una expresión regular para encontrar palabras (por ejemplo, [\ w] +) y contar sólo los partidos

public static Regex regex = new Regex(
    "[\\w]+", 
RegexOptions.Multiline 
| RegexOptions.CultureInvariant 
| RegexOptions.Compiled 
); 

regex.Match (_someString) .Count

1

Esta es la versión simplificada de la clase C# código que hice para contar palabras, palabras asiáticas, charaters etc. Esto es casi igual como Microsoft Word. Desarrollé el código original para contar palabras para documentos de Microsoft Word.

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Text.RegularExpressions; 
    namespace BL { 
    public class WordCount 
    { 

    public int NonAsianWordCount { get; set; } 
    public int AsianWordCount { get; set; } 
    public int TextLineCount { get; set; } 
    public int TotalWordCount { get; set; } 
    public int CharacterCount { get; set; } 
    public int CharacterCountWithSpaces { get; set; } 


    //public string Text { get; set; } 

    public WordCount(){} 

    ~WordCount() {} 


    public void GetCountWords(string s) 
    { 
     #region Regular Expression Collection 
     string asianExpression = @"[\u3001-\uFFFF]"; 
     string englishExpression = @"[\S]+"; 
     string LineCountExpression = @"[\r]+"; 
     #endregion 


     #region Asian Character 
     MatchCollection asiancollection = Regex.Matches(s, asianExpression); 

     AsianWordCount = asiancollection.Count; //Asian Character Count 

     s = Regex.Replace(s, asianExpression, " "); 

     #endregion 


     #region English Characters Count 
     MatchCollection collection = Regex.Matches(s, englishExpression); 
     NonAsianWordCount = collection.Count; 
     #endregion 

     #region Text Lines Count 
     MatchCollection Lines = Regex.Matches(s, LineCountExpression); 
     TextLineCount = Lines.Count; 
     #endregion 

     #region Total Character Count 

     CharacterCount = AsianWordCount; 
     CharacterCountWithSpaces = CharacterCount; 

     foreach (Match word in collection) 
     { 
      CharacterCount += word.Value.Length ; 
      CharacterCountWithSpaces += word.Value.Length + 1; 
     } 

     #endregion 

     #region Total Character Count 
     TotalWordCount = AsianWordCount + NonAsianWordCount; 
     #endregion 
    } 
} 
} 
Cuestiones relacionadas