c# - 从数组列表 C# 检查颜色是否已被使用
问题描述
您好,我想检查我的数组中的某种颜色是否已被使用,那么它将不会再次使用。我正在使用数组中的随机颜色,所以有时它会得到相同的颜色。
// Add random block color
Color[] colors = new Color[] { Color.Red, Color.Blue, Color.Green, Color.Purple, Color.Black, Color.Aqua };
Random ra = new Random();
int rnum = ra.Next(0, 5);
p.block.brush_color = new SolidBrush(Color.FromArgb(100, colors[rnum]));
// Add new generated process to list
processes.Add(p);
我怎样才能做到这一点?
解决方案
处理此问题的一种方法是打乱数组中的项目,然后按顺序选择项目。Fisher-Yates shuffle通常被认为是最好的算法:
private static Color[] colors =
{
Color.Red, Color.Blue, Color.Green, Color.Purple, Color.Black, Color.Aqua
};
private static Random random = new Random();
private static void ShuffleColors()
{
for (int index = 0; index < colors.Length; index++)
{
var randomIndex = index + random.Next(colors.Length - index);
var temp = colors[randomIndex];
colors[randomIndex] = colors[index];
colors[index] = temp;
}
}
但是当你到达数组的末尾时会发生什么?似乎有3种可能:
- 重新从头开始(但你会有一个非随机模式)
- 打乱数组并重新从头开始
- 随机排列数组,但确保最后使用的颜色不是第一项
我认为最后一个可能更可取,因为它会给出最随机的输出,所以让我们实现那个。
我们可以做的是跟踪我们显示的最后一个索引,然后当它表示数组中的最后一项时,我们可以再次对数组进行洗牌。然后,在我们继续之前,我们要检查以确保数组中的第一项不是我们显示的最后一项。如果是,那么我们将它与其他一些随机元素交换,因此我们永远不会有重复项。
private static int nextIndex = 0;
private static SolidBrush GetNextColoredBrush()
{
// If we've displayed all the items, shuffle the deck
if (nextIndex == colors.Length)
{
var lastColorUsed = colors[nextIndex - 1];
ShuffleColors();
// If the first color is the same as the last color
// we displayed, swap it with a random color
if (colors[0].Name == lastColorUsed.Name)
{
var rndIndex = random.Next(1, colors.Length);
colors[0] = colors[rndIndex];
colors[rndIndex] = lastColorUsed;
}
// Reset our index tracker
nextIndex = 0;
}
// Return the next color and increment our index
return new SolidBrush(colors[nextIndex++]);
}
现在我们可以在循环中调用这个方法来看看输出会是什么样子:
private static void Main()
{
// Output our random colors. Note that even though we
// only we only have 6 colors, they are consistently
// output in a random order (but with no duplicates).
for (int i = 0; i < 20; i++)
{
Console.WriteLine(GetNextColoredBrush().Color.ToKnownColor());
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
输出
请注意,在显示 6 之前没有重复元素,然后接下来的 6 个元素以不同的顺序排列:
在您的代码中使用
哦,最后,要在您的代码中使用它,您只需执行以下操作:
p.block.brush_color = GetNextColoredBrush();
但是,您可能会注意到我稍微更改了输出,以便输出KnownColor
. 如果要维护原始代码,则应修改GetNextColoredBrush
方法中返回值的行:
return new SolidBrush(Color.FromArgb(100, colors[nextIndex++]));
推荐阅读
- spring-boot - 春季启动:@Valid 不适用于 @RequestHeader
- python - 当 Debug 为 False 时,Django 国际化仅在 500.html 存在时给出内部错误
- android - 如何修复属性android:水平滚动视图中的拇指宽度
- python - 使用 keras 的多分类任务
- python - 在python中使用正则表达式在冒号或括号后提取字符串
- angular - Angular :: 环境文件获取属性错误
- python - scrapy 返回一个空对象
- asp.net - 有什么方法可以在 asp net webforms 上全局处理 Ajax 错误?
- c++ - 这行代码在 C++ 类中是什么意思?
- ruby-on-rails - 使用 Webdriver 和 Ruby 的 UI 测试自动化;无法初始化 chrome 浏览器会话