对不起,如果这是一个愚蠢的菜鸟问题。我正在为我的女朋友做一个非常小的项目 - 一个国家名单,她必须进入他们的首都(晦涩的国家,请注意)。由于我是一个初学者,我不得不求助于使用两个数组,一个用于国家,另一个用于大写,具有匹配的索引。这样很容易检查正确的答案,我不必解析任何文本文件或使用任何数据库。我使用随机数字来使它更有趣。为了阻止程序一遍又一遍地生成相同的国家,我使用了一个整数列表来跟踪已经使用了哪些索引,如果列表包含前一个索引,则重新生成该数字。很基本的东西。令人惊讶的是,这一切都有效。
但我遇到了问题。我如何检查我的国家已经用完了? :)我不能简单地检查我的国家/地区数组的列表大小,因为List可能包含比数组更多的值,并且if(taken.Equals(Countries.Length))似乎不起作用。或者我在代码中找不到合适的位置来进行此检查。
很抱歉,如果这很简单,但我似乎找不到合适的解决方案。
修改 哇,多么棒的社区。在从星巴克到我的地方的短暂步行中,我得到了许多质量答案,涵盖了大量的设计技巧。这真是太棒了!谢谢大家!显然,问题已得到解答,但如果有人有任何其他意见,我会为你发布代码。
//现在只需13个国家进行测试
string[] Countries = {"Belgium", "France", "The Netherlands", "Spain", "Monaco", "Belarus", "Germany",
"Portugal", "Ukraine", "Russia", "Sweden", "Denmark", "South Africa"};
string[] Capitals = {"Brussels", "Paris", "Amsterdam", "Madrid", "Monaco", "Minsk", "Berlin",
"Lisbon", "Kiev", "Moscow", "Stockholm", "Copenhagen", "Pretoria"};
Random number = new Random();
List<int> taken = new List<int>();
int index;
int score = 0;
private int Generate()
{
while (true) {
index = number.Next(0, Countries.Length);
if (taken.Contains(index)) continue;
// THIS IS WHAT I WAS INITIALLY TRYING TO DO
if (taken.Equals(Countries.Length)) {
MessageBox.Show("Game over!");
return -1;
}
return index;
}
}
private void Form1_Load(object sender, EventArgs e)
{
index = Generate();
taken.Add(index);
label1.Text = Countries[index];
label3.Text = "0 out of " + Countries.Length.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text.Trim() == Capitals[index].ToString()) {
label2.Text = "You win!";
index = Generate();
taken.Add(index);
label1.Text = Countries[index];
textBox1.Clear();
label3.Text = ++score + " out of " + Countries.Length.ToString();
}
else {
label2.Text = "Wrong!";
textBox1.Clear();
}
}
}
}
答案 0 :(得分:5)
要阻止程序一遍又一遍地生成相同的国家/地区,我正在使用一个整数列表来跟踪已经使用了哪些索引,如果列表包含前一个索引,则重新生成该数字。
...
我如何检查我的国家已经用完了?
您可能想要考虑另一种方法,因为这将非常昂贵且过于复杂。
不是试图随机添加一个国家/地区,而是检查您已添加的国家/地区,而只需制作整个国家/地区列表,然后perform a shuffle(“随机排序”)即可。这样,您将以随机顺序一次性获得所有国家/地区。
答案 1 :(得分:4)
我们不再使用两个数组,一个数组和一个列表,而是介绍一些实际上看起来很容易使用的C#4.0,并且似乎是针对这种类型的赋值。
用眼睛遵循此代码,具体了解这些“匿名类型”最终是如何使用的。它让生活变得轻松。
// initialize your array like so,
// now you can access your items as countries[1].name and countries[1].city
// and you will never have to worry about having too much cities or countries
// PLUS: they're always together!
var countries = new [] {
new { name = "The Netherlands", city = "Amsterdam"},
new { name = "Andorra", city = "Vaduz" },
new { name = "Madagascar", city = "Antananarivo"}
};
// randomize by shuffling (see http://stackoverflow.com/questions/375351/most-efficient-way-to-randomly-sort-shuffle-a-list-of-integers-in-c-sharp/375446#375446)
Random random = new Random();
for (int i = 0; i < countries.Length; i += 1)
{
int swapIndex = random.Next(i, countries.Length);
if (swapIndex != i)
{
var temp = countries[i];
countries[i] = countries[swapIndex];
countries[swapIndex] = temp;
}
}
// go through all your items in the array using foreach
// so you don't have to worry about having too much items
foreach(var item in countries)
{
// show your girlfriend the country, something like
string inputString = DisplayCountry(item.country);
if(inputString == item.city)
{
ShowMessage("we are happy, you guessed right!");
}
}
// at the end of the foreach-loop you've automatically run out of countries
DisplayScore(to-your-girlfriend);
注意:您可以通过添加该特定国家/城市对是否被正确猜测来轻松扩展此匿名类型,并对其失败的那些进行后续测试。
答案 2 :(得分:1)
您可以使用HashSet<int>
来跟踪已使用的索引。这不接受重复值。 Add
方法返回一个布尔值,指示该值是否已在列表中:
if (hashSet.Add(index))
DisplayValue(index);
else
//regenerate
但我可能会使用你现有的策略,但是后退:创建一个预先填充从0到Count的值的列表 - 1.从此列表中选择索引,在使用它们时将其删除。这在逻辑上类似于Reed Copsey的排序建议,但可能需要对现有代码进行较少的更改。
var availableIndexes = new List<int>(Enumerable.Range(0, countryCount));
var random = new Random();
while (availableIndexes.Count > 0)
{
var index = availableIndexes[Random.Next(0, availableIndexes.Count)];
DisplayValue(index);
availableIndexes.Remove(index);
}
答案 3 :(得分:1)
创建Country类和Capital类。
然后对类进行建模以使用Dictionary<TKey, TValue>
通用集合,以便将通用Dictionary对象声明为:
Dictionary<Country, Capital>
其中国家是关键,资本是其价值。
对于MSDN对Dictionary及其示例用法的引用,您可以按照以下链接进行操作:
http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
当你继续使用国家和大写字母时,在检查它们是否存在于Dictionary实例中之后,将它们添加到Dictionary实例之上,如果它们中的任何一个存在,则弹出信息消息或警告。
答案 4 :(得分:1)
您可以使用键/值对,例如Dictionary<string, string>
来存储您的国家/地区和首都。然后使用随机LINQ orderby子句迭代集合:
Dictionary<string, string> Countries = new Dictionary<int, string>();
// populate your collection of countries
foreach(var country in Countries.OrderBy(c => Guid.NewGuid()))
{
Console.WriteLine("Key: {0} Value: {1}", country.Key, country.Value);
}
答案 5 :(得分:1)
快速而肮脏,不一定高效或安全。
Dictionary<string, string> countriesAndCapitals = new Dictionary<string, string>()
{
{ "Afghanistan", "Kabul" },
{ "Albania", "Tirane" },
{ "Algeria","Algers" },
{ "Andorra", "Andorra la Vella" } //etc, etc
};
foreach (var countryCapital in countriesAndCapitals.OrderBy(f => Guid.NewGuid()))
{
Console.WriteLine(countryCapital.Key + " " + countryCapital.Value);
}
答案 6 :(得分:1)
看起来你需要的是一种不同类型的数据结构,两组列表可以正常工作,但它没有任何复杂性。我建议查看词典列表类型。
Dictionary<string,string> countryList = new Dictionary<string,string>();
countryList.Add("Canada","Ottawa");
countryList.Add("Thailand","Bankok");
等...
然后,您可以遍历列表,同时布尔值可以查看是否存在匹配。有关Dictionary list type的更多信息。
答案 7 :(得分:0)
为什么不从列表中删除您使用的项目?那你没有冲突。然后你检查states.Count()&gt; 0
答案 8 :(得分:0)
我能想到的最快的事情就是在列表中使用Distinct()调用。然后,可以将列表中的项目计数与数组的计数进行比较,以查看是否已使用所有项目。
if(myUsedList.Distinct().Count() < myArray.Count) { ... }