试试下面的代码。我使用 Linq 将字符串组合在一起以获取所有重复项。然后我创建一个随机的唯一字符串列表。然后将剩余的重复项添加到列表中,使字符串均匀分布。结果是完全随机且均匀分布的。
注意:我发现了一个小错误。下面换行
from : firstItem += spacing;
to : firstItem += spacing + 1;
在调试代码时,我发现 firstItem 偶尔会变为负数,因此我添加了代码以确保 firstItem 始终为正数。然后我开始思考为什么我没有在 firstItem 大于数组大小的情况下出现任何溢出。那时我意识到我必须在间距上加 1。带有数组 A,B,C,D,E 的旧代码将给出 1,1,1,1,1,A,B,C,D,E。新代码将给出 1,A,1,B,1,C,1,D,1,E。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication20
{
class Program
{
static void Main(string[] args)
{
Random rand = new Random();
List<string> input = new List<string>();
List<string> output = new List<string>();
//create 150 random strings with duplicates
for(int i = 0; i < 150; i++)
{
input.Add(rand.Next(0,25).ToString());
}
//create dictionary with two columns key, number of entries
Dictionary<string, Value> dict = input.AsEnumerable()
.GroupBy(x => x)
.ToDictionary(x => x.Key, y => new Value { count = y.Count(), ranNumber = rand.Next() });
dict = dict.OrderBy(x => x.Value.ranNumber).ToDictionary(x => x.Key, y => y.Value);
//add 1 sorted numbers to output
foreach(string key in dict.Keys)
{
output.Add(key);
}
//add rest of numbers
foreach (string key in dict.Keys)
{
int numberOfItems = dict[key].count;
if (dict[key].count > 1)
{
int arraySize = output.Count;
int spacing = arraySize / numberOfItems;
int firstItem = 0;
//center around middle
if (numberOfItems % 2 == 0)
{
firstItem = (arraySize / 2) - (((numberOfItems / 2) * spacing) + (spacing / 2));
}
else
{
firstItem = (arraySize / 2) - (((numberOfItems - 1) / 2) * spacing);
}
if (firstItem < 0)
{
firstItem = 0;
}
//remove existing item
output.Remove(key);
//insert items
for (int i = 0; i < numberOfItems; i++)
{
output.Insert(firstItem,key);
firstItem += spacing;
}
}
}
}
public class Value
{
public int count { get; set; }
public int ranNumber { get; set; }
}
}
}