C# 用随机数重命名
我想让smth像这样。。。 基本上我试着用他们的名字来洗牌音乐。 一切都很好,但我想知道是否有一种方法可以让随机函数不重复相同的数字C# 用随机数重命名,c#,random,foreach,rename,generate,C#,Random,Foreach,Rename,Generate,我想让smth像这样。。。 基本上我试着用他们的名字来洗牌音乐。 一切都很好,但我想知道是否有一种方法可以让随机函数不重复相同的数字 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { button1.Enabled = true; DirectoryInfo dir = new DirectoryInfo(comboBox1.SelectedItem.ToString());
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
button1.Enabled = true;
DirectoryInfo dir = new DirectoryInfo(comboBox1.SelectedItem.ToString());
count = dir.GetFiles().Length;
label3.Text = "Files loaded: " + count.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
DirectoryInfo d = new DirectoryInfo(comboBox1.SelectedItem.ToString());
FileInfo[] infos = d.GetFiles("*.mp3");
int i = 1;
foreach (FileInfo f in infos)
{
File.Move(f.FullName, Path.Combine(f.DirectoryName, i + ". " + f.Name));
i = rnd.Next(1, count+1);
}
}
一个简单的方法是创建一个文件列表,将所有文件名都放在其中。然后,您可以使用类似于的方法来洗牌该列表,从而得到一个有保证的随机序列。然后,您可以在列表上执行常规for循环,并根据计数变量重命名文件 这样,您就不用尝试生成随机数来重命名对象,只需将它们像一副牌一样洗牌,然后根据新的顺序重命名它们。另外,请注意,Fisher-Yates shuffle是O(n),因为对任何一组值进行随机化只需要执行一次 示例代码,基于您的代码:
DirectoryInfo d = new DirectoryInfo(comboBox1.SelectedItem.ToString());
List<FileInfo> infos = new List<FileInfo>(d.GetFiles("*.mp3"));
infos.FisherYatesShuffle(rnd);
for (int i = 0; i < files.Count; ++i)
{
File.Move(f.FullName, Path.Combine(f.DirectoryName, i + ". " + f.Name));
}
DirectoryInfo d=newdirectoryinfo(comboBox1.SelectedItem.ToString());
列表信息=新列表(d.GetFiles(“*.mp3”);
渔业信息(rnd);
对于(int i=0;i
还有一些(未经测试的)Fisher-Yates Shuffle算法,我刚刚拼凑起来作为列表的扩展方法:
public static void FisherYatesShuffle<T>(this IList<T> list, Random random)
{
for (int i = 0; i < list.Count; i++)
{
int index = rnd.Next(0, list.Count - i);
int lastIndex = list.Count - i - 1;
T value = list[index];
{
T temp = list[num1];
list[num1] = list[num2];
list[num2] = temp;
}
list.RemoveAt(lastIndex);
list.Add(value);
}
}
publicstaticvoidfisheryatesshuffle(此IList列表,随机)
{
for(int i=0;i
您可以尝试以下方法:
string path = comboBox1.SelectedItem.ToString();
var files = Directory.GetFiles(path, "*.mp3");
// Create list of shuffled numbers
var shuffledNumbers = Enumerable.Range(1, files.Length).ToArray().OrderBy(i => Guid.NewGuid());
// put the shuffled numbers into a stack
var indexes = new Stack<int>(shuffledNumbers);
foreach(var file in files) {
// extract first item from the stack
var index = indexes.Pop();
// move file
File.Move(file, Path.Combine(path, $"{index}. {Path.GetFileName(file)}"));
}
string path=comboBox1.SelectedItem.ToString();
var files=Directory.GetFiles(路径“*.mp3”);
//创建随机数字列表
var shuffledNumbers=Enumerable.Range(1,files.Length).ToArray().OrderBy(i=>Guid.NewGuid());
//将洗牌后的数字放入堆栈中
var index=新堆栈(洗牌数字);
foreach(文件中的var文件){
//从堆栈中提取第一项
var index=index.Pop();
//移动文件
File.Move(File,Path.Combine(Path,$“{index}.{Path.GetFileName(File)}”);
}
基本上,我使用Guid.NewGuid
作为顺序键来洗牌序列号数组
每次,OrderBy
将比较数组的两个项时,它将得到一个不同的、完全随机的值
使用堆栈可以让我只弹出下一个数字,而不必使用索引器变量(但如果您喜欢这种方式,则完全可以)。我同意Max的答案。如果有人觉得它有用,我有一个名为RandomShuffler的Nuget包: DataJuggler.RandomShuffler.Core(点网核心) DataJuggler.Core.RandomShuffler(.Net Framework) 洗牌器和随机数生成器之间的区别在于,洗牌器一直在拉牌,就像一副牌,并导致更均匀的分布,其中随机数可以在数百万年或更长的时间内均匀分布 获取列表或数组的最小和最大界限
using DataJuggler.RandomShuffler.Core;
int min = 0;
int max = List.Count -1;
// Create a new instance of a 'RandomShuffler' object.
Shuffler = new RandomShuffler(min, max, 1, 3);
这将在最小值和最大值之间创建一个列表,1作为第三个参数,表示只有1个集合(无重复)
然后,每次需要一个新值时,只需调用Shuffler.PullNextItem:
// pull the next White value
int index = Shuffler.PullNextItem();
var songToPlay = List[index]; // not sure what properties you need
如果您用完了,它会自动洗牌,并且还有对卡片的覆盖。看看我发现这非常有用,它可以完成这项工作
每次OrderBy比较数组中的两个项目时,它都会得到一个不同的、完全随机的值。
不,不会。虽然guid是唯一的,但顺序可能保持不变。F.e.UID对(1234523456)和(5432165432)虽然是唯一的,但产生相同的顺序