我从用户那里得到一个字符串,然后把它放在一个char数组中。现在我想显示字符串中的所有字符以及它们出现的次数。我的代码如下请纠正我?
using System;
class count
{
public void charcount()
{
int i ;
int count = 0;
string s;
Console.WriteLine("Enter the String:");
s = Console.ReadLine();
char[] carr = s.ToCharArray();
for(i = 0; i < carr.Length; i++)
{
for(int j = 1; j < carr.Length; j++)
{
if(carr[j] == carr[i])
{
count++;
}
else
{
return;
}
Console.WriteLine("The Character " + carr[i] + " appears " + count);
}
}
}
static void Main()
{
count obj = new count();
obj.charcount();
}
}
答案 0 :(得分:5)
好吧,你的代码至少会遇到问题,因为你没有建立一个唯一字符列表,你可以在原始字符串中找到它们。任何出现多次字符的字符串都会显示奇怪的结果。
这是一个为您计算信息的LINQ表达式(您可以在LINQPad中运行它以立即查看结果):
void Main()
{
string s = "This is a test, with multiple characters";
var statistics =
from c in s
group c by c into g
select new { g.Key, count = g.Count() };
var mostFrequestFirst =
from entry in statistics
orderby entry.count descending
select entry;
foreach (var entry in mostFrequestFirst)
{
Debug.WriteLine("{0}: {1}", entry.Key, entry.count);
}
}
输出:
: 6 <-- space t: 5 i: 4 s: 4 h: 3 a: 3 e: 3 l: 2 c: 2 r: 2 T: 1 ,: 1 w: 1 m: 1 u: 1 p: 1
如果你不能使用LINQ,这是一个不使用它的例子:
void Main()
{
string s = "This is a test, with multiple characters";
var occurances = new Dictionary<char, int>();
foreach (char c in s)
{
if (occurances.ContainsKey(c))
occurances[c] = occurances[c] + 1;
else
occurances[c] = 1;
}
foreach (var entry in occurances)
{
Debug.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
}
答案 1 :(得分:1)
看起来你想要一个外部循环和一个内部循环,并且对于数组中的每个字符,你想要与int j = 1
后面的每个字符进行比较。在这种情况下,您需要内部循环中的int j = i + 1
:
for (int i = 0; i < carr.Length; i++)
{
for (int j = i + 1; j < carr.Length; j++)
{
}
}
但是你的return语句会在事物中间退出函数。您需要让循环完成,因此您要删除return
。
你的Console.WriteLine
在内循环的每次迭代中执行,但你真的只希望它在外循环上迭代 - 一次为字符串的每个字符而不是一次i和j的每个组合。所以你需要把它推到外循环中,在内循环之外。
此外,每次开始外循环的另一次迭代时,您需要重置计数,因为您再次计数,并且,当您找到一个时,您想要开始计算 1 而不是零因为它刚出现时就出现了一次。
正如Lasse指出的那样,当你沿着外圈移动时击中相同的角色时,你会得到奇怪的输出。防止这种情况的一种简单方法是在每次匹配时将更多(向右)char [j]设置为'\ 0'(空字符),然后在外循环中,忽略计数中的空字符,例如使用{{ 1}},随着你的进展有效地剔除它们:
continue
我的第一个想法是使用像丹尼尔建议的字典,如下所示:
for(int i = 0; i < carr.Length; i++)
{
if (carr[i] == '\0')
{
continue; // skip any further chars we've already set to null char
}
int count = 1;
for (int j = i + 1; j < carr.Length; j++)
{
if(carr[j] == carr[i])
{
carr[j] = '\0'; // don't look for this char again later
count++;
}
}
Console.WriteLine("The Character " + carr[i] + " appears " + count);
}
但我喜欢优雅的LINQ解决方案。
答案 2 :(得分:0)
如果您已经测试了代码,您会意识到代码是非常错误的 它的一些问题:
count
变量,但您想要计算字符串中所有字符的出现次数正确的方法是使用Dictionary<char, int>
来保存每个角色的计数,如下所示:
var counts = new Dictionary<char, int>();
foreach(var c in s)
{
int count;
if(!counts.TryGetValue(c, out count))
{
counts.Add(c, 1);
}
else
{
++counts[c];
}
}
我没有故意使用LINQ,因为我认为您不会理解该代码。这不是冒犯。
答案 3 :(得分:0)
如果你想采用LINQ方式,这是一个相当简单的方法(我意识到它与Lasse V. Karlsen's answer非常相似,只使用不同的语法):
var s = Console.ReadLine();
foreach (var group in s.GroupBy(c => c).OrderByDescending(g => g.Count()))
{
Console.WriteLine(" {0}: {1}", group.Key, group.Count());
}
无论你使用什么方法,逻辑都是一样的:
在我的代码示例中,s.GroupBy(c => c)
负责前两个步骤。调用OrderByDescending(g => g.Count())
只会对结果进行排序,以便更频繁地使用字符。结果中的每个元素都有一个Key
属性(字符)和(以及其他)一个Count()
方法,它将返回该字符的出现次数。