C# - 如何在字符串数组中删除元音字母?

3
using System;    
using System.Collections.Generic;    
using System.Linq;   
using System.Text;    
using System.Threading.Tasks;

namespace myApp  
{    
    class Program
    {
        static void Main(string[] args)
        {
            string[] vowels = new string[]{"A","a","E","e","I","i","O","o","U","u"};
            for(int j=0;j<vowels.Length;j++)
            {
                string[] names = new string[5];
                names[0] = "john";
                names[1] = "samuel";
                names[2] = "kevin";
                names[3] = "steve";
                names[4] = "martyn";
            for (int i = 0; i < names.Length; i++)
            {
               if(vowels[j]==names[i])
               {

               }
            }


                Console.WriteLine("The output is:"+names[i]);
            }
                Console.ReadLine();
        }
    }
}

有人能帮我删除给定名称中的元音字母并在控制台中显示它们吗?


你正在将元音字母与整个名称进行比较。你需要循环遍历每个名称的每个字母以进行元音比较,或使用string.contains。此外,你可以只存储每个元音字母的一个版本(而不是大小写),并在比较中处理大小写。 - devlin carnate
1
if(vowels[j]==names[i])更改为names[i].Replace(vowels[j], ' '); - Les
在开始解析元音并且只包含大写元音字母的字符串[]vowels之前,您应该对字符串执行ToUpper()操作。这将提高性能。 - PeonProgrammer
7个回答

2

您可以使用Linq处理相关技术。

string[] names = new string[5];
names[0] = "john";
names[1] = "samuel";
names[2] = "kevin";
names[3] = "steve";
names[4] = "martyn";

var vowels = new HashSet<char>("AaEeIioUu");


names = names.Select(Name => string.Concat(Name.Where(C => !vowels.Contains(C))))
             .ToArray();

Console.WriteLine(string.Join(Environment.NewLine, names));

2

您可以使用Regex.Replace

Regex r = new Regex("[aAeEiIoOuU]");
//or Regex r = new Regex("[aeiou]", RegexOptions.IgnoreCase);
string[] names = new string[5];
names[0] = "john";
names[1] = "samuel";
names[2] = "kevin";
names[3] = "steve";
names[4] = "martyn";

for (int i = 0; i < names.Length; i++)
{
    names[i] = r.Replace(names[i], "");

    Console.WriteLine("The output is:" + names[i]);
}

为了让您的原始方法起作用,您需要添加一个调用string.Replace

names[i] = names[i].Replace(vowels[j], "");

这段代码的意思是“将names[i]中所有出现的vowels[j]替换,并将结果赋值给names[i]”。

然而,你目前是在元音字母循环内部声明了名字数组,所以如果添加替换代码,你不会得到预期的结果。

此外,你先循环元音字母再循环名字;逻辑上可能更合理的做法是反过来——这样输出结果会更容易。以下代码应该适用于你:

string[] vowels = new string[] { "A", "a", "E", "e", "I", "i", "O", "o", "U", "u" };

string[] names = new string[5];
names[0] = "john";
names[1] = "samuel";
names[2] = "kevin";
names[3] = "steve";
names[4] = "martyn";

for (int i = 0; i < names.Length; i++)
{
    for (int j = 0; j < vowels.Length; j++)
    {
        names[i] = names[i].Replace(vowels[j], "");
    }

    Console.WriteLine("The output is:" + names[i]);
}

编辑

在评论中,OP要求提供一个不使用Replace的示例。这里是一种方法(@Eser在他们的答案中还有另一种方法)。该方法迭代输入字符串的每个字符,直到找到一个元音字母。此时,已读取的字符(不包括元音字母)将添加到StringBuilder中:

public static string RemoveVowels(string name)
{
    StringBuilder noVowels = new StringBuilder();

    //keep track of the last index we read
    int lastIndex = 0;

    int i;
    for (i = 0; i < name.Length; i++)
    {
        if (vowels.Contains(name[i]))
        {
            //the current index is a vowel, take the text from the last read index to this index
            noVowels.Append(name, lastIndex, i - lastIndex);
            lastIndex = i + 1;
        }
    }

    if (lastIndex < i)
    {
        //the last character wasn't a vowel so we need to add the rest of the string here.
        noVowels.Append(name, lastIndex, name.Length - lastIndex);
    }

    return noVowels.ToString();
}

可以为数组中的每个名称调用上述方法:

for (int i = 0; i < names.Length; i++)
{
    Console.WriteLine("The output is:" + RemoveVowels(names[i]));
}

关于使用哪种方法,我会选择最易读的那个,除非你有一些特定的性能要求,在这种情况下,我认为你需要测量每种方法并选择最适合你要求的那个。

依我拙见,使用正则表达式来处理这个问题有点杀鸡用牛刀。 - Andrew
@j14 - 是的,你可以使用Esers answer中的方法,或者你可以迭代每个字符检查元音并将非元音添加到一个StringBuilder中(如果需要,我可以提供一个示例)。我认为除了被接受的答案之外的任何方法都适用于你。 - petelids
@petelids,你能回答我这个问题吗?我没听懂。 - tom_boy
@jc54 - 我已经更新了我的答案,包括一种方法。 - petelids

