使用while循环和字典解决重复的问题

时间:2018-10-22 01:52:41

标签: c# dictionary input while-loop duplicates

我有一个项目列表,该列表由玩家在几个输入字段中输入的内容确定,但是出于这个示例的原因,我们假设它包含“ a”,“ b”,“ c”,“ d”和“ e”。然后将它们分类到字典中,并以数字列表作为值(不重要)。然后,我使用两个不同的随机变量(i和j)对字典进行随机化,以便从字典中获取两个对象并将它们显示在屏幕上,以便玩家可以按下各种关联的按钮。一直持续到转过x圈。 主要问题,我遇到的问题是防止半重复出现,例如“ a b”和“ b a”。

我尝试将随机对及其半重复插入到另一个字典中,然后使用while循环语句来防止该字典中的任何对出现。不幸的是,这没有用。

下面是我的代码。

public void Start() {
    finalList = new Dictionary<string, int>();
    for (index = 0; index < allNumbers; index++)
    {
        finalList.Add(itemList[index], valueList[index]);
        Debug.Log(finalList[index.ToString()]);
    }
}
public void Update() {
    choose();
}

public void choose() {
    duplicates = new Dictionary<string, string>();
    duplicates.Clear();
    while (rounds < insertNum) {

        key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
        reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";

        while (j == i || (duplicates.ContainsKey(key) || duplicates.ContainsKey(reverseKey))) {
            i = UnityEngine.Random.Range(0, allNumbers - 1);
            j = UnityEngine.Random.Range(0, allNumbers - 1);
            key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
            reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
            Debug.Log("(new keys " + key + ", " + reverseKey + ")");
            //break;
            } while (j == i || (duplicates.ContainsKey(key) && duplicates.ContainsKey(reverseKey)))
            {
                i = UnityEngine.Random.Range(0, allNumbers - 1);
                j = UnityEngine.Random.Range(0, allNumbers - 1);
                key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
                reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
                Debug.Log("(new keys " + key + ", " + reverseKey + ")");
            }while (j == i && (duplicates.ContainsKey(key) || dupes.ContainsKey(reverseKey))) {
            i = UnityEngine.Random.Range(0, allNumbers - 1);
            j = UnityEngine.Random.Range(0, allNumbers - 1);
            key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
            reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
            Debug.Log("(new keys " + key + ", " + reverseKey + ")");

        }
        while (j == i && (duplicates.ContainsKey(key) && duplicates.ContainsKey(reverseKey))) {
            i = UnityEngine.Random.Range(0, allNumbers - 1);
            j = UnityEngine.Random.Range(0, allNumbers - 1);
            key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
            reverseKey = "(" + itemList[j].ToString() + " " + itemList[i].ToString() + ")";
            Debug.Log("(new keys " + key + ", " + reverseKey + ")");
        }
        duplicates.Add(key, "1"); // the one is just a filler variable
        duplicates.Add(reverseKey, "1");
        if (buttonOneBool) { //this is in another script, ignore
            finalList[itemList[i].ToString()] = valueList[i] += 2;
            finalList[itemList[j].ToString()] = valueList[j] -= 2;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        } else if (buttonTwoBool) {
            finalList[itemList[i].ToString()] = valueList[i] -= 2;
            finalList[itemList[j].ToString()] = valueList[j] += 2;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        } else if (buttonThreeBool) {
            finalList[itemList[i].ToString()] = valueList[i] -= 1;
            finalList[itemList[j].ToString()] = valueList[j] -= 1;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        } else if (buttonFourBool) {
            finalList[itemList[i].ToString()] = valueList[i] += 1;
            finalList[itemList[j].ToString()] = valueList[j] += 1;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        }
        break;
    } 

2 个答案:

答案 0 :(得分:0)

解决此问题的最简单方法是保证i < j。当选择一个新的i和j时:

i = UnityEngine.Random.Range(min, max); j = UnityEngine.Random.Range(min, max);

相反,这样做:

i = UnityEngine.Random.Range(min, max - 1); j = UnityEngine.Random.Range(i + 1, max);

这样做排除了选择前一种情况的“镜像”的可能性,并且避免了“ i == j”的情况。

进行这些修改后,您的choice()函数应如下所示:

    public void choose()
{
    duplicates = new HashSet<string>();
    while (rounds < insertNum)
    {
        key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
        while (duplicates.Contains(key))
        {
            i = UnityEngine.Random.Range(0, allNumbers - 2);
            j = UnityEngine.Random.Range(i + 1, allNumbers - 1);
            key = "(" + itemList[i].ToString() + " " + itemList[j].ToString() + ")";
        }
        duplicates.Add(key); // the one is just a filler variable

        if (buttonOneBool) { //bool definitions are in another script, ignore
            finalList[itemList[i].ToString()] = valueList[i] += 2;
            finalList[itemList[j].ToString()] = valueList[j] -= 2;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        } else if (buttonTwoBool) {
            finalList[itemList[i].ToString()] = valueList[i] -= 2;
            finalList[itemList[j].ToString()] = valueList[j] += 2;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        } else if (buttonThreeBool) {
            finalList[itemList[i].ToString()] = valueList[i] -= 1;
            finalList[itemList[j].ToString()] = valueList[j] -= 1;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        } else if (buttonFourBool) {
            finalList[itemList[i].ToString()] = valueList[i] += 1;
            finalList[itemList[j].ToString()] = valueList[j] += 1;
            i = UnityEngine.Random.Range(0, n - 1);
            j = UnityEngine.Random.Range(0, n - 1);
        }
        break;
    }
}

答案 1 :(得分:0)

您可以使用以下代码将两个随机索引添加到列表中。该代码使用整数作为列表类型,并且可以使用任何类型。

List<int> randomList = itemList.Select((x, i) => new { index = i, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.index).ToList();

然后,列表中的两个随机索引是randomList [0]和randomList [1]。该代码为列表的每个索引i分配一个随机数。要从列表中获得两个项目,请使用itemList [randomList [0]]和itemList [randomList [1]]。该代码假定原始列表ItemList []中至少有两个项目。

如果原始列表重复,则需要使用Distinct(),如下面的代码所示

        List<int> distinctList = itemList.Distinct().ToList();
        List<int> randomList = distinctList.Select((x, i) => new { index = i, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.index).ToList();