Solutions to review questions for Test 2B ------------------------------------------ 1. Longest function [len, ind] = longest(C) % Find the longest string(s) in cell array C. % C is an n-by-1 cell array of strings, n>=1. % len is the length of the longest string in C. % ind is a vector, possibly of length one, containing the index number(s) % of the string(s) with length len % len records the length of the longest string from C{1} to C{k} len = -1; % ind records indicies of strings whose lengths are len ind = []; for k=1:length(C) l = length(C{k}); if l == len ind = [ind k]; elseif l > len ind = k; len = l; end end 2. BigTriplets function N = BigTriplets(A) % Suppose A is a length-50 array of State objects with two properties. % Assume A(k).name is a string that names a state and A(k).pop % is an integer whose value is the states population. % We say that three different states form a "big triplet" if % the sum of their populations is greater than 15 million. % N is the number of big triplets. N = 0; for i=1:50 for j=i+1:50 for k=j+1:50 if A(i).pop+A(j).pop+A(k).pop > 15000000 N = N+1; end end end end 3. Above the median function C = topHalf(A) % A is a 1-d array of State objects; each object has two properties: name and pop. % A(k).name is a string that names a state. % A(k).pop is an integer whose value is the states population. % The states in A are ordered alphabetically by state name. % C is a 1-d cell array of strings that names all the states whose % populations are above the median state population. % The states should be ordered alphabetically in C. % % Do NOT use vectorized code. % % Hint: Function median returns the median value of a NUMERIC vector. % Build a numeric vector of the population and get the median value n= length(A); for k= 1:n p(k)= A(k).pop; end med= median(p); % Build cell array C, using the original order (alphabetical) in A count= 0; for k= 1:n if p(k)>med count= count + 1; C{count}= A(k).name; end end 4. Point class % Given an array of Point objects Pts where each object has two properties, % x and y, sort Pts so that the objects are in the order of % increasing distance from (0,0) n = length(Pts); % compute the distances dist = zeros(n, 1); for i=1:n dist(i)=sqrt(Pts(i).x^2+Pts(i).y^2); end % sort the distances [s, idx] = sort(dist); oldPts = Pts; for i=1:n Pts(i) = oldPts(idx(i)); end 5. Implement function partialStrings as specified. Do not use vectorized code. function M = partialStrings(CA, t) % CA is a length n cell array of "strings"; a "string" is a row char vector. % t is a positive integer. % M is an n-by-t matrix of characters: % Row r of M contains the first t characters of the rth char vector in CA. % If the rth char vector in CA is shorter than t, pad the char vector with '!'. % NO VECTORIZED CODE n= length(CA); M= char(zeros(n,t)); for r= 1:n len= length(CA{r}); for c= 1:t if c<=len M(r,c)= CA{r}(c); else M(r,c)= '!'; end end end 6. (a) Implement this function: function z = overlap(diskA, diskB) % z is 1 (true) if diskA and diskB overlap; otherwise z is 0 (false). % diskA and diskB are each a disk object with the following public properties: % x: x-coordinate of center of disk % y: y-coordinate of center of disk % radius: radius of disk dis = sqrt((diskA.x - diskB.x)^2 + (diskA.y - diskB.y)^2); if dis < diskA.radius + diskB.radius z = 1; else z = 0; end (b) Implement the following function to return the indices of disk triplets that overlap. Three disks form a triplet if every disk overlaps with each of the other two. Make effective use of function overlap from part (a). Your code should be efficient—avoid unnecessary iterations. function idx = diskTriplets(D) % D is a 1-d array of disk objects; each object has properties as defined in % part (a). Assume D has a length greater than 3. % idx is a vector of indices indicating all triplet overlap combinations. For example, % if disks 2, 4, and 5 form a triplet and disks 3, 4, and 6 form a triplet, idx % should be the vector [2 4 5 3 4 6]. Other orderings of triplets are acceptable, % however each triplet should only appear once. n = length(D); idx = []; for i = 1:n - 2 for j = i + 1:n - 1 for k = j + 1:n if overlap(D(i), D(j)) && ... overlap(D(j), D(k)) && overlap(D(i), D(k)) idx = [idx, i, j, k]; end end end end 7. (OOP) Refer to class Interval from Lecture 24. Implement the following function: function idxs = greatestOverlap(iArray) % Find the biggest pairwise overlap between Intervals in iArray. % iArray is an array of Interval references. iArray has a length greater than 1. % idxs is a vector of length 2 storing the indices of the two Intervals in % iArray that overlap the most. If there is not a pair of overlapping % Intervals in iArray, idxs is the empty vector. % Write efficient code: avoid unnecessary iteration. idxs= []; maxWidth= 0; % width of overlap n= length(iArray); for i= 1:n-1 for j= i+1:n olap= iArray(i).overlap(iArray(j)); if ~isempty(olap) && olap.getWidth()>maxWidth maxWidth= olap.getWidth(); idxs= [i j]; end end end 8. (OOP) Implement the following class as specified: classdef LengthUnit < handle % A LengthUnit represents a length (distance) in imperial units: feet and % inches. The values are non-negative and inches must be less than 12. properties feet % a non-negative integer value inches % a non-negative value end methods function L = LengthUnit(ft, in) % Constructor: Create a LengthUnit object with ft feet and in inches. % If one or both parameters are negative, halt the program and % display an error message. if nargin==2 if ft<0 || in<0 error('LengthUnit object must have non-negative properties') else % ft --> feet and inches L.inches= 12*(ft - floor(ft)); L.feet= floor(ft); % in --> feet and inches in2ft= floor(in/12); inRemaining= in - in2ft*12; L.feet= L.feet + in2ft; L.inches= L.inches + inRemaining; end end end function ft = inFeet(self) % self references a LengthUnit. ft is self represented in feet. ft= self.feet + self.inches/12; end function L = add(self, other) % self and other reference LengthUnits. L references a new % LengthUnit that is the sum of self and other. ft= self.feet + other.feet; in= self.inches + other.inches; L= LengthUnit(ft,in); end function yesno = isLongerThan(self, other) % self and other reference LengthUnits. yesno is true (1) if % self is longer than other; otherwise yesno is false (0). % For full credit, make effective use of method inFeet. yesno= self.inFeet() > other.inFeet(); end end %methods end %classdef 9. (OOP) Write a script that (a) generates 10 values, each uniformly random in (0,50). Let these random values be lengths in inches and use an array of LengthUnit objects to store these lengths. (b) determines which LengthUnits are shorter than or equal in length to the first LengthUnit in the array; display their indices and their lengths in feet. Make efficient use of available methods in class LengthUnit. %(a) n= 10; for k= 1:n inches= rand*50; array(k)= LengthUnit(0, inches); end %(b) idxs= []; for k= 2:n if array(1).isLongerThan(array(k)) idxs= [idxs k]; end end if isempty(idxs) disp('First LengthUnit is shortest of all LengthUnits have same length.') else disp(' Index Length') for k= 1:length(idxs) fprintf(' %4d %10f\n', idxs(k), array(idxs(k)).inFeet()) end end 10. Insight questions -------------------- % Sec 9.1 #4 function s = Compress(t) % t is a string % s is obtained by deleting all the blanks in t. % Thus, if t = 'ab cd efg ', the s should be assigned 'abcdef' s= ''; k= 0; for i= 1:length(t) if t(i)~=' ' k= k+1; s(k)= t(i); end end -------------------- % Sec 9.1 #7 function k = FindSubstring(S1, S2) %Find the first occurrence of string S1 in string S2. %If S1 is a substring of S2 then k is the position of the first % matching character of the first match in S2. %If s1 is not a substring of S2, then k is zero. len1 = length(S1); len2 = length(S2); lastPos2Check= len2-len1+1; k = 1; while k <= lastPos2Check && strcmp(S1, S2(k:k+len1-1))==0 k= k+1; end if k>lastPos2Check k= 0; end -------------------- % Sec 9.2 #5 function a = compare1(s1,s2) % s1 and s2 are strings % If s1 comes before or is equal to s2 in the ASCII dictionary order then a % is 1. otherwise, a is 0. Case is ignored. if (length(s1) < length(s2)) for i = 1:length(s2)-length(s1) s1 = [s1 ' ']; end end if (length(s2) < length(s1)) for i = 1:length(s1)-length(s2) s2 = [s2 ' ']; end end k = 1; while (k < length(s1)) && (s1(k) == s2(k)) k = k + 1; end if s1(k) <= s2(k) a = 1; else a = 0; end