首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >基于MATLAB的DJing (低电平I/O)

基于MATLAB的DJing (低电平I/O)
EN

Stack Overflow用户
提问于 2014-10-09 16:36:36
回答 3查看 178关注 0票数 0

好吧,各位,这是一个星期的时间,我学习如何用MATLAB做奇怪的事情。这周是DJing。我需要做的是弄清楚如何让我的函数输出歌曲的名字,歌曲的长度最接近剩下的时间。例如,如果我展示我的DJing技能,而我还有3:22,我必须选择一首长度最接近剩下时间的歌曲(可以是短的,也可以是更长的)。我有一个.txt文件可供选择。

代码语言:javascript
运行
AI代码解释
复制
Test Case
song1 = pickSong('Funeral.txt', '3:13')
song1 => 'Neighborhood #2 (Laika)'


The file for this looks like:
1. Neighborhood #1 (Tunnels) - 4:48
2. Neighborhood #2 (Laika) - 3:33
3. Une annee sans lumiere - 3:40
4. Neighborhood #3 (Power Out) - 5:12
5. Neighborhood #4 (7 Kettles) - 4:49
6. Crown of Love - 4:42
7. Wake Up - 5:39
8. Haiti - 4:07
9. Rebellion (Lies) - 5:10
10. In the Backseat - 6:21

我已经计划好了大部分,我遇到的问题是填充我的单元格数组。它只输入最后一首歌,然后在循环运行后将其更改为a-1。我尝试了三种不同的方法,最后一种是最复杂的(而且看起来很抱歉)。一旦我把单元格数组变成了正确的形式(作为完整的歌曲列表,而不仅仅是-1),我就应该清楚了。

代码语言:javascript
运行
AI代码解释
复制
function[song] = pickSong(file_name,time_remain)

Song_list = fopen(file_name, 'r'); %// Opens the file
Song_names = fgetl(Song_list); %// Retrieves the lines, or song names here
Songs_in = ''; %// I had this as a cell array first, but tried to populate a string this time
while ischar(Songs) %// My while loop to pull out the song names
Songs_in = {Songs_in, Songs}; 
Songs = fgetl(Song_list);
if ischar(Songs_in) %//How I was trying to populate my string
    song_info = [];
    while ~isempty(Songs_in)
    [name, time] = strtok(Songs_in);
    song_info = [song_info {name}]; 
        end
    end
end

[songs, rest] = strtok(Songs, '-');
[minutes, seconds] = strtok(songs, ':');
[minutes2, seconds2] = strtok(time_remain, ':')

all_seconds = (minutes*60) + seconds; %// Converting the total time into seconds
all_seconds2 = (minutes2*60) + seconds2;
song_times = all_seconds;
time_remain = all_seconds2

time_remain = min(time_remain - song_times);



fclose(file_name);

end

请并感谢您的帮助:)

麻烦的案件:

代码语言:javascript
运行
AI代码解释
复制
song3 = pickSong('Resistance.txt', '3:57') 
song3 => 'Exogenesis: Symphony Part 2 (Cross-Pollination)'

