一种选择特定随机名称的方法

发布于 2024-11-15 14:05:06 字数 485 浏览 3 评论 0原文

我正在开发一个 Windows 应用程序。该应用程序包含一个动态名称列表,这些名称显示在表单中(用户可以添加或删除某个名称)。 我想要做的是,对于数据库中的每个名称,都有列表中的另一个随机名称。唯一的条件是每个名称应分配不同的名称,并且所有名称只能使用一次。

我尝试做的是使用列表来包含数据库中的名称,并从列表中选择一个随机索引,并将其与数据库中的相应位置进行比较。如果不同,则从该索引处删除,依此类推,直到没有更多名称可放置。

但后来我意识到这不是一个完美的方法。 假设我有 5 个名字,

名字 1 随机得到名字 3 名字 2 随机得到名字 1 名字 3 随机得到名字 4 名字 4 随机得到名字 2 和... name 5 只能获取 name 5,所以在这种情况下它不起作用。

有人知道我如何让它发挥作用吗?我还应该使用什么其他方法? 名字的数量大约是20个。稍后我必须为每个名字分配2个不同的名字。 但首先我需要解决这个问题。

任何帮助将不胜感激! 我正在用 C# 编写

I'm working on an windows app. This app contains a dynamic list of names, that are displayed in the form (user can add or delete a certain name).
What I want to do is for each name in db have another random name from the list. The only condition is that for each name should be asssigned different name and all the names must be used only once.

What I've tried to do is using a List to contain names from db and pick a random index from the List and compare it with the corresponding place in db. If it's different then remove at that index, and so on until no more names to place.

But after that I realised it's not a perfect way to do it.
Let's say, I've got 5 names,

name 1 randomly gets name 3
name 2 randomly gets name 1
name 3 randomly gets name 4
name 4 randomly gets name 2
and...
name 5 can only get name 5, so in this case it doesn't work.

Anyone has any idea how I could make it work? What other method should I use?
Number of names is about 20. Later on I will have to assign 2 different names for each name.
But at first I need to solve this problem.

Any help will be appreciated!
I'm writing in C#

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柳若烟 2024-11-22 14:05:06

Jan 比我先一步,但这是我正在做的代码,用于解释如果未选择的名称匹配,您只需要切换最后两个即可。

    static void Main(string[] args)
    {
        List<string> names = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };
        List<string> otherNames = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };

        Random r = new Random();

        for (int i = 4; i >= 0; i--)
        {
            int pick1 = r.Next(i);
            int pick2 = r.Next(i);
            while (names[pick1] == otherNames[pick2])
            {
                pick2++;
                if (pick2 >= otherNames.Count) pick2 = 0;
            }
            if (names.Count == 2)
            {
                // when you only have 2 names left, if the other names match...
                if (names[1 - pick1] == otherNames[1 - pick2])
                {
                    // swap one of the picked names
                    pick2 = 1 - pick2;
                }
            }
            Console.Write(names[pick1]); Console.Write(" != "); Console.WriteLine(otherNames[pick2]);
            names.RemoveAt(pick1);
            otherNames.RemoveAt(pick2);
        }
        Console.ReadKey();
    }

Jan beat me to it, but here's the code I was doing to explain how you just need to switch the two last if the non-selected names match.

    static void Main(string[] args)
    {
        List<string> names = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };
        List<string> otherNames = new List<string>() { "Jeff", "John", "Joe", "Jack", "Jim" };

        Random r = new Random();

        for (int i = 4; i >= 0; i--)
        {
            int pick1 = r.Next(i);
            int pick2 = r.Next(i);
            while (names[pick1] == otherNames[pick2])
            {
                pick2++;
                if (pick2 >= otherNames.Count) pick2 = 0;
            }
            if (names.Count == 2)
            {
                // when you only have 2 names left, if the other names match...
                if (names[1 - pick1] == otherNames[1 - pick2])
                {
                    // swap one of the picked names
                    pick2 = 1 - pick2;
                }
            }
            Console.Write(names[pick1]); Console.Write(" != "); Console.WriteLine(otherNames[pick2]);
            names.RemoveAt(pick1);
            otherNames.RemoveAt(pick2);
        }
        Console.ReadKey();
    }
你的背包 2024-11-22 14:05:06

使用您建议的方法,并在遇到您描述的问题时交换最后两个元素。

Use the method you propose and Just swap the last two elements when you encounter the problem you described.

给妤﹃绝世温柔 2024-11-22 14:05:06
while (position == 0) {
   position = randInt() % nameCount;
}

for (int i=0;i<nameCount;i++) {
   addPair(i,position);
   position++;
   if (position>=nameCount) position=0;
}

db 中的名称逻辑编号为 0 到 nameCount-1;
这个想法是,您为第二个名称选择随机位置,然后递增它并在最后滚动。

这是伪代码。我不懂 C#。

好问题!

while (position == 0) {
   position = randInt() % nameCount;
}

for (int i=0;i<nameCount;i++) {
   addPair(i,position);
   position++;
   if (position>=nameCount) position=0;
}

Names in db are logically numbered from 0 to nameCount-1;
The idea is that you choose random position for the second name and then increment it and roll over at the end.

This is pseudocode. I don't know C#.

Great question!

一城柳絮吹成雪 2024-11-22 14:05:06

您可能想查看这个类似的问题ruby 测验 2 获取想法。

一种基本方法可能是复制列表,打乱副本并将两者对齐。但这最终可能会导致与您遇到的相同问题。但是,然后浏览一下列表,您可以与每个自引用列表进行交换。

You might want to look at this similar problem or the answers to ruby quiz 2 for ideas.

A basic approach might be to copy the list, shuffle the copy and line the two up. But that can end up with the same issue you have. But then look through the list you can swap with each self-referencing one.

听,心雨的声音 2024-11-22 14:05:06

我认为洗牌一个 List会更简单。名称,创建一个副本,将副本向下移动一个项目(使最后一个项目成为第一个)并按位置匹配名称。您确保一次传递中没有重复项。

I think it would just be simpler to shuffle one List<string> names, create a copy, shift the copy one item down (make last item become first) and match names by position. You ensure no duplicates in one pass.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文