C# 一致地洗牌字符串列表
使用C#6,我有一个按字母顺序排列的姓名列表:C# 一致地洗牌字符串列表,c#,C#,使用C#6,我有一个按字母顺序排列的姓名列表: List<String> names = getAlphabeticallyOrderedNames(); List name=getAlphableCallyorderedNames(); 我需要洗牌的名字,但我想得到相同的结果,每次。因此,我不能使用: List<String> shuffledNames = names.OrderBy(x => Guid.NewGuid()); List shuffledN
List<String> names = getAlphabeticallyOrderedNames();
List name=getAlphableCallyorderedNames();
我需要洗牌的名字,但我想得到相同的结果,每次。因此,我不能使用:
List<String> shuffledNames = names.OrderBy(x => Guid.NewGuid());
List shuffledNames=names.OrderBy(x=>Guid.NewGuid());
然后我尝试了一些类似的方法:
List<String> shuffledNames = names.OrderBy(x => "d2fda3b5-4089-43f9-ba02-f68d138dee49");
List shuffledNames=names.OrderBy(x=>“d2fda3b5-4089-439-ba02-F68D13849”);
或
List shuffledNames=names.OrderBy(x=>Int32.MaxValue);
但是名字并没有被洗牌
如何解决此问题?尝试按哈希值排序
var shuffled = names.OrderBy(n=>n.GetHashCode());
尝试按哈希值排序
var shuffled = names.OrderBy(n=>n.GetHashCode());
您可以使用标准的洗牌算法,例如: 经过适当修改以添加种子参数,它将如下所示:
public static void Shuffle<T>(IList<T> list, int seed)
{
var rng = new Random(seed);
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
publicstaticvoidshuffle(IList列表,int种子)
{
var rng=新随机(种子);
int n=list.Count;
而(n>1)
{
n--;
int k=下一个(n+1);
T值=列表[k];
列表[k]=列表[n];
列表[n]=值;
}
}
然后,要以可重复的方式进行洗牌,只需为每次重复洗牌指定相同的种子:
List<String> names = getAlphabeticallyOrderedNames();
int seed = 12345;
Shuffle(names, seed);
List name=getAlphableCallyorderedNames();
int seed=12345;
洗牌(名字、种子);
您可以使用标准的洗牌算法,例如:
经过适当修改以添加种子参数,它将如下所示:
public static void Shuffle<T>(IList<T> list, int seed)
{
var rng = new Random(seed);
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
publicstaticvoidshuffle(IList列表,int种子)
{
var rng=新随机(种子);
int n=list.Count;
而(n>1)
{
n--;
int k=下一个(n+1);
T值=列表[k];
列表[k]=列表[n];
列表[n]=值;
}
}
然后,要以可重复的方式进行洗牌,只需为每次重复洗牌指定相同的种子:
List<String> names = getAlphabeticallyOrderedNames();
int seed = 12345;
Shuffle(names, seed);
List name=getAlphableCallyorderedNames();
int seed=12345;
洗牌(名字、种子);
一个可枚举扩展,使用Yield并将Seed值作为参数():
公共静态IEnumerable Shuffle(此IEnumerable源,Int32?seed=null){
列表缓冲区=source.ToList();
随机随机=seed.HasValue?新随机(seed.Value):新随机();
Int32计数=缓冲区计数;
对于(int32i=0;i
一个可枚举扩展,使用Yield并将Seed值作为参数():
公共静态IEnumerable Shuffle(此IEnumerable源,Int32?seed=null){
列表缓冲区=source.ToList();
随机随机=seed.HasValue?新随机(seed.Value):新随机();
Int32计数=缓冲区计数;
对于(int32i=0;i
我敢打赌,使用一个带有常数种子的随机数进行洗牌。使用来自的洗牌器,但使用接受种子的Random
构造函数的重载,每次使用相同的种子。.OrderBy(x=>Guid.NewGuid());我认为这是一个可怕的黑客,在SQL或一些罕见的情况下使用…@ XANATOS在这种情况下,我不在SQL中使用,但有时我需要在SQLYes使用它,使用一个随机的种子来拖曳,我敢打赌。并且每次都使用相同的种子..OrderBy(x=>Guid.NewGuid());我认为这是一个可怕的黑客,在SQL或一些罕见的情况下使用…@ XANATOS在这种情况下,我不在SQL中使用,但有时我需要在SQLYes使用它,注意字符串的散列不是固定的…中有一个选项可以将“种子”随机化。除非OP希望保证应用程序每次运行的顺序相同,否则这是可以的。来自MSDN:“哈希代码本身不保证稳定。相同字符串的哈希代码可能因.NET Framework的不同版本而异,也可能因.NET Framework的单个版本而因平台而异(如32位和64位)。在某些情况下,它们甚至可能因应用程序域而异。”
我确实想保证每次运行应用程序的顺序相同。哈希值不是随机的,并且在每次新执行程序时都会发生变化。请注意,字符串的哈希值不是固定的。。。中有一个选项可以将“种子”随机化。除非OP希望保证应用程序每次运行的顺序相同,否则这是可以的。来自MSDN:“哈希代码本身不保证稳定。相同字符串的哈希代码可能因.NET Framework的不同版本而异,也可能因.NET Framework的单个版本而因平台而异(如32位和64位)。在某些情况下,它们甚至可能因应用程序域而异。”
我确实希望保证应用程序每次运行的顺序相同。哈希不是随机的,并且在每次新执行程序时都会发生更改。我正在寻找IEnumerable扩展,而不是IList,并且不更改源代码,而是返回一个新的扩展,因此它与OrderBy一样工作。我添加了更新,一个基于您的代码,另一个使用yield。你认为哪一个更好?@ MiguelMura,我发现更新3基本上是一样的。我会选择那个。它在算法上也和我上面发布的洗牌算法一样。我做了一些单元测试,更新3似乎运行良好。。。这是:@MiguelMoura是的,我想你应该跟着它走!我正在寻找一个IEnumerable扩展,而不是IList,并且不改变源代码,而是返回一个新的扩展,这样它就可以像OrderBy一样工作。我添加了更新,一个基于您的代码,另一个使用yield。你认为哪一个更好?@ MiguelMura,我发现更新3基本上是一样的。我会选择那个。它在算法上也和我上面发布的洗牌算法一样。我做了一些单元测试,更新3似乎运行良好。。。这是:@MiguelMoura是的,我知道