我必须编写一个程序来检查输入是否是回文,并且在此代码中,我需要有一个从字符串中删除所有非字母字符的方法。做这个的最好方式是什么?将输入转换为数组是否更好(现在我以字符串形式进行操作)?我不想为每个单独的字符编写一个循环或将每个字符放入修剪中。装饰也会在中间脱掉吗?
我也不被允许使用正则表达式,可枚举或抛出新异常,因为教授不是后两者的拥护者,而前一个不起作用,只会抛出错误。
我这样做的方式似乎并不是解决此问题的最有效方法。
我的代码在这里:
public partial class frmPalindrome : Form
{
public frmPalindrome()
{
InitializeComponent();
}
//allows btnCheck to take in user input in txtEnterWordPhrase and check if it is a palindrome
private void btnCheck_Click(object sender, EventArgs e)
{
try
{
if (IsValidData())
{
string strPhrase = Convert.ToString(txtEnterWordPhrase.Text);
string strCleanPhrase = CharacterStrip(strPhrase);
txtPalindrome.Text = Convert.ToString(IsPalindrome(strCleanPhrase));
}
}
catch (Exception ex) //catches any other exceptions
{
MessageBox.Show(ex.Message + "\n\n" + ex.GetType().ToString() + "\n" + ex.StackTrace, "Exception");
}
}
//a method that cuts all the nonalphabetic characters out of txtEnterWordPhrase
public string CharacterStrip(string Phrase)
{
//neither of these seem very efficient
//Phrase = Phrase.Trim(new Char[] {' ', '&', '*', ',', '-', '_', '/', '\', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', });
while (Phrase.IndexOf(" ") >= 0)
{
int intIndex = Phrase.IndexOf(" ");
Phrase.Remove(intIndex, 1);
}
return Phrase;
}
//checks if the input is a palindrome
public bool IsPalindrome(string Phrase)
{
//not sure how to do this yet
return true; //have not built this method yet
}
//checks that the input is valid
public bool IsValidData ()
{
return IsString(txtEnterWordPhrase, "Enter a Word or Phrase"); //have not built this validation method yet
}
//checks that the input in txtEnterWordPhrase is a string
public bool IsString(TextBox Textbox, string Name)
{
decimal Number = 0m;
if (Decimal.TryParse(Textbox.Text, out Number))
{
MessageBox.Show(Name + " must be a word or phrase.", "Entry Error");
return false;
}
else
return true;
}
//allows btnExit to close the program
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
//a method that clears txtPalindrome and returns focus to txtEnterWordPhrase
private void ClearResults(object sender, EventArgs e)
{
txtPalindrome.Text = "";
txtEnterWordPhrase.Focus();
}
}
答案 0 :(得分:1)
简单的LINQ解决方案就像
string exampleString = "123 Example Text 456";
string onlyAlpha = new string(exampleString.Where(c => Char.IsLetter(c)).ToArray());
Console.WriteLine(onlyAlpha);
输出:
Example Text
实际上没有什么方法可以避免在某个级别循环遍历字符串。
答案 1 :(得分:0)
首先,示例方法CharacterStrip
存在几个问题。 Phrase.Trim()
仅会修剪字符串开头和结尾的字符,因此,一旦遇到不在数组中的字符,它将假定它属于该字符并停止处理。因此,它不会从您的字符串中删除所有非字母字符。
第二,Phrase.Remove()
返回一个删除了1个字符的新字符串-您没有使用该字符串。您可能打算再次将结果分配给Phrase
。 C#学习的一个重要原则是字符串的不变性:拥有字符串后就无法更改,只能从该字符串创建一个新字符串,在这种情况下,该字符串具有给定索引中的字符删除。这就是说,即使进行了此修订,您的while循环也不会删除非字母字符,只会删除空格。
因此,在担心效率之前,让我们先从有效的方法开始,不管它多么微妙:
public string CharacterStrip(string phrase)
{
string[] chars = new string[] { " ", "&", "*", ",", "-", "_", "/", "\\", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", };
foreach (string c in chars)
phrase = phrase.Replace(c, "");
return phrase;
}
这有一个缺点,您将需要维护字符数组(存储为字符串)以包括所有非字母字符,虽然目前还没有,但这只是一个开始。
接下来的另一种方法是,在原始字符串上使用循环,利用Char.IsLetter
,如Matt的建议所示。这意味着您不需要维护要删除的字符数组。
string output = "";
foreach (char c in phrase)
{
if (Char.IsLetter(c))
output = output + c;
}
return output;
但是,这仍然会在每次循环迭代中一遍又一遍地创建新的字符串(请记住这是字符串的工作方式),这不是很有效。
最有效的方法是,您可以使用奇妙的StringBuilder
类,该类维护一个 mutable 字符/字符串集合,完成后可以组装为单个字符串。值得一读的是,如果您有兴趣以有效的方式进行大量的字符串操作:
StringBuilder builder = new StringBuilder();
foreach (char c in phrase)
{
if (Char.IsLetter(c))
builder.Append(c);
}
return builder.ToString();
答案 2 :(得分:0)
就像:
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
phrase= rgx.Replace(phrase, "");