C# - 使用结构或枚举查找字符串中的元音
本文关键字:字符串 查找 枚举 结构 | 更新日期: 2024-11-08 11:16:09
我正在学习使用C#中的主要类型。为此,我制作了一个简单的算法来查找字符串中的元音。在这里:
public static string Vowels()
{
string myString = "Count the number of the vowels in this string";
string output = string.Empty;
for (int i = 0; i < myString.Length; i++)
{
if (myString[i] == 'a' || myString[i] == 'e' ||
myString[i] == 'i' || myString[i] == 'o' ||
myString[i] == 'u')
{
output += myString[i].ToString().ToUpper(); //Vowel
}
}
return output;
}
问题是,首先 - 我不喜欢我的if
语句中的太多条件,所以我认为使用一些指称类型将是一种更优雅的方式来容纳元音,其次,即使有充分的理由选择if
语句而不是struct
、enum
或任何其他类型我也想学习使用它们。您能否帮助我使用struct
或enum
(您认为更好)来保存元音myString
查找字符串中的每个字符的最佳方法?
谢谢
莱龙
编程中完成任务并不是一种有用的方法......尤其是这个。在本例中,您正在执行更适合 LINQ 的数据处理。例如,您的方法可以实现为:
public static string ExtractVowels(string text)
{
// Note that this won't find upper-case vowels...
var vowelArray = text.Where(c => "aeiou".Contains(c))
.ToArray();
// Upper-case it if you want, of course.
return new string(vowelArray);
}
不需要枚举或类似的东西。您应该考虑任务中涉及的步骤,然后考虑是否需要存储状态,如果是,则需要存储哪种状态等。
也许这就是你要找的:
Enum.GetNames(typeof(myenum)).Contains(...);
像这样使用:
enum myenum { a, e, i, o, u }
和:
for (int i = 0; i < mystring.Length; i++)
if (Enum.GetNames(typeof(myenum)).Contains(mystring.Substring(i, 1)))
Text = "True";
要查找struct
(或class
,就此而言)中的字段,请使用以下内容:
System.Reflection.FieldInfo[] fi = typeof(mystruct).GetFields();
Text = fi[0].Name;
正如其他人指出的那样 - 我并不是说这是执行此任务的正确方法。我只是在回答似乎是要点的问题 - 如何获取这些对象的部分列表。
struct
s、enum
s 和 class
es 都是固定大小(而且非常非常简单)的数据结构。 也就是说,每个结构总是保存相同数量的信息,无论其值如何。 与 JavaScript 不同,不能动态地将成员添加到 C# 结构。
您正在尝试查找某个集合中的所有字符实例 - 尽管您碰巧知道该集合的大小,但您已经注意到它不是一个非常通用的解决方案。 一般来说,集合不是固定大小的:所以没有"只使用结构"的解决方案。 你在这里看到的是错误的抽象级别。
相当于 .NET 中的 javascript 对象(您可以在其中添加成员a
e
i
o
u
然后使用该对象检查字母是否作为成员出现)是一个Dictionary<string, object>
。 但是,您知道您的键是单个字母,因此您可以使用char
而不是string
,并且您不需要使用这些键保存任何值(您只关心键的存在/不存在),因此您可以使用HashSet<char>
。
在任何情况下;通常,您都无法轻松地将动态值(如某些输入字母)映射到静态概念(如类型成员)(至少没有缓慢、不方便、容易出错的技术(如反射)是这样)。 尽管枚举值是运行时(动态)变量,但您也不能轻松使用它们,因为 (1) 如果没有至少像大型 if 语句这样复杂的东西,您就无法真正轻松地将 char
很好地转换为enum
,以及 (2) 即使你可以,您通常也无法更好地测试枚举是否是某个集合的成员,您可以检查 char 是否是某个集合的成员。
回顾一下:枚举没有帮助,char
-> enum
不是一个"微不足道"的转换,struct
的成员是静态概念,您无法真正将其与动态概念(例如字母的值)进行比较。
:您的示例方法将在输入"另一个小细节"的情况下产生不正确的输出......
我不喜欢我的if语句中有那么多条件"可以这样解决:
public static string Vowels()
{
string myString = "Count the number of the vowels in this string";
string output = string.Empty;
for (int i = 0; i < myString.Length; i++)
{
switch(myString[i])
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
output += myString[i].ToString().ToUpper(); //Vowel
break;
}
}
return output;
}
如果您想完全从函数中提取字母,请尝试:
string Vowels = "aeiou";
public static string Vowels()
{
string myString = "Count the number of the vowels in this string";
string output = string.Empty;
for (int i = 0; i < myString.Length; i++)
{
if(Vowels.Contains(myString[i]))
{
output += myString[i].ToString().ToUpper(); //Vowel
break;
}
}
return output;
}
这里有几种不同的方法来完成你的任务。
这个很简单:
private static readonly char[] vowel = "aeiouAEIOU".ToArray() ;
public static string ExtractVowels_1( string s )
{
if ( s == null ) throw new ArgumentNullException("s");
StringBuilder sb = new StringBuilder( s.Length ) ;
for ( int i = s.IndexOfAny(vowel) ; i >= 0 ; i = s.IndexOfAny(vowel , i+1 ) )
{
sb.Append(s[i]) ;
}
return sb.ToString() ;
}
这甚至更简单:
private static readonly Regex rxVowels = new Regex( "[^aeiou]+" , RegexOptions.IgnoreCase ) ;
public static string ExtractVowels_2( string s )
{
string vowels = rxVowels.Replace( s , "" ) ;
return vowels ;
}
你可以得到所有的Linqy,"流利",如果你愿意:
private static readonly SortedSet<char> setOfVowels = new SortedSet<char>( "aeiouAEIOU" ) ;
private static string ExtractVowels_3( string s )
{
if ( s == null ) throw new ArgumentNullException("s");
string vowels = new string( s.Where( c => setOfVowels.Contains(c) ).ToArray() ) ;
return vowels ;
}
正如Perl Monks所说,"Tim Toady"或TMTOWTDI:有不止一种方法可以做到这一点。
http://en.wikipedia.org/wiki/There's_more_than_one_way_to_do_it