首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FOR cycle效果很差

FOR cycle效果很差
EN

Stack Overflow用户
提问于 2013-05-10 23:07:13
回答 6查看 202关注 0票数 0

这就是我的问题:我正在开发一个玩家分组(它将玩家分成组)。我是通过一个for循环来做的,但是它没有划分所有的玩家:(.

代码如下:

代码语言:javascript
复制
namespace Grouper
{
public partial class Form1 : Form
{
    List<string> players=new List<string>(); 

    public Form1()
    {
        InitializeComponent();
        LoadPlayers();
    }

    private void But_rnd_Click(object sender, EventArgs e)
    {
        LoadPlayers();
        bool isOdd = players.Count % 2 == 1;
        List<string> results=new List<string>();
        if(!isOdd) // Count of players is even
        {
            Grouping(ref results);
        }
        if(isOdd) // Count of players is odd
        {
            Grouping(ref results);
            results.Add("Remained: " + players[0]);
            ShowResults(ref results);
        }
    }

    private void Grouping(ref List<string> results)
    {
        Random r=new Random();
        for (int i = 0; i < players.Count() / 2 + 1; i++)
        {
            int randomPlr = r.Next(players.Count() / 2 + 1, players.Count());
            results.Add(i + 1 + ".: " + players[i] + " + " + players[randomPlr]);
            players.RemoveAt(i);
            players.RemoveAt(randomPlr - 1);
        }
    }

    private void ShowResults(ref List<string> results)
    {
        string write = "";
        foreach (string result in results)
        {
            write += result + "\n";
        }
        MessageBox.Show(write);
    }

    private void LoadPlayers()
    {
        players.Clear();
        players.Add("p1");
        players.Add("p2");
        players.Add("p3");
        players.Add("p4");
        players.Add("p5");
        players.Add("p6");
        players.Add("p7");
    }
}
}

方法ShowResults()只显示了2个组和1个玩家,剩下的是谁(2个组和1个剩余=5个玩家,但我有7个玩家!)。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-05-10 23:28:53

您的代码中有几个问题。

if语句使用

这真的很奇怪

代码语言:javascript
复制
bool isOdd = players.Count % 2 == 1;
…
if(!isOdd)
{
    …
}
if(isOdd) // Count of players is odd
{
    …
}

使用if / else,您的代码将更具可读性:

代码语言:javascript
复制
if (players.Count % 2 == 0)
{
    …
}
else
{
    …
}

此外,您可以完全省略此检查,进行分组,然后弄清楚如何处理其余部分(谁说每次最多只能保留一个?如果您将来需要将它们划分为三个组,该怎么办?):

代码语言:javascript
复制
Grouping(…);
if (players.Count > 0)
{
    … process remaining players …
}

for循环中的迭代次数

正如其他人所指出的,你在这里“重复”了:

代码语言:javascript
复制
for (int i = 0; i < players.Count() / 2 + 1; i++)

这将总是比你想要的多进行两次迭代。您应该将其更改为:

代码语言:javascript
复制
for (int i = 1; i < players.Count() / 2; i++)

这样,它将适用于偶数或奇数计数,也适用于角球情况(仅限0或1玩家)。或者,假设您每次迭代都将两个玩家从列表中删除,只需使用:

代码语言:javascript
复制
while (Players.count() > 1)

索引访问和随机访问的组合是错误的

在下面的代码中,你不能确定a) i-th元素存在,b)随机索引不匹配i,这将有效地将相同的玩家放入两组中:

代码语言:javascript
复制
int randomPlr = r.Next(players.Count() / 2 + 1, players.Count());
results.Add(i + 1 + ".: " + players[i] + " + " + players[randomPlr]);
players.RemoveAt(i);
players.RemoveAt(randomPlr - 1);

要么取一半,然后取另一半,因为它们在players列表中(在这种情况下,您根本不需要做任何fors ),或者每次随机选择一个球员。例如,如下所示:

代码语言:javascript
复制
public string PickRandomPlayer(List<string> players)
{
    int random = … generate random index …;
    string player = players[random];
    players.RemoveAt(random);
    return player;
}

然后在for look中调用此方法两次,为每个半场挑选一个球员。

ref参数使用无效

以下声明包含不必要和不需要的ref

代码语言:javascript
复制
private void Grouping(ref List<string> results)

简单地说: Object,就像List<string>一样,默认情况下是通过引用传递的。这意味着,当您在代码中访问results参数并对其进行修改(添加/删除项)时,受影响的实例是调用者提供的实例:

代码语言:javascript
复制
void Grouping(List<string> results) { … }

…

List<string> results = new … ;
…
Grouping(results);
…
… here results contains what Grouping put in

另一方面,当您指定ref时,可以将List<string>的新实例传递到该方法的外部

代码语言:javascript
复制
void Grouping(List<string> results)
{
    results = new … ; // this instance will be returned out of the method!
}

…

List<string> results = new … ;
…
Grouping(ref results); // here, whatever is in results currently, is lost
…

goto的使用

这就是可怕的。查看此SO question及其接受的答案。此外,谷歌的“GOTO声明被认为是有害的”,以进一步阅读这一话题。

票数 4
EN

Stack Overflow用户

发布于 2013-05-10 23:21:13

对于循环,您的条件是i < players.Count() / 2 + 1。也就是说,由于您在循环的每次迭代中删除了2个玩家,因此您更改了条件的值。

假设你从7个玩家开始。

条件迭代1:i= 0,条件= 4,共2人处理,5人remaining

  • Iteration 2:i= 1,条件= 3,4人共处理,3人remaining

  • Iteration 3:i= 2,条件= 2,条件不满足

最后,您有2个组和3个剩余的玩家,但是由于您执行了"Remained: " + players[0],您只显示了剩余的玩家中的1个。

票数 2
EN

Stack Overflow用户

发布于 2013-05-10 23:25:15

这不是很好,但应该可以工作(只需输入,因此调整语法):

代码语言:javascript
复制
   private void But_rnd_Click(object sender, EventArgs e)
    {
        LoadPlayers();
        List<string> results=new List<string>();
        Grouping(ref results);
        ShowResults(ref results);
    }

    private void Grouping(ref List<string> results)
    {
        Random r=new Random();
        while (Players.count() > 1)
        {
           int p1 = r.next(players.count());
           String p1s = players.get(p1);
           players.removeat(p1);
           int p2 = r.next(players.count());
           String p2s = players.get(p2);
           players.removeat(p2);

           results.add(//whatever string you use to combine p1 + p2);
        }
        if (players.count() > 0)
        {
            // add remaining players
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16485356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档