我正在做Chris Pine的“学习编程”。 Ch.11中的练习要求创建一个改组的播放列表。以下是我写的内容:
def shuffle songs
playlist = []
x = 0
y = 0
count = songs.length
while y <= count
x = rand(count)
if songs[x] != 'used'
playlist.push songs[x]
songs[x] = 'used'
y= y + 1
end
end
filename = '/Users/M/Music/shuffled_playlist8.m3u'
File.open filename, 'w' do |s|
s.puts playlist
end
end
song_name = Dir['/Users/M/Music/*.{MP3,mp3}']
shuffle song_name
在ln7中,当我将<=
代替<
时,该程序不会退出。它可能与方法rand
有关,它不包含随机化,或者数组的范围从0
开始。有人可以指出导致该计划没有退出的原因吗?
答案 0 :(得分:1)
由于你在0处开始'y'并在每次找到一条新的未使用的歌曲(然后标记为已使用的歌曲)时递增它,'y'可以获得的最大值是'count'。
因此,while循环将永远持续,因为它总是满足&lt; ='count'条件。
使用&lt;比较是达到你想要做的事情的正确方法,因为一旦'y == count',你就创建了一个播放列表,其中只包含原始数组中的每首歌曲一次。
答案 1 :(得分:0)
y
始终小于或等于count
,且永远不会超过count
。这是因为您从y = 0
开始,当使用所有歌曲时,y
等于count
。
例如,如果只有一首歌曲,则该歌曲将在第一个循环中使用,您的y = 1
和count = 1
。在此之后,这些歌曲将永远不会增加。因此,如果条件为y <= count
使用此方法,您将使用随机循环循环不必要的次数。更好的方法是动态地减少x
给rand()
并从列表中删除使用过的歌曲,这样就不会再次出现相同条件的重复。
def shuffle songs
playlist = []
while songs.length > 0
x = rand(songs.length)
playlist.push songs[x]
songs.delete_at(x)
end
playlist
end
song_name = ("a".."e").to_a
shuffle song_name # => ["d", "c", "a", "b", "e"]
或单行,使用内置shuffle
函数
song_name = ("a".."e").to_a
song_name.shuffle # => ["e", "c", "b", "a", "d"]