1. Uprising - 5:02
2. Resistance - 5:46
3. Undisclosed Desires - 3:56
4. United States of Eurasia (+Collateral Damage) - 5:47
5. Guiding Light - 4:13
6. Unnatural Selection - 6:54
7. MK ULTRA - 4:06
8. I Belong to You (+Mon Coeur S'ouvre a Ta Voix) - 5:38
9. Exogenesis: Symphony Part 1 (Overture) - 4:18
10. Exogenesis: Symphony Part 2 (Cross-Pollination) - 3:57
11. Exogenesis: Symphony Part 3 (Redemption) - 4:37
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-09 20:12:04

我将用你已经写的大部分内容来写一个答案,而不是建议一些完全不同的东西。虽然regexp也很强大(我也喜欢正则表达式),但我发现它对于您目前所了解的东西来说太高级了,所以现在让我们放弃它吧。

这样,您就可以了解代码的错误所在,以及我的调试器有多棒(开玩笑)。当你在文本文件中阅读时,你所拥有的几乎是有效的。在创建存储所有字符串的单元格数组方面,您做了一个很好的选择。

我还将借用MrAzzaman先生在通过strtok (可怕的工作)以秒为单位计算时间时的逻辑。

另外,我要稍微改变一下你们的逻辑,这样我才能理解我将如何去做。以下是基本算法:

  1. 打开文件,像在代码中那样读第一行(歌曲)
  2. 初始化包含文本文件中第一首歌曲的单元格数组。
  3. 直到我们到达文本文件的末尾,读取整行并将其添加到单元格数组中。您还注意到,一旦您点击了-1,我们就没有更多的歌曲可读了,所以退出循环。
  4. 现在我们已经把歌曲放在一个单元格数组中,其中包括曲目号、歌曲和每首歌曲的时间,我们将再创建两个单元格数组。第一个将只将歌曲的时间存储为字符串,分钟和秒都由:分隔。下一个只会包含歌曲本身的名字。现在,我们遍历从步骤3创建的单元格数组中的每个元素。(A)为了填充第一个单元格数组,我使用strfind查找all出现的-字符所在位置。一旦我找到了这些发生的位置,我就会选择最后一个位置,即-发生的位置。我用它来索引我们的歌曲字符串,跳过两个字符来跳过-字符和空格字符。我们从这一点开始提取所有的字符到行的末尾来提取我们的时间。 (b)要填充第二个单元格数组,我再次使用strfind,但随后确定空间发生的位置,并选择第一个空格发生的位置的索引。这与歌曲编号与歌曲音轨之间的差距相对应。使用(a)中索引的结果,我从第一个空格的索引中跳过一个字符到索引- 字符前的索引,以成功地获得歌曲。这是因为在-字符之前的歌曲标题的最后一个字之间可能会有一个空格,所以我们想要删除这个空格。
  5. 接下来,对于步骤4中计算的第一个单元格数组中的每一首歌曲时间,我使用strtok,就像您使用过的那样,并将字符串由:拆分。MrAzzaman也使用了它,我将借用他的逻辑来计算每一次所需的总秒数。
  6. 最后,我们找出了哪个时间最接近剩余的时间。注意,我们还需要像第5步那样将剩余时间转换为秒。正如MrAzzaman所说,您可以在MATLAB中使用min函数,并使用函数的第二输出。这将告诉数组中的发生了最小值。因此,我们只需搜索每首歌的剩馀时间和经过的时间之间的最小差异。请注意,您说过您不关心您是否过去或在过去的时间。您只需要最近的时间。在这种情况下,您需要获得时间差的绝对值。假设你有一首歌花了3:59,另一首歌是6:00,剩下的时间是4:00。假设你的曲目中没有4:00长的歌曲,你会想要选择3:59的歌曲。但是,如果您从较长的轨道(6:00)减去剩余的时间,您将得到一个负差,min将返回此轨道.不是3:59的那首歌。这就是你需要取绝对值的原因,所以这会忽略你是在剩余的时间内还是在剩余的时间内。
  7. 一旦我们知道了选择哪首歌,返回给我们最小的歌曲名称。确保你也关闭了文件!

下面是代码,不需要再多说了:

代码语言:javascript
运行
AI代码解释
复制
function [song] = pickSong(file_name, time_remain)

% // Open up the file
fid = fopen(file_name, 'r');

%// Read the first line
song_name = fgetl(fid);

%// Initialize cell array
song_list = {song_name};

%// Read in the song list and place
%// each entry into a cell array
while ischar(song_name)
    song_name = fgetl(fid);
    if song_name == -1
        break;
    end
    song_list = [song_list {song_name}];
end

%// Now, for each entry in our song list, find all occurrences of the '-'
%// with strfind, and choose the last index that '-' occurs at
%// Make sure you skip over by 2 spaces to remove the '-' and the space
song_times = cell(1,length(song_list));
song_names = cell(1,length(song_list));
for idx = 1 : length(song_list)
    idxs = strfind(song_list{idx}, '-');
    song_times{idx} = song_list{idx}(idxs(end)+2:end);

    idxs2 = strfind(song_list{idx}, ' ');
    %// Figure out the index of where the first space is, then extract
    %// the string that starts from 1 over, to two places before the 
    %// last '-' character
    song_names{idx} = song_list{idx}(idxs2(1)+1 : idxs(end)-2);
end

%// Now we have a list of times for each song.  Tokenize by the ':' to 
%// separate the minutes and times, then calculate the number of seconds
%// Logic borrowed by MrAzzaman
song_seconds = zeros(1,length(song_list));
for idx = 1 : length(song_list)
    [minute_str, second_str] = strtok(song_times{idx}, ':');
    song_seconds(idx) = str2double(minute_str)*60 + str2double(second_str(2:end));
end

%// Now, calculate how much time is remaining from the input
[minute_str, second_str] = strtok(time_remain, ':');
seconds_remain = str2double(minute_str)*60 + str2double(second_str(2:end));

%// Now, choose the song that is closest to the amount of time
%// elapsed
[~,song_to_choose] = min(abs(seconds_remain - song_seconds));

%// Return the song you want
song = song_names{song_to_choose};

%// Close the file
fclose(fid);

end

在上面给出的两个例子中,这是我得到的输出。我冒昧地创建了自己的文本文件,其中包含了您的音乐(非常棒的品味):

代码语言:javascript
运行
AI代码解释
复制
>> song1 = pickSong('Funeral.txt', '3:13')

song1 =

Neighborhood #2 (Laika)

>> song2 = pickSong('Resistance.txt', '3:57')

song2 =

Exogenesis: Symphony Part 2 (Cross-Pollination)
票数 1
EN

Stack Overflow用户

发布于 2014-10-10 21:25:11

以下是我的实现:

代码语言:javascript
运行
AI代码解释
复制
function song = pickSong(filename, time_remain)
    % read songs file into a table
    t = readSongsFile(filename);

    % query song length (in seconds)
    len = str2double(regexp(time_remain, '(\d+):(\d+)', ...
        'tokens', 'once')) * [60;1];

    % find closest match
    [~,idx] = min(abs(t.Duration - len));

    % return song name
    song = t.Title(idx);
end

function t = readSongsFile(filename)
    % read the whole file (as a cell array of lines)
    fid = fopen(filename,'rt');
    C = textscan(fid, '%s', 'Delimiter',''); C = C{1};
    fclose(fid);

    % parse lines of the form: "0. some name - 00:00"
    C = regexp(C, '^(\d+)\.\s+(.*)\s+-\s+(\d+):(\d+)$', 'tokens', 'once');
    C = cat(1, C{:});

    % extract columns and create a table
    t = table(str2double(C(:,1)), ...
        strtrim(C(:,2)), ...
        str2double(C(:,3:4)) * [60;1], ...
        'VariableNames',{'ID','Title','Duration'});
    t.Properties.VariableUnits = {'', '', 'sec'};
end

我们应该从测试文件中得到预期的结果:

代码语言:javascript
运行
AI代码解释
复制
>> pickSong('Funeral.txt', '3:13')
ans = 
    'Neighborhood #2 (Laika)'

>> pickSong('Resistance.txt', '3:57')
ans = 
    'Exogenesis: Symphony Part 2 (Cross-Pollination)'

注意:上面的代码使用MATLAB表来存储数据,这样可以方便地操作。例如:

代码语言:javascript
运行
AI代码解释
复制
>> t = readSongsFile('Funeral.txt');
>> t.Minutes = fix(t.Duration/60);       % add minutes column
>> t.Seconds = rem(t.Duration,60);       % add seconds column

>> sortrows(t, 'Duration', 'descend')    % show table sorted by duration
ans = 
    ID                Title                Duration    Minutes    Seconds
    __    _____________________________    ________    _______    _______
    10    'In the Backseat'                381         6          21     
     7    'Wake Up'                        339         5          39     
     4    'Neighborhood #3 (Power Out)'    312         5          12     
     9    'Rebellion (Lies)'               310         5          10     
     5    'Neighborhood #4 (7 Kettles)'    289         4          49     
     1    'Neighborhood #1 (Tunnels)'      288         4          48     
     6    'Crown of Love'                  282         4          42     
     8    'Haiti'                          247         4           7     
     3    'Une annee sans lumiere'         220         3          40     
     2    'Neighborhood #2 (Laika)'        213         3          33    

% find songs that are at least 5 minutes long
>> t(t.Minutes >= 5,:)

% songs with the word "Neighborhood" in the title
>> t(~cellfun(@isempty, strfind(t.Title, 'Neighborhood')),:)
票数 2
EN

Stack Overflow用户

发布于 2014-10-09 17:10:51

您可以使用textscan来管理这一点,如下所示:

代码语言:javascript
运行
AI代码解释
复制
function[song,len] = pickSong(file_name,time_remain)

fid = fopen(filename);

toks = textscan(fid,'%[^-] - %d:%d');
songs = toks{1};
song_len = double(toks{2}*60 + toks{3});

[min_rem, sec_rem] = strtok(time_remain, ':');
time_rem = str2double(min_rem)*60 + str2double(sec_rem(2:end));

[len,i] = min(abs(time_rem - song_len));
song = songs{i};

请注意,只有当您的歌曲名称中没有“-”字符时,这才会有效。

编辑:这是一个解决方案,(应该)在任何歌曲标题上工作:

代码语言:javascript
运行
AI代码解释
复制
function[song,len] = pickSong(file_name,time_remain)

file = fileread(file_name);
toks = regexp(file,'\d+. (.*?) - (\d+):(\d+)\n','tokens');
songs = cell(1,length(toks));
song_lens = zeros(1,length(toks));
for i=1:length(toks)
    songs{i} = toks{i}{1};
    song_lens(i) = str2double(toks{i}{2})*60 + str2double(toks{i}{3});
end

[min_rem, sec_rem] = strtok(time_remain, ':');
time_rem = str2double(min_rem)*60 + str2double(sec_rem(2:end));

[len,i] = min(abs(time_rem - song_lens));
song = songs{i};

regexp是一个MATLAB函数,它在字符串上运行正则表达式(在本例中是歌曲名文件)。字符串'\d+. (.*?) - (\d+):(\d+)\n'扫描每一行,提取每首歌曲的名称和长度。\d+匹配一个或多个数字,而.*?匹配任何数字。括号用于对输出进行分组。因此,我们有:

代码语言:javascript
运行
AI代码解释
复制
match n digits, followed by a (string), followed by (n-digits):(n-digits)

括号中的所有内容都作为单元格数组返回给toks变量。for循环只是从结果单元格数组中提取歌曲名称和长度。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26290154

复制
相关文章
jsonobject string转json_string转换为long
本文使用一个小例子展示在java中怎样将一个JSON格式的字符串转化为JSONObject对象。注意,我们使用的是 org.json.simple.JSONObject;
全栈程序员站长
2022/09/22
3.4K0
jsonobject string转json_string转换为long
integer转string java_Integer转换为String类型[通俗易懂]
Exception in thread “main” java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
全栈程序员站长
2022/11/01
2.1K0
string转换为jsonarray_jsonobject转jsonarray
如果用的是fastjson 则导包为 import com.alibaba.fastjson.JSONObject
全栈程序员站长
2022/09/22
2K0
string转换为jsonarray_jsonobject转jsonarray
java map 转string_java-将Map <String,Object>转换为Map <String,String>
Map map = new HashMap(); //Object is containing String
全栈程序员站长
2022/08/25
12.4K0
integer转换为string_go 字符串转int
str := “123” // string 转 int i, err := strconv.Atoi(str) if err == nil {   fmt.Printf(“i: %v\n”,i) } // string 转 int64 i64,err := strconv.ParseInt(str,10,64) if err == nil {   fmt.Printf(“i64: %v\n”,i64) } // string 转 int32 j,err := strconv.ParseInt(str,10,32) if err == nil {   fmt.Printf(“i32: %v\n”,int32(j)) }
全栈程序员站长
2022/11/06
3.5K0
PHP中的Array2String & String2Array
在用PHP开发时我们有时期望将一个数组(任意多维),在页面之间传递或者存入数据库。这时我们可以将Array转换为String传递或保存,取出用的时候在转换回来即可。 <?/*在Array和String
joshua317
2018/04/10
2K0
java把string转int类型_java把String类型转换为int类型的方法
这篇文章将为大家详细讲解有关java把String类型转换为int类型的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
全栈程序员站长
2022/11/10
4.2K0
java把string转int类型_java把String类型转换为int类型的方法
iOS基础【string和Array 互转】&【 string与class互转】& 【json string 和Array互转】
在适配iOS13的时候,经常要对特定类进行特出处理,这个时候class与string之间的互相转换就经常需要使用。
公众号iOS逆向
2021/03/24
1.2K0
iOS基础【string和Array 互转】&【 string与class互转】& 【json string 和Array互转】
Java中将Map转String,String转Map
但很多时候并不能直接将Map对象的toString() 而是应该转换为JsonObject后再调用toString()后存入就正常了
JavaEdge
2021/02/22
14.5K0
jsonobject string转json_java jsonobject转string
这里的JSONObject对像是不是hutool这些工具类的哦,是java内部自带这个。
全栈程序员站长
2022/09/25
3.8K0
String转JsonArray转List[通俗易懂]
场景是查看学生详情时需要展示学生学历信息 比如某某年 哪个学校毕业 奖惩情况等等
全栈程序员站长
2022/08/31
3.2K0
javabyte数组转string_byte数组转string
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/179050.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
3K0
IntPtr 转 string
假设有 intPtr pBuffer 方法一: 直接使用Marshal.PtrToStringAnsi方法: string ss = Marshal.PtrToStringAnsi(pBuffer); 但,如果pBuffer中有\0,此方法所获取的字符串会被截断。这种情况要用方法二。 方法二: 先转为byte数组,然后再转string: byte[] cc = new byte[dwBufSize]; Marshal.Copy(pBuffer, cc, 0, (int)dwBufSi
庞小明
2018/03/09
2.4K0
long转string mybatis_Long转String总结
* 通过测试,发现如果传入null,则第一种方式报错;第二种方式打印出null字符串
全栈程序员站长
2022/08/28
3.3K0
python 数组转换为字典_char转换为string
会触发TypeError: sequence item 0: expected string, int found的错误
全栈程序员站长
2022/11/07
1.1K0
数组转String
这里对文章进行总结:以上就是今天要讲的内容,本文仅仅简单介绍了Java转的数组使用
用户10175992
2022/11/15
3K0
Array,Date,String 对象方法
方法 描述 concat() 连接两个或更多的数组,并返回结果。 copyWithin() 从数组的指定位置拷贝元素到数组的另一个指定位置中。 entries() 返回数组的可迭代对象。 every() 检测数值元素的每个元素是否都符合条件。 fill() 使用一个固定值来填充数组。 filter() 检测数值元素,并返回符合条件所有元素的数组。 find() 返回符合传入测试(函数)条件的数组元素。 findIndex() 返回符合传入测试(函数)条件的数组元素索引。 forEach() 数组每个元素都执行一次回调函数。 from() 通过给定的对象中创建一个数组。 includes() 判断一个数组是否包含一个指定的值。 indexOf() 搜索数组中的元素,并返回它所在的位置。 isArray() 判断对象是否为数组。 join() 把数组的所有元素放入一个字符串。 keys() 返回数组的可迭代对象,包含原始数组的键(key)。 lastIndexOf() 搜索数组中的元素,并返回它最后出现的位置。 map() 通过指定函数处理数组的每个元素,并返回处理后的数组。 pop() 删除数组的最后一个元素并返回删除的元素。 push() 向数组的末尾添加一个或更多元素,并返回新的长度。 reduce() 将数组元素计算为一个值(从左到右)。 reduceRight() 将数组元素计算为一个值(从右到左)。 reverse() 反转数组的元素顺序。 shift() 删除并返回数组的第一个元素。 slice() 选取数组的的一部分,并返回一个新数组。 some() 检测数组元素中是否有元素符合指定条件。 sort() 对数组的元素进行排序。 splice() 从数组中添加或删除元素。 toString() 把数组转换为字符串,并返回结果。 unshift() 向数组的开头添加一个或更多元素,并返回新的长度。 valueOf() 返回数组对象的原始值。
江一铭
2022/07/05
1.2K0
string和array基本方法
  变异方法 :  push() pop() shift() unshift() splice() sort() reverse()  会改变被这些方法调用的原始数组。
刘嘿哈
2022/10/25
4040
alibaba String转json转map
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/145506.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/27
5K0
String转JSONArray,遍历JSONArray,Array数组转换成JSON字符串
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/151413.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/31
1.2K0
String转JSONArray,遍历JSONArray,Array数组转换成JSON字符串

相似问题

将Array<String>转换为String,然后返回到Array<String>

26

从Array[((String,String),Double)]转换为Array[(String,Array[((String,String),Double)]]

11

如何将Array[(String,List[String])]转换为Array[(String,String)]

43

配置单元:将array<struct<key:string、value:array<string>>>转换为map<string、array<string>>

10

将array<String^>转换为System::String^

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文