C# 如何仅从字符串数组中拾取一次随机字符串
我正在尝试用C语言制作Hangman,在游戏开始时,你需要猜一个单词,这样游戏就不会无聊了,一次只能猜一个单词。但是当你开始一个新游戏时,你不会得到一个你已经猜到的单词。所以我必须选择一个我还没有选择的随机字符串 我尝试了多种方法来解决这个问题,但都没有成功 方法1: 在这里,我运行NewWord函数,然后在numberOfTries中添加1C# 如何仅从字符串数组中拾取一次随机字符串,c#,arrays,string,random,combinations,C#,Arrays,String,Random,Combinations,我正在尝试用C语言制作Hangman,在游戏开始时,你需要猜一个单词,这样游戏就不会无聊了,一次只能猜一个单词。但是当你开始一个新游戏时,你不会得到一个你已经猜到的单词。所以我必须选择一个我还没有选择的随机字符串 我尝试了多种方法来解决这个问题,但都没有成功 方法1: 在这里,我运行NewWord函数,然后在numberOfTries中添加1 string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "ST
string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
int numberOfTries = 0;
int randomNumber = -1;
protected string NewWord()
{
if (!(numberOfTries >= wordArr.Length))
{
randomNumber = RandomNumberFromTo(0, (wordArr.Length - numberOfTries));
ChangeWord(((wordArr.Length - numberOfTries)-1), randomNumber);
return wordArr[(randomNumberl)];
}
else
{
return "There are no more new words!! :(";
}
}
private int RandomNumberFromTo(int NumberA, int NumberB)
{
System.Threading.Thread.Sleep(2);
Random minRandomGenerator = new Random();
System.Threading.Thread.Sleep(3);
return minRandomGenerator.Next(NumberA, NumberB);
}
protected void ChangeWord (int NumberA, int NumberB)
{
string cashe1 = wordArr[NumberA];
wordArr[NumberA] = wordArr[NumberB];
wordArr[NumberB] = cashe1;
return;
}
string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
int numberOfTries = 0;
Random random = new Random();
protected string NyttOrd()
{
if (!(numberOfTries >= wordArr.Length))
{
var names = new List<string> { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
System.Threading.Thread.Sleep(3);
int index = random.Next(names.Count);
var name = names[index];
names.RemoveAt(index);
return name;
}
else
{
return "There are no more new words!! :(";
}
}
我在StackOverflow上找到了方法2,但它不起作用
在这里,我还运行了NewWord函数,然后将1添加到numberOfTries
string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
int numberOfTries = 0;
int randomNumber = -1;
protected string NewWord()
{
if (!(numberOfTries >= wordArr.Length))
{
randomNumber = RandomNumberFromTo(0, (wordArr.Length - numberOfTries));
ChangeWord(((wordArr.Length - numberOfTries)-1), randomNumber);
return wordArr[(randomNumberl)];
}
else
{
return "There are no more new words!! :(";
}
}
private int RandomNumberFromTo(int NumberA, int NumberB)
{
System.Threading.Thread.Sleep(2);
Random minRandomGenerator = new Random();
System.Threading.Thread.Sleep(3);
return minRandomGenerator.Next(NumberA, NumberB);
}
protected void ChangeWord (int NumberA, int NumberB)
{
string cashe1 = wordArr[NumberA];
wordArr[NumberA] = wordArr[NumberB];
wordArr[NumberB] = cashe1;
return;
}
string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
int numberOfTries = 0;
Random random = new Random();
protected string NyttOrd()
{
if (!(numberOfTries >= wordArr.Length))
{
var names = new List<string> { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
System.Threading.Thread.Sleep(3);
int index = random.Next(names.Count);
var name = names[index];
names.RemoveAt(index);
return name;
}
else
{
return "There are no more new words!! :(";
}
}
我还尝试了一个版本,其中我有两个不同的数组,一个是Int数组,另一个是字符串数组。它真的很乱,不起作用
我对C语言也很陌生,我只知道一些基本知识,如+-/*、转换、函数和数组。从概念上讲,您可以跟踪已使用的字符串,也可以在使用时从可选字符串列表中删除字符串
static readonly List<string> Words = new List<string>(wordArr);
static readonly Random Rnd = new Random();
public string Next()
{
if(Words.Count < 1)
return "There are no more new words!! :(";
var index = Rnd.Next(0, Words.Length);
var result = Words[index];
Words.RemoveAt(index);
return result;
}
要实现第一种方法,您可以保留一个已使用字符串的哈希表,在提取新字符串时—查看它是否存在于哈希表中,如果存在,则选择另一个,直到选择新字符串
要实现第二种方法,只需在拾取字符串时将其从列表中移除。从概念上讲,您可以跟踪已使用的字符串,也可以在使用可选字符串时将其从列表中移除 要实现第一种方法,您可以保留一个已使用字符串的哈希表,在提取新字符串时—查看它是否存在于哈希表中,如果存在,则选择另一个,直到选择新字符串 要实现第二种方法,只需在拾取字符串时将其从列表中移除。使用 关键是你的字,值是它被使用了多少次,然后只取使用最少的字并增加它的计数器
List<KeyValuePair<string, int>>
使用
关键是你的字,值是它被使用了多少次,然后只取使用最少的字并增加它的计数器
List<KeyValuePair<string, int>>
如果您洗牌您的单词数组:
var r = new Random();
var shuffledWords = wordArr.OrderBy(_ => r.Next());
然后把你的话放进一堆:
var wordStack = new Stack<string>(shuffledWords);
如果您洗牌您的单词数组:
var r = new Random();
var shuffledWords = wordArr.OrderBy(_ => r.Next());
然后把你的话放进一堆:
var wordStack = new Stack<string>(shuffledWords);
既然你已经说过你是编程新手,我将很快解释一下要点: .Except将您的数组与其他数组进行比较,并仅返回唯一的元素。 .OrderByx=>rn.Next将以随机顺序返回数组。 .FirstOrDefault将从数组中获取第一个条目,如果数组为空,则返回null
public void GenerateWord()
{
Random rn = new Random();
string[] attemptedWords = LoadUsedWords();
string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
string word = wordArr.Except(attemptedWords).OrderBy(x => rn.Next()).FirstOrDefault();
if (string.IsNullOrEmpty(word))
{
Console.WriteLine("Oh no");
}
else
{
Console.WriteLine(word);
}
}
public string[] LoadUsedWords()
{
return new string[] { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL" };
}
既然你已经说过你是编程新手,我将很快解释一下要点: .Except将您的数组与其他数组进行比较,并仅返回唯一的元素。 .OrderByx=>rn.Next将以随机顺序返回数组。 .FirstOrDefault将从数组中获取第一个条目,如果数组为空,则返回null
public void GenerateWord()
{
Random rn = new Random();
string[] attemptedWords = LoadUsedWords();
string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
string word = wordArr.Except(attemptedWords).OrderBy(x => rn.Next()).FirstOrDefault();
if (string.IsNullOrEmpty(word))
{
Console.WriteLine("Oh no");
}
else
{
Console.WriteLine(word);
}
}
public string[] LoadUsedWords()
{
return new string[] { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL" };
}
你应该把你的单词列成一个列表。它更容易满足您的需要
以下是一种随机化列表的简单方法:
List<string> wordArr = new List<string>()
{
"PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO"
};
Random random = new Random();
wordArr = wordArr.OrderBy(x => random.Next()).ToList();
当wordArr为空时,您就完成了。您应该将wordArr表示为一个列表。它更容易满足您的需要
以下是一种随机化列表的简单方法:
List<string> wordArr = new List<string>()
{
"PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO"
};
Random random = new Random();
wordArr = wordArr.OrderBy(x => random.Next()).ToList();
当单词arr为空时,您就完成了。方法中的差异可能会导致难以理解的重复,但不要在方法中声明随机类。只需在整个代码中使用一个实例。Pierre-Luc,他要求的是相同的方法,但Int不是string。L.B.对不起,代码太乱了。。。Wil移动随机类:我已经编辑了你的标题。请看,如果共识是否定的,他们就不应该这样。好的,谢谢,我会记住的!:方法中的差异很难理解,但不要在方法中声明随机类。只需在整个代码中使用一个实例。Pierre-Luc,他要求的是相同的方法,但Int不是string。L.B.对不起,代码太乱了。。。Wil移动随机类:我已经编辑了你的标题。请看,如果共识是否定的,他们就不应该这样。好的,谢谢,我会记住的!:在第二个方法中,已选择的字符串将被删除:names.removateIndex;。但是,当我多次运行此方法时,仍然会得到重复的结果…在第二个方法中,已选择的字符串将被删除,并带有:names.removatendex;。但是,当我多次运行此程序时,仍然会得到重复项…Random.Next具有奇怪的语义。第二个参数高于所需的上限。因此,您的调用应该是Rnd.Next0,Words.Length,不带“-1”。此外,此代码如何跟踪已使用的单词?不保留已使用的单词,从集合中删除已使用的单词,如果您需要了解已使用的单词,则wordArr.ExceptWords就足够了。我不需要跟踪何时已使用的单词
所有用过的词都被删除了。我可以通过一个简单的Int计数器记录我使用了多少次尝试:@TolgahanAlbayrak-我的道歉-我错过了代码中的删除。我想我需要多睡一会儿-Next有奇怪的语义。第二个参数高于所需的上限。因此,您的调用应该是Rnd.Next0,Words.Length,不带“-1”。此外,此代码如何跟踪已使用的单词?不保留已使用的单词,从集合中删除已使用的单词,如果你需要知道用过的词,那么wordArr.ExceptWords就足够了。当所有用过的词都被删除时,我不需要记录我已经用过的词。我可以通过一个简单的Int计数器记录我使用了多少次尝试:@TolgahanAlbayrak-我的道歉-我错过了代码中的删除。我想我需要多睡一会儿。。。阿卡?是的,同样的事情P我只使用列表,因为他已经在用它了。。。。阿卡?是的,同样的事情P我只使用列表,因为他已经在用它了。