我正在学习使用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
或我想学习使用的任何其他类型。您能否使用myString
或struct
(您认为哪个更好)在enum
字符串中查找每个字符的最佳方式来帮助我将元音保存在其中?
谢谢
Leron
答案 0 :(得分:7)
考虑在编程中完成任务并不是一种有用的方式...尤其是这一点。在这种情况下,您正在进行数据处理,这更适合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);
}
不需要枚举或类似的东西。您应该考虑任务中涉及的步骤,然后考虑是否需要存储状态,如果需要,是什么类型的状态等。
答案 1 :(得分:1)
struct
s,enum
和class
es都是固定大小(非常非常简单)的数据结构。即,每个结构总是保持相同数量的信息,无论其价值如何。与javascript不同,您无法动态地将成员添加到C#struct。
你试图在某些集合中找到所有字符实例 - 虽然你碰巧知道该集合的大小,但你已经注意到它不是一个非常通用的解决方案。通常,集合不是固定大小:因此没有“只使用结构”的解决方案。你在这里看错了抽象层次。
相当于一个javascript对象(您可以在其中添加成员a
e
i
o
u
,然后使用该对象检查是否存在在.NET中作为成员出现的字母是Dictionary<string, object>
。但是,您知道您的密钥是单个字母,因此您可以使用char
而不是string
,而且您还不需要使用这些密钥保存任何值(您只关心是否存在密钥)所以你可以使用HashSet<char>
。
无论如何;通常,您无法轻松地将动态值(如某些输入字母)映射到静态概念(例如类型的成员)(至少不会没有缓慢,不方便,容易出错的技术,如反射)。虽然枚举值是运行时(动态)变量,但是你不能轻易地使用它们,因为(1)你很难轻易地将char
很容易地转换为enum
而没有至少像大的if语句,(2)即使你可以,你通常也无法测试枚举是否是某些集合的成员,你可以检查char是否是某些集合的成员。
回顾一下:枚举不起作用,char
- &gt; enum
不是“琐碎”转换,struct
成员是静态概念,你不能真的比较一个动态的概念,比如一封信的价值。
另一个小细节:给定输入“另一个小细节”......
,您的示例方法将产生不正确的输出答案 2 :(得分:1)
也许这就是你要找的东西:
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;
正如其他人所指出的那样 - 我并不是说这是执行此任务的正确方法。我只是回答一下似乎是主要观点 - 如何获得这些对象的部分列表。
答案 3 :(得分:1)
“我在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;
}
答案 4 :(得分:0)
以下是完成任务的几种不同方法。
这个很简单:
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