我正在开发一个简单的hangman程序。我有大部分代码工作,但我无法弄清楚如何在char数组中获取多个匹配字符的索引。例如,我有一个单词“sushi”转换为char数组。如果用户猜到“s”,则应显示char数组中的所有“s”。我的代码的方式,实际上有两个相同长度的char数组。第一个数组保存单词的字符以进行猜测,而第二个数组保存问号。我的代码应遍历第一个数组并返回与用户猜测匹配的数组中每个元素的索引。然后,代码在每个指定的索引处插入用户猜测,并为用户显示第二个数组。不幸的是,在第二个数组中只更改了第一个匹配项,因此只从匹配查询返回第一个索引。有问题的代码如下:
//check if char array contains the user input
if (guessThis.Contains(Convert.ToChar(textBox1.Text)))
{
//save user input as char
char userGuess = Convert.ToChar(textBox1.Text);
//iterate through first char array
for (int i = 0; i < guessThis.Length - 1; i++ )
{
//check each element in the array
//probably don't need both for and foreach loops
foreach (char c in guessThis)
{
//get index of any element that contains the userinput
var getIndex = Array.IndexOf(guessThis, c);
//check if the element matches the user guess
if (c == userGuess)
{
//insert the userguess into the index
displayAnswer[getIndex] = userGuess;
}
}
}
//update the display label
answerLabel.Text = new string(displayAnswer);
解决: 使用所选答案中的示例,我将代码更新为:
//check if char array contains the user input
if (guessThis.Contains(Convert.ToChar(textBox1.Text)))
{
//save user input as char
char userGuess = Convert.ToChar(textBox1.Text);
string maybeThis = textBox1.Text;
string tryThis = new string(guessThis);
foreach (Match m in Regex.Matches(tryThis, maybeThis))
{
displayAnswer[m.Index] = userGuess;
}
answerLabel.Text = new string(displayAnswer);
}
答案 0 :(得分:1)
因为你的:
var getIndex = Array.IndexOf(guessThis, c);
总是返回第一次出现的角色。
你的第二个for循环和getIndex是无用的,更清晰的代码可能是:
for (int i = 0; i < guessThis.Length - 1; i++ )
{
//check if the element matches the user guess
if (c == userGuess[i])
{
//insert the userguess into the index
displayAnswer[i] = userGuess;
}
}
此外,您的代码允许用户在textBox1中输入多个字符。我认为在这种游戏中,每次只能猜到一个角色。所以我建议你限制你的意见。
答案 1 :(得分:1)
尝试Regex.Matches
构建正则表达式并查找所有匹配项及其位置。
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = "a*";
string input = "abaabb";
foreach (Match m in Regex.Matches(input, pattern))
Console.WriteLine("'{0}' found at index {1}.",
m.Value, m.Index);
}
}
// The example displays the following output:
// 'a' found at index 0.
// '' found at index 1.
// 'aa' found at index 2.
// '' found at index 4.
// '' found at index 5.
// '' found at index 6.`
http://msdn.microsoft.com/en-gb/library/system.text.regularexpressions.regex.matches(v=vs.110).aspx
答案 2 :(得分:1)
我认为问题在于方法: var getIndex = Array.IndexOf(guessThis,c); 因为它返回第一个位置。 您可以使用for循环中的索引
答案 3 :(得分:0)
你可以这样做(为了清晰起见,通用了):
public static IEnumerable<int> AllIndexesOfAny<T>(this IList<T> list, IEnumerable<T> ofAny)
{
return Enumerable.Range(0, list.Count).Where(i => ofAny.Contains(list[i]));
}
如果性能问题,您可以将IEnumerable<T> ofAny
替换为HashSet
。
<强>更新强>
只需更仔细地阅读您的代码,并意识到您正在通过guessThis
建立索引,并为guessThis
中的每个字符找到guessThis
中的索引,并检查它是否与{{1}匹配}。这是不必要的。在thisGuess
匹配guessThis
中查找所有字符索引的最简单的非通用方法可能是:
userGuess
附加说明
顺便说一句,它可能对您的应用程序并不重要,但.Net中的一些非ASCII Unicode字符实际上由surrogate pairs of chars表示。 (还有diacritical combining characters修改了前面的字符。)在&#34;国际化的&#34;您可能希望通过将代理人对转换为UTF32 code points来处理代理人对的刽子手游戏:
var matches = Enumerable.Range(0, guessThis.Length).Where(i => guessThis[i] == userGuess);
答案 4 :(得分:0)
尝试这样的事情:
char userGuess = Convert.ToChar(textBox1.Text);
char[] displayAnswer = answerLabel.Text.ToCharArray();
for (int n = 0; n < displayAnswer.Length; n++)
{
if (guessThis[n] == userGuess)
{
displayAnswer[n] = userGuess;
}
}
answerLabel.Text = new string(displayAnswer);
一种简单的方法