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语句而不是structenum或任何其他类型我也想学习使用它们。您能否帮助我使用structenum(您认为更好)来保存元音myString查找字符串中的每个字符的最佳方法?

谢谢

莱龙

C# - 使用结构或枚举查找字符串中的元音

编程中完成任务并不是一种有用的方法......尤其是这个。在本例中,您正在执行更适合 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