【问题标题】:generating a specefied number of random but unique colors生成指定数量的随机但唯一的颜色
【发布时间】:2011-07-18 17:23:02
【问题描述】:

我想要做的是让我的 listView 中的每个项目都具有唯一的颜色。所以我所拥有的是列表视图中的项目数为“计数”

我的方法是调用下面的方法并给出我的项目的方法编号,然后它应该有一个保存第一种颜色的数组,然后当要生成下一种颜色时,它应该与之前的颜色进行比较在数组中。

问题是我无法弄清楚我需要什么样的数组以及如何将数组中每个插入的颜色与最后插入的颜色进行比较。这是我的代码:

public Color GetUniqueRandomColor(int count){

for(int i = 0; i < count; i++)
{
Color.FromArgb(randomColor.Next(70, 200), randomColor.Next(100, 225), randomColor.Next(100, 230));
}

return Color.Red;}

这是一个元素在数组中的外观:

颜色 [A=255, R=132, G=148, B=181]

如您所见,我的方法仍然缺少所需的数组和算法来比较新插入的颜色。我们将提供一些帮助和提示!

【问题讨论】:

  • 作为旁注...您正在生成可能非常相似的颜色。如果可以,请尝试区分 132、148、181 和 132、148、180! :-) 从技术上讲,它们是不同的。
  • 如果用户无论如何都看不到差异,那么唯一性有什么用?
  • 接受的答案解决了您所说的问题,是的。但我认为您的使用无法将其与不强制唯一性的幼稚算法区分开来。

标签: c# arrays random colors unique


【解决方案1】:

使用 C# 3.5

public static Color[] GetUniqueRandomColor(int count)
{
    Color[] colors = new Color[count];
    HashSet<Color> hs = new HashSet<Color>();

    Random randomColor = new Random();

    for(int i = 0; i < count; i++)
    {
        Color color;
        while (!hs.Add(color = Color.FromArgb(randomColor.Next(70, 200), randomColor.Next(100, 225), randomColor.Next(100, 230))));
        colors[i] = color;
    }    

    return colors;
}

如果你只有 C# 2.0,你可以用 Dictionary 代替 HashSet,其中 bool 只是你不会使用的占位符,但是 while 表达式会变得更复杂一些

public static Color[] GetUniqueRandomColor(int count)
{
    Color[] colors = new Color[count];
    Dictionary<Color, bool> hs = new Dictionary<Color, bool>();

    Random randomColor = new Random();

    for (int i = 0; i < count; i++)
    {
        Color color;
        while (hs.ContainsKey(color = Color.FromArgb(randomColor.Next(70, 200), randomColor.Next(100, 225), randomColor.Next(100, 230)))) ;
        hs.Add(color, true);
        colors[i] = color;
    }

    return colors;
}

【讨论】:

  • 一段没有身体的时光。丑陋的。 IMO 您应该将分配分配给colorwhile 条件。如果您使用没有正文的while,至少在新行中添加{} 以使其明显。
  • 当您接近2 112 500 项目时,该算法会变得更慢,并且一旦不再满足唯一性条件,最终将陷入无限循环。
  • +1 对他们俩...而且我知道...但是当您必须与 SO 的文本编辑器作斗争时,换行中的 {} 是一种痛苦:-) 而且第二点......他的(OP)是规则,他是痛苦的。真正的问题是它可以产生几乎相同的颜色。我永远不会为我做与此代码类似的事情。 :-) 我会根据颜色之间距离最小的 HSL 空间做一些事情(从技术上讲,我已经做过一次)
  • 顺便说一句,HashSet&lt;T&gt; 自 .net 3.5 以来就存在。
  • @CodeInChaos 你显然是对的......而且这很有趣,考虑到我两个月前开始使用 C# 4.0 并且去年使用了 HashSet :-)
【解决方案2】:

我将填充“已用颜色”列表,因此每次在调用 Color.FromArgb 之前生成新颜色时,您都可以在列表中检查它。如果颜色存在,您将再次调用随机函数,否则您将生成颜色并将值添加到列表中。

【讨论】:

  • 谢谢,但是如何将颜色存储在列表中?
  • 你可以创建一个简单的 POCO 类的颜色。类似于: public class MyColor { int Red {get;set;} int Green {get;set;} int Blue {get;set;}} 然后在您的函数 IList 中创建,然后使用 Add、Delete 或 Linq 语句做你的比较。或者你直接使用.NET框架的Color类(IList
猜你喜欢
  • 2014-10-08
  • 2015-01-12
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
相关资源
最近更新 更多