1

首先,如果您要处理一个名称数组,您需要使用嵌套循环。您必须遍历每个名称,然后在内部循环遍历每个元音字母。然后使用String.Replace来完成此过程。

name = name.Replace(vowels[j], String.Empty);

虽然这是正确的,但完整的代码片段会极大地改善这个答案。 - Michael McGriff
同意,但我更喜欢回答确切的问题或填补空白,而不是编写整个代码块,让别人可以简单地复制粘贴,而实际上并没有学到任何东西。 - Adam Milecki

0

我认为这是最简单的选择:

static void Main(string[] args)
{
    string[] names = new string[] { "john", "samuel", "george", "steve", "martyn" };

    foreach (var name in names)
    {
        string withoutVowels = new string(name.Where(x => !"aeiou".Contains(x)).ToArray());
        Console.WriteLine("The output is: " + withoutVowels);
    }
    Console.ReadKey();
}

如果您需要将文本转换为大写字母,只需使用以下代码行即可:
string withoutVowels = new string(name.Where(x => "aeiou".IndexOf(x.ToString(), StringComparison.InvariantCultureIgnoreCase) < 0).ToArray());

当然,你也可以使用“aeiouAEIOU”并坚持第一种选择。

仅仅为了好玩,这是基于Eser的答案的极短版本:

static void Main(string[] args)
{
    string[] names = new string[] { "johnE", "samuel", "george", "steve", "martyn" };
    Console.WriteLine(string.Join(Environment.NewLine, names.Select(s => new string(s.Where(x => !"aeiou".Contains(x)).ToArray()))));
}

0
Eser的回答是最简洁和正确的方法,但如果您想更精细地控制何时以及删除哪些元音字母,您也可以尝试类似以下的方法:
string[] names = new string[5];
names[0] = "john";
names[1] = "samuel";
names[2] = "kevin";
names[3] = "steve";
names[4] = "martyn";

List<char> vowels = new List<char>("AaEeIiOoUuYy".ToCharArray());

for(int i = 0; i < names.Length; i++) {
    string name = names[i];
    string trimmedName = name;

    foreach(char vowel in vowels) {
        int vowelIndex;
        while((vowelIndex = trimmedName.IndexOf(vowel)) != -1) {
            trimmedName = trimmedName.Substring(0, vowelIndex) + trimmedName.Substring(vowelIndex + 1);
        }

    }
    name = trimmedName;
}

尽管如此,这种方式更加明确,性能较差,而且肯定更加丑陋--因此,您可能希望采用原始方案。


-1
forech(string s in strings)
{
    s.Replace("a", "");
    // etc
}

4
我没有点踩,但我可以告诉你它被点踩的原因。 "Replace" 方法将返回一个新的字符串作为结果。它不会改变给定的字符串。这就是 s,你必须重新给它赋值才能应用更改。因此,使用 foreach 是不可能的,因为你无法修改只读值 s - M.kazem Akhgary
请注意,在StackOverflow上,仅包含代码的答案通常是不可接受的,因此可能会被删除。 - Wai Ha Lee

-1

你可以使用 ToUpper / ToLower 来检查元音字母,这样你就不必为每个大小写都列出一次元音字母。

首先循环遍历每个名称,然后从每个名称中循环遍历每个元音字母。然后,使用 .Replace() 删除匹配的元音字母。

这是一个可行的示例:

fiddle: https://dotnetfiddle.net/STnyWE

using System;    

public class Program
{
  public static void Main()
  {
    string[] vowels = new string[]{"A","E","I","O","U"};


            string[] names = new string[5];
            names[0] = "john";
            names[1] = "samuel";
            names[2] = "kevin";
            names[3] = "steve";
            names[4] = "martyn";

            for (int i = 0; i < names.Length; i++)
            {
                foreach(var v in vowels)
                {

                    if(names[i].ToString().ToUpper().Contains(v.ToString()))
                    {
                        Console.WriteLine(names[i]);
                        names[i] = names[i].ToString().ToUpper().Replace(v.ToString(), "");
                        Console.WriteLine("The output is: "+names[i].ToString().ToLower());
                    }
                }
            }

            Console.ReadLine();
   }
}

1
问题在于您会失去原始名称中的任何可能的大写字母。此外,这种方法有点冗长,当您可以使用Linq获得更短的代码时,就像其他答案中所看到的一样(例如我的答案)。 - Andrew
我绝对喜欢Linq。我是个粉丝。我只想使用他现有的代码,并稍作修改以解决问题。OP在他的示例中没有使用大小写,所以我将它们全部转换为小写。当然,我们可以使用ToTitleCase来处理名称,例如CultureInfo.CurrentCulture.TextInfo.ToTitleCase(names[i].ToString().ToLower())。你说得对,如果其他地方出现大小写问题,那就会有问题。 - NKD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接