我正在尝试编写一个程序来读取文本文件,按字符对其进行排序,并跟踪每个字符在文档中出现的次数。这就是我到目前为止所拥有的。
class Program
{
static void Main(string[] args)
{
CharFrequency[] Charfreq = new CharFrequency[128];
try
{
string line;
System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Users\User\Documents\Visual Studio 2013\Projects\Array_Project\wap.txt");
while ((line = file.ReadLine()) != null)
{
int ch = file.Read();
if (Charfreq.Contains(ch))
{
}
}
file.Close();
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
}
}
我的问题是,if语句应该包含哪些内容?
我还有一个Charfrequency类,我将在这里包括以防我包含它有用/必要(是的,我需要使用数组而不是列表或arraylist)。
public class CharFrequency
{
private char m_character;
private long m_count;
public CharFrequency(char ch)
{
Character = ch;
Count = 0;
}
public CharFrequency(char ch, long charCount)
{
Character = ch;
Count = charCount;
}
public char Character
{
set
{
m_character = value;
}
get
{
return m_character;
}
}
public long Count
{
get
{
return m_count;
}
set
{
if (value < 0)
value = 0;
m_count = value;
}
}
public void Increment()
{
m_count++;
}
public override bool Equals(object obj)
{
bool equal = false;
CharFrequency cf = new CharFrequency('\0', 0);
cf = (CharFrequency)obj;
if (this.Character == cf.Character)
equal = true;
return equal;
}
public override int GetHashCode()
{
return m_character.GetHashCode();
}
public override string ToString()
{
String s = String.Format("'{0}' ({1}) = {2}", m_character, (byte)m_character, m_count);
return s;
}
}
答案 0 :(得分:1)
看一下这篇文章。
https://codereview.stackexchange.com/questions/63872/counting-the-number-of-character-occurrences
它使用LINQ来实现您的目标
答案 1 :(得分:1)
您不应该使用Contains
首先,您需要初始化Charfreq
数组:
CharFrequency[] Charfreq = new CharFrequency[128];
for (int i = 0; i < Charferq.Length; i++)
{
Charfreq[i] = new CharFrequency((char)i);
}
try
然后你可以
int ch;
// -1 means that there are no more characters to read,
// otherwise ch is the char read
while ((ch = file.Read()) != -1)
{
CharFrequency cf = new CharFrequency((char)ch);
// This works because CharFrequency overloads the
// Equals method, and the Equals method checks only
// for the Character property of CharFrequency
int ix = Array.IndexOf(Charfreq, cf);
// if there is the "right" charfrequency
if (ix != -1)
{
Charfreq[ix].Increment();
}
}
请注意,不是我编写程序的方式。这是使您的程序正常运行所需的最小更改。
作为旁注,该程序将计算ASCII字符的“频率”(代码&lt; = 127的字符)
CharFrequency cf = new CharFrequency('\0', 0);
cf = (CharFrequency)obj;
这是一个无用的初始化:
CharFrequency cf = (CharFrequency)obj;
就足够了,否则你只是想创建一个CharFrequency
来丢弃它。
答案 2 :(得分:1)
字典非常适合这样的任务。你没有说出文件所在的字符集和编码。因此,因为Unicode很常见,所以我们假设使用Unicode字符集和UTF-8编码。 (毕竟,它是.NET,Java,JavaScript,HTML,XML等的默认设置。)如果情况并非如此,则使用适用的编码读取文件并修复代码,因为您当前使用的是UTF您的StreamReader中的-8。
接下来是遍历&#34;字符&#34;。然后递增一个&#34;字符的计数&#34;在字典中,如文中所见。
Unicode确实有一些复杂的功能。一种是组合字符,其中基本字符可以用变音符号等覆盖。用户将这样的组合视为一个&#34;字符&#34;,或者如Unicode所称,它们是字形。值得庆幸的是,.NET给出的是StringInfo类,它将它们作为&#34;文本元素进行迭代。&#34;
所以,如果你考虑一下,使用数组会非常困难。您必须在阵列之上构建自己的字典。
以下示例使用词典,并使用LINQPad script运行。在创建字典之后,它会通过一个漂亮的显示来命令和转储它。
var path = Path.GetTempFileName();
// Get some text we know is encoded in UTF-8 to simplify the code below
// and contains combining codepoints as a matter of example.
using (var web = new WebClient())
{
web.DownloadFile("http://superuser.com/questions/52671/which-unicode-characters-do-smilies-like-%D9%A9-%CC%AE%CC%AE%CC%83-%CC%83%DB%B6-consist-of", path);
}
// since the question asks to analyze a file
var content = File.ReadAllText(path, Encoding.UTF8);
var frequency = new Dictionary<String, int>();
var itor = System.Globalization.StringInfo.GetTextElementEnumerator(content);
while (itor.MoveNext())
{
var element = (String)itor.Current;
if (!frequency.ContainsKey(element))
{
frequency.Add(element, 0);
}
frequency[element]++;
}
var histogram = frequency
.OrderByDescending(f => f.Value)
// jazz it up with the list of codepoints in each text element
.Select(pair =>
{
var bytes = Encoding.UTF32.GetBytes(pair.Key);
var codepoints = new UInt32[bytes.Length/4];
Buffer.BlockCopy(bytes, 0, codepoints, 0, bytes.Length);
return new {
Count = pair.Value,
textElement = pair.Key,
codepoints = codepoints.Select(cp => String.Format("U+{0:X4}", cp) ) };
});
histogram.Dump(); // For use in LINQPad