0

我正在学习使用 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或者我也想学习使用它们的任何其他类型。你能帮我找到最好的方法来查找myString字符串中的每个字符,struct或者enum(你认为更好)来保存元音吗?

谢谢

勒龙

4

5 回答 5

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);
}

不需要枚举或类似的东西。你应该考虑一个任务涉及的步骤,然后考虑是否需要存储状态,如果需要存储什么样的状态等。

于 2012-08-08T22:18:15.740 回答
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;
    }
于 2012-08-24T11:50:26.353 回答
1

structs、enums 和classes 都是固定大小(非常非常简单)的数据结构。即,每个结构总是包含相同数量的信息,无论其值如何。与 javascript 不同,您不能动态地将成员添加到 C# 结构中。

您正在尝试查找某个集合中的所有字符实例 - 尽管您碰巧知道该集合的大小,但您已经注意到这不是一个非常通用的解决方案。一般来说,集合不是固定大小的:所以没有“只使用结构”的解决方案。您在这里查看了错误的抽象级别。

.NET中的 javascript 对象(您可以在其中添加成员a e i o u,然后使用该对象检查字母是否作为成员出现)的等价物是Dictionary<string, object>. 但是,您知道您的键是单个字母,因此您可以使用char而不是string,而且您不需要使用这些键保存任何值(您只关心键的存在/不存在),因此您可以使用 HashSet<char>.

任何状况之下; 通常,您不能轻松地将诸如某些输入字母之类的动态值映射到诸如类型成员之类的静态概念(至少在没有诸如反射之类的缓慢,不方便,容易出错的技术的情况下并非如此)。尽管枚举值是运行时(动态)变量,但您也不能轻易使用它们,因为(1)如果没有至少像大 if 语句那样复杂的东西,您也不能真正轻松地转换charenum很好的变量,以及(2)即使你可以,你通常不能更好地测试枚举是否是某个集合的成员,而你可以检查 char 是否是某个集合的成员。

回顾一下:枚举没有帮助,并且char->enum不是“微不足道”的转换,并且structs 成员是静态概念,您无法真正将其与动态概念(例如字母的值)进行比较。

另一个小细节:给定输入“另一个小细节”,您的示例方法将产生不正确的输出......

于 2012-08-08T22:23:31.507 回答
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要在 a (或class,就此而言)中查找字段,请使用以下内容:

System.Reflection.FieldInfo[] fi = typeof(mystruct).GetFields();
Text = fi[0].Name;

正如其他人所指出的 - 我并不是说这是执行此任务的正确方法。我只是在回答似乎是要点-如何获取这些对象的部分列表。

于 2012-08-08T22:41:56.327 回答
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

于 2012-08-09T00:23:47.497 回答