这一周的那个时刻,我意识到我在MATLAB中的理解有多少。本周,我们在迭代上做了功课,所以使用for循环和while循环。我目前遇到的问题是我必须编写一个决定雇用某人的职能的问题。我给出了一个名单,一份GPA列表和一个逻辑向量,告诉我一个学生是否留下来说话。我要输出的是雇用人员的名字以及他们与招聘人员聊天的时间。
function[candidates_hire, time_spent] = CFRecruiter(names, GPAs, stays_to_talk)
为了被录用,犬科动物的GPA必须高于2.5(不包括在内)。为了被录用,学生必须坚持说话,如果他们不说话,他们就不会被录用。名称由','分隔开。和GPA是一个向量。谈话所花费的时间取决于:
Time in minutes = (GPA - 2.5) * 4;
到目前为止我的代码:
function[candidates_hire, time_spent] = CFRecruiter(names, GPAs, stays_to_talk)
candidates = strsplit(names, ', ');
%// My attempt to split up the candidates names.
%// I get a 1x3 cell array though
for i = 1:length(GPAs)
%// This is where I ran into trouble, I need to separate the GPAs
student_GPA = (GPAs(1:length(GPAs)));
%// The length is unknown, but this isn't working out quite yet.
%// Not too sure how to fix that
return
end
time_spent = (student_GPA - 2.5) * 4; %My second output
while stays_to_talk == 1 %// My first attempt at a while-loop!
if student_GPA > 2.5
%// If the student has a high enough GPA and talks, yay for them
student = 'hired';
else
student = 'nothired'; %If not, sadface
return
end
end
hired = 'hired';
%// Here was my attempt to get it to realize how was hired, but I need
%// to concatenate the names that qualify into a string for the end
nothired = 'nothired';
canidates_hire = [hired];
我的主要问题是如何让函数知道它们的名称(1)具有GPA的GPA(1)。建议我启动一个计数器,并且我必须确保我的循环保留了它们的名称。有这个问题的任何建议吗?拜托,谢谢你:)
Test Codes
[Names, Time] = CFRecruiter('Jack, Rose, Tom', [3.9, 2.3, 3.3],...
[false true true])
=> Name = 'Tom'
Time = 3.2000
[Names, Time] = CFRecruiter('Vatech, George Burdell, Barnes Noble',...
[4.0, 2.5, 3.6], [true true true])
=> Name = 'Vatech, Barnes Noble'
Time = 10.4000
答案 0 :(得分:2)
对于这个特殊问题,我将取消for
和while
循环,主要是因为你可以非常优雅地解决这个问题(我不是你)三代码行...如果你计算返回候选人名字,那就好四个。另外,教你MATLAB的人(绝对没有违法行为)对他们所说的内容并不是最微妙的想法。 MATLAB中的第一条规则是,如果你可以对代码进行矢量化,那就去做吧。但是,由于JIT(即时)加速器的性能增强,在某些情况下for
循环非常合适。如果您很好奇,可以check out this link了解有关JIT的更多详细信息。但是,我可以保证在这种情况下使用循环会很慢。
我们可以将您的问题分解为三个步骤:
> 2.5
。我们可以使用logical
向量生成一个布尔数组,该数组同时检查步骤#1和#2,以便我们可以索引到您指定的GPA数组。一旦我们这样做,我们只需将公式应用于过滤的GPA,然后总结花费的时间。因此,您的代码非常简单:
function [candidates_hire, time_spent] = CFRecruiter(names, GPAs, stays_to_talk)
%// Pre-processing - split up the names
candidates = strsplit(names, ', ');
%// Steps #1 and #2
filtered_candidates = GPAs > 2.5 & stays_to_talk;
%// Return candidates who are hired
candidates_hire = strjoin(candidates(filtered_candidates), ', ');
%// Step #3
time_spent = sum((GPAs(filtered_candidates) - 2.5) * 4);
您有正确的想法根据逗号分割名称。 strsplit
将包含您正在查找的令牌(在您的情况下为,
)的字符串拆分为单元格数组中的单独字符串。因此,您将获得一个单元格数组,其中每个元素都具有要访问的人员的姓名。现在,我将步骤#1和#2合并为一个步骤,我计算出一个逻辑向量,告诉您哪些候选符合要求。然后我使用它来索引我们的候选单元格数组,然后使用strjoin
将所有名称连接在一个字符串中,其中每个名称按照示例输出以,
分隔。
最后一步是使用逻辑向量索引GPAs向量,从那些成功的候选者中获取GPA,然后将公式应用于每个元素并总结它们。有了这个,这里是使用您的样本输入的结果:
>> [Names, Time] = CFRecruiter('Jack, Rose, Tom', [3.9, 2.3, 3.3],...
[false true true])
Names =
Tom
Time =
3.2000
>> [Names, Time] = CFRecruiter('Vatech, George Burdell, Barnes Noble',...
[4.0, 2.5, 3.6], [true true true])
Names =
Vatech, Barnes Noble
Time =
10.4000
现在,如果您绝对不情愿使用for
循环,我们可以使用循环和if
条件替换步骤#1和#2,以及保持计数器追踪到目前为止所花费的总时间。我们还需要一个额外的单元阵列来跟踪那些已经通过要求的名称。就这样:
function [candidates_hire, time_spent] = CFRecruiter(names, GPAs, stays_to_talk)
%// Pre-processing - split up the names
candidates = strsplit(names, ', ');
final_names = [];
time_spent = 0;
for idx = 1 : length(candidates)
%// Steps #1 and #2
if GPAs(idx) > 2.5 && stays_to_talk(idx)
%// Step #3
time_spent = time_spent + (GPAs(idx) - 2.5)*4;
final_names = [final_names candidates(idx)];
end
end
%// Return candidates who are hired
candidates_hire = strjoin(final_names, ', ');
上面代码的诀窍在于我们保留了一个额外的单元格数组,用于存储那些已经通过的候选项。然后,我们将加入所有字符串,并在每个名称之间加上,
,就像我们之前一样。您还会注意到检查两种方法之间的步骤#1和#2存在差异。特别是,第一种方法中有&
,第二种方法中有&&
。单&
用于数组和矩阵,而&&
用于单个值。如果你不知道那个符号是什么,那就是logical
AND的符号。这意味着只有当&
的左侧和&
的右侧都为真时,才会出现这种情况。在您的情况下,这意味着,如果要雇用GPA为> 2.5
且保持谈话的人必须都是真的。