我正在尝试通过更改索引来随机更改数组的元素。没关系。现在问题是因为随机总是随机的,我可以得到两个相同的结果。
例如:
周一:歌曲1
歌曲2
歌曲3
周二:歌曲2
歌曲1
歌曲3
周三:歌曲1
歌曲2
歌曲3
等等......
来自
的清单周一
和
在这种情况下,星期三
是相同的。我需要控制它,但正如你在代码中看到的那样,一旦我从一天获得列表,我就打印出来。我想把它放在数组或元组上并检查该元组是否存在,但我认为它太复杂了。我想也许我可以制作自己的随机功能。但是,我仍然不确定那个解决方案。有关如何解决这种情况的任何想法?谢谢!
这是我到目前为止的代码:
static string[] songs = new string[] { "song1", "song2", "song3" };
static string[] days = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
private static Random random = new Random();
/* Random number between lower and higher, inclusive */
public static int rand(int lower, int higher)
{
int r = lower + (int)(random.Next(0, 2) * (higher - lower));
return r;
}
/* pick M elements from original array. Clone original array so that
7 * we don’t destroy the input. */
public static string[] pickMRandomly()
{
string[] subset = new string[songs.Length];
string[] array = (string[])songs.Clone();
for (int j = 0; j < songs.Length; j++)
{
int index = rand(j, array.Length - 1);
subset[j] = array[index];
array[index] = array[j]; // array[j] is now “dead”
}
return subset;
}
public static void playListCreation()
{
for (int j = 0; j < days.Length; j++)
{
var result =pickMRandomly();
System.Console.WriteLine(days[j]);
foreach (var i in result)
{
System.Console.WriteLine(i + " ");
}
System.Console.WriteLine("/n");
}
}
}
答案 0 :(得分:2)
如果我理解正确,你不仅希望每天随机排列歌曲,而且每天都想要一个唯一的(和随机)歌曲排列。
我能想到保证这一点的唯一方法是找出所有可能的歌曲组合并随机排序 - 然后从列表中挑选出每天的不同组合。
from sklearn.feature_extraction.image import extract_patches
all_patches = extract_patches(x, patch_size)
upper_left = indices - patch_size // 2
patches = all_patches[upper_left[0], upper_left[1]]
答案 1 :(得分:1)
根据我的理解,您想要创建一个随机播放列表,如果之前已创建此播放列表,您希望生成另一个播放列表(直到它是唯一的)。您可以这样做的一种方法是将某种哈希值添加到HashSet
并查看它是否先前已生成。例如,
bool HashSet<int> playlistHashes = new HashSet<int>();
private bool CheckIfUnique(string[] playlist)
{
//HashSet returns false if the hash already exists
//(i.e. playlist already likely to have been created)
return playlistHashes.Add(string.Join("",playlist).GetHashCode());
}
然后,一旦您生成了播放列表,就可以调用该方法并查看它是否返回false。如果它返回false,则之前已创建该播放列表顺序,因此您可以再次生成。使用上述技术意味着song1, song2, song3
与song3, song2, song1
不同,因此顺序非常重要。
正如我在这个问题的评论中所提到的,如果你正在测试3首歌曲,那么一周只有6种不同的排列和7天,所以你会得到一份副本。
旁注,GetHashCode
可以抛出“误报”,但是由您决定它的可能性,以及影响实际上是否具有任何意义,因为无论如何都会产生新的播放列表。好线程获取更多信息here。如果GetHashCode
在这里不够用,有许多散列技术可以降低碰撞几率。
答案 2 :(得分:1)
考虑到您手头有3 Songs
,并希望为一周中的每一天(7天)分配唯一的组合。这是不可能的,因为你只能用这三个组成六个独特的组合。所以肯定有一个重复序列。如果您将另一首歌曲(让它为24
)添加到此集合中,您将获得"song4"
个唯一的歌曲序列。我已经添加了一个片段,可以帮助您获得这些独特歌曲序列的组合。
string[] songs = new string[] { "song1", "song2", "song3", "song4" };
int numberOfSongs = songs.Count();
var collection = songs.Select(x => x.ToString()); ;
for (int i = 1; i < numberOfSongs; i++)
{
collection = collection.SelectMany(x => songs, (x, y) => x + "," + y);
}
List<string> SongCollections = new List<string>();
SongCollections.AddRange(collection.Where(x => x.Split(',')
.Distinct()
.Count() == numberOfSongs)
.ToList());
现在SongCollections
将包含24
个4
首歌曲的唯一序列。 (如果您选择3首歌曲,那么您将获得6
个独特序列。您可以从这些集合中应用随机选择的序列,并根据需要分配到日期。
现在让我使用Dictionary<string, int> dayCollectionMap
将一个集合映射到一天(注意:这里我使用4
首歌曲的集合,因为3不足以{{ 1}})。请考虑以下代码段:
7 days
这样您就可以使用代码
选择Dictionary<string, int> dayCollectionMap = new Dictionary<string, int>();
string[] days = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
Random randomCollection = new Random();
foreach (string day in days)
{
int currentRandom = randomCollection.Next(0, SongCollections.Count());
if (!dayCollectionMap.Any(x => x.Value == currentRandom))
{
dayCollectionMap.Add(day, currentRandom);
}
else
{
// The collection is already taken/ Add another random sequence
while (true)
{
currentRandom = randomCollection.Next(0, SongCollections.Count());
if (!dayCollectionMap.Any(x => x.Value == currentRandom))
{
dayCollectionMap.Add(day, currentRandom);
break;
}
}
}
}
的歌曲集
Wednesday