几天前,我接受了Jr.开发人员职位的采访,他们问:
“如果你有一个字母数组”a“和”b“你怎么写一个方法来计算这些字母在这个数组中的实例数?”
我说你会有for loop
if else
语句,它会增加2个计数器变量中的1个。然而,在那之后,他们问我如何解决同样的问题,如果数组可以包含任何字母表的字母。我说我会用同样的方式,用长IF
语句或switch
语句。事后看来,这似乎并不那么有效;有没有更容易的方法来做这件事?
答案 0 :(得分:3)
您可以将大小为256的数组(可能的字符代码数)声明为零,并简单地增加与您读取的字符代码对应的数字。
例如,如果您正在读取'a',则相应的代码为ASCII 97,因此您可以增加数组[97],您可以优化内存量,将代码减少97(如果您知道输入将是字符只有)你还需要知道如何处理大写字符(你是否将它们称为不同或不同)在这种情况下你需要注意将字符减少65.
所以最后代码看起来像这样:
int counts[122 - 97] = {0}; // codes of a - z
char a = get_next_char();
if ( is_capital(a)){
counts[a - 65]++;
}
else
{
counts[a - 97] ++;
}
此代码假定'A'='a' 如果不是这种情况你需要在if中有不同的翻译,但你现在可以想出这个想法。与您的方法相比,这节省了大量的比较。
答案 1 :(得分:2)
根据目标是CPU效率,内存效率还是开发人员效率,您可以这样做:
foreach(var grp in theString.GroupBy(c => c)) {
Console.WriteLine("{0}: {1}", grp.Key, grp.Count());
}
效率不高,但在非病理情况下几乎没有效果。在实际场景中,由于unicode,我可能会使用字典作为计数器 - unicode很大,可以预先分配一个数组。
Dictionary<char, int> counts = new Dictionary<char, int>();
foreach(char c in theString) {
int count;
if(!counts.TryGetValue(c, out count)) count = 0;
counts[c] = count + 1;
}
foreach(var pair in counts) {
Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}
答案 2 :(得分:1)
您可以创建Dictionary<string, int>
,然后遍历数组,检查元素是否作为字典中的键存在并增加值。
Dictionary<string, int> counter = new Dictionary<string, int>();
foreach(var item in items)
{
if(counter.ContainsKey(item))
{
counter[item] = counter[item] + 1;
}
}
答案 3 :(得分:0)
这是一个很好的例子,它可以解决你的问题。
http://www.dotnetperls.com/array-find
string[] array1 = { "cat", "dog", "carrot", "bird" };</br>
//
// Find first element starting with substring.
//
string value1 = Array.Find(array1,
element => element.StartsWith("car", StringComparison.Ordinal));</br>
//
// Find first element of three characters length.
//
string value2 = Array.Find(array1,
element => element.Length == 3);
//
// Find all elements not greater than four letters long.
//
string[] array2 = Array.FindAll(array1,
element => element.Length <= 4);
Console.WriteLine(value1);
Console.WriteLine(value2);
Console.WriteLine(string.Join(",", array2));