gpt4 book ai didi

c# - 测试角色是否属于 .net 中某个类别的最佳方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:16:20 25 4
gpt4 key购买 nike

我需要一种有效的方法来测试给定字符 (System.Char) 是否为辅音。然后我需要同样的元音。更一般地说,我需要以下接口(interface)的有效实现,因为目标字符集大约有 20 个字符。请指教。谢谢!

using System;

public interface ITester
{
Boolean IsInCategory(Char something);
}

更新

好的,我已经进行了一些测试。这就是我得到的。最好的方法是使用预先计算的映射,其中每个字符都映射到一个 bool 值。 (请参阅下面代码中的 IndexBased)。事实证明,HashSet 并不是最好的。如果有人有更多想法,请告诉我。

[TestClass]
public class Runner
{
public const Int32 NumberOfRuns = 10000;
public const String TextSample = @"The Letter It was November. Although it was not yet late, the sky was dark when I turned into Laundress Passage. Father had finished for the day, switched off the shop lights and closed the shutters; but so I would not come home to darkness he had left on the light over the stairs to the flat. Through the glass in the door it cast a foolscap rectangle of paleness onto the wet pavement, and it was while I was standing in that rectangle, about to turn my key in the door, that I first saw the letter. Another white rectangle, it was on the fifth step from the bottom, where I couldn't miss it. I closed the door and put the shop key in its usual place behind Bailey's Advanced Principles of Geometry. Poor Bailey. No one has wanted his fat gray book for thirty years. Sometimes I wonder what he makes of his role as guardian of the bookshop keys. I don't suppose it's the destiny he had in mind for the masterwork that he spent two decades writing. A letter. For me. That was something of an event. The crisp-cornered envelope, puffed up with its thickly folded contents, was addressed in a hand that must have given the postman a certain amount of trouble. Although the style of the writing was old-fashioned, with its heavily embellished capitals and curly flourishes, my first impression was that it had been written by a child. The letters seemed untrained. Their uneven strokes either faded into nothing or were heavily etched into the paper. There was no sense of flow in the letters that spelled out my name.";
private interface ITester
{
Boolean IsConsonant(Char something);
}

// results in millisecs: 14807, 16411, 15050,
private class HashSetBasedTester : ITester
{
private HashSet<Char> hash;
public HashSetBasedTester()
{
this.hash = new HashSet<Char>("bcdfghjklmnpqrstvwxz");
}
public Boolean IsConsonant(Char something)
{
return this.hash.Contains(Char.ToLower(something));
}
}

// results in millisecs: 12270, 12495, 12853,
private class HardcodedTester : ITester
{
public Boolean IsConsonant(Char something)
{
var lower = Char.ToLower(something);
return lower == 'b' || lower == 'c' || lower == 'd' || lower == 'f' || lower == 'g' || lower == 'h' || lower == 'j' || lower == 'k' || lower == 'l' || lower == 'm' || lower == 'n' || lower == 'p' || lower == 'q' || lower == 'r' || lower == 's' || lower == 't' || lower == 'v' || lower == 'w' || lower == 'x' || lower == 'z';
}
}

// WORST RESULTS
// results in millisecs: 32140, 31549, 31856
private class ListBasedTester : ITester
{
private List<Char> list;
public ListBasedTester()
{
this.list = new List<Char> { 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z' };
}
public Boolean IsConsonant(Char something)
{
return this.list.Contains(Char.ToLower(something));
}
}

// WINNER! (fastest and most consistent)
// results in millisecs: 11335, 11349, 11386,
private class IndexBased : ITester
{
private Boolean[] map;
private char min;
private char max;
public IndexBased()
{
var chars = "bcdfghjklmnpqrstvwxz".ToArray();
this.min = chars.Min();
this.max = chars.Max();
var length = this.max - this.min + 1;
this.map = new Boolean[length];
foreach (var at in chars)
{
map[at - min] = true;
}
}
public Boolean IsConsonant(Char something)
{
something = Char.ToLower(something);
return something <= this.max && something >= this.min && this.map[something - this.min];
}
}


[TestMethod]
public void RunTest()
{
var tester = new IndexBased(); // new HashSetBasedTester(); // new HardcodedTester(); // new ListBasedTester(); //
var stopwatch = Stopwatch.StartNew();
for (var i = 0; i < NumberOfRuns; i++)
{
foreach (var at in TextSample)
{
var tested = tester.IsConsonant(at);
}
}
Trace.WriteLine(stopwatch.ElapsedMilliseconds.ToString());
}
}

更新 2:

这组测试没有转换为下/上,我们得到了更好的结果!无论如何,热门/失败者都是一样的。检查一下:

[TestClass]
public class Runner
{
public const Int32 NumberOfRuns = 10000;
public const String TextSample = @"The Letter It was November. Although it was not yet late, the sky was dark when I turned into Laundress Passage. Father had finished for the day, switched off the shop lights and closed the shutters; but so I would not come home to darkness he had left on the light over the stairs to the flat. Through the glass in the door it cast a foolscap rectangle of paleness onto the wet pavement, and it was while I was standing in that rectangle, about to turn my key in the door, that I first saw the letter. Another white rectangle, it was on the fifth step from the bottom, where I couldn't miss it. I closed the door and put the shop key in its usual place behind Bailey's Advanced Principles of Geometry. Poor Bailey. No one has wanted his fat gray book for thirty years. Sometimes I wonder what he makes of his role as guardian of the bookshop keys. I don't suppose it's the destiny he had in mind for the masterwork that he spent two decades writing. A letter. For me. That was something of an event. The crisp-cornered envelope, puffed up with its thickly folded contents, was addressed in a hand that must have given the postman a certain amount of trouble. Although the style of the writing was old-fashioned, with its heavily embellished capitals and curly flourishes, my first impression was that it had been written by a child. The letters seemed untrained. Their uneven strokes either faded into nothing or were heavily etched into the paper. There was no sense of flow in the letters that spelled out my name.";
private interface ITester
{
Boolean IsConsonant(Char something);
}

// results in millisecs: 8378, 7980, 7533, 7752
private class HashSetBasedTester : ITester
{
private HashSet<Char> hash;
public HashSetBasedTester()
{
this.hash = new HashSet<Char>("bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ");
}
public Boolean IsConsonant(Char something)
{
return this.hash.Contains(something);
}
}

// results in millisecs: 6406, 6667, 6500, 6708
private class HardcodedTester : ITester
{
public Boolean IsConsonant(Char something)
{
return something == 'b' || something == 'c' || something == 'd' || something == 'f' || something == 'g' || something == 'h' || something == 'j' || something == 'k' || something == 'l' || something == 'm' || something == 'n' || something == 'p' || something == 'q' || something == 'r' || something == 's' || something == 't' || something == 'v' || something == 'w' || something == 'x' || something == 'z' ||
something == 'B' || something == 'C' || something == 'D' || something == 'F' || something == 'G' || something == 'H' || something == 'J' || something == 'K' || something == 'L' || something == 'M' || something == 'N' || something == 'P' || something == 'Q' || something == 'R' || something == 'S' || something == 'T' || something == 'V' || something == 'W' || something == 'X' || something == 'Z';
}
}

// WORST RESULTS
// results in millisecs: 36585, 37702, ...
private class ListBasedTester : ITester
{
private List<Char> list;
public ListBasedTester()
{
this.list = new List<Char> { 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z',
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Z' };
}
public Boolean IsConsonant(Char something)
{
return this.list.Contains(something);
}
}

// WINNER!
// results in millisecs: 4716, 4846, 4756, 4550
private class IndexBased : ITester
{
private Boolean[] map;
private char min;
private char max;
public IndexBased()
{
var chars = "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ".ToArray();
this.min = chars.Min();
this.max = chars.Max();
var length = this.max - this.min + 1;
this.map = new Boolean[length];
foreach (var at in chars)
{
map[at - min] = true;
}
}
public Boolean IsConsonant(Char something)
{
return something <= this.max && something >= this.min && this.map[something - this.min];
}
}


[TestMethod]
public void RunTest()
{
var tester = new IndexBased();//new IndexBased(); // new HashSetBasedTester(); // new HardcodedTester(); // new ListBasedTester(); //
var stopwatch = Stopwatch.StartNew();
for (var i = 0; i < NumberOfRuns; i++)
{
foreach (var at in TextSample)
{
var tested = tester.IsConsonant(at);
}
}
Trace.WriteLine(stopwatch.ElapsedMilliseconds.ToString());
}
}

最佳答案

HashSet<char> 会成功的。为辅音、元音等创建单独的实例,并使用它们来测试成员资格。

ISet<char> vowels = new HashSet<char>("auoie");

if (vowels.Contains('a')) {
// ...
}

更新:对于英文字符子集,您可以构建一个 bool数组 - 类似于您在更新中使用的数组,但没有 min 的偏移量, 以及大写/小写重复:它会更快 - 几乎和它得到的一样快。

private class IndexBased : ITester {
private readonly bool[] map = new bool[128];
public IndexBased() {
foreach (var ch in "bcdfghjklmnpqrstvwxz") {
map[ch] = map[Char.ToUpper(ch)] = true;
}
}
public bool IsConsonant(Char ch) {
return ch < map.Length && map[ch];
}
}

关于c# - 测试角色是否属于 .net 中某个类别的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10607374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com