Scilab Bag Of Tricks: The Scilab-2.5.x IAQ (Infrequently Asked Questions) | ||
---|---|---|
Prev | Chapter 10. Complete Examples | Next |
listdiff returns the differences of two vectors in the style of the diff(1) command. It is a funny example of doing something completely non-numerical with Scilab.
function diff = listdiff(lst1, lst2, equ) // listdiff() implements a diff(1) like Scilab-function // for vectors. // The caller can supply a boolean equ(x, y) function // that will be used in all comparisons, otherwise // operator '==' is used. // // RETURN VALUE // 2-column vector describing the differences. // Column 1 contains the element and column 2 // the element's index. A '+' in front of the // index means: 'Extra element in lst2', a '-' // means missing element in lst1. // // AUTHOR // Christoph L. Spiel // // Copyright 1999, 2000 by Christoph Spiel // listdiff is free software distributed under the terms // of the GNU General Public License, version 2. //! [nl, nr] = argn(0); select nr case 0 then error('Too few arguments. Got 0, require 2 or 3.'); case 1 then error('Too few arguments. Got 1, require 2 or 3.'); case 2 then deff('b = equ(s1, s2)', 'b = s1 == s2'); case 3 then // caller supplied equ() if type(equ) ~= 13 then error('Function expected, got a ' + typeof(equ) + '.'); end else error('Too many arguments. Got ' + string(nr) + ' require 2 or 3.'); end if type(lst1) ~= 1 & type(lst2) ~= 1 then // none of the lists is empty if type(lst1) ~= type(lst2) then error('Both lists must be of the same type, or be empty.'); end end fuzz = 10; diff = []; n1 = size(lst1, 1); n2 = size(lst2, 1); // special cases if n1 == 0 & n2 == 0, return, end if n1 == 0 then p = 1 : n2; diff = [lst2, '+' + string(p')]; return; end if n2 == 0 then p = 1 : n1; diff = [lst1, string(-p')]; return; end // general case (neither list is empty) i = 1; j = 1; while i <= n1 & j <= n2 while i <= n1 & j <= n2 if ~equ(lst1(i), lst2(j)), break, end i = i + 1; j = j + 1; end if i >= n1 | j >= n2, break, end icurs = i; while icurs <= min(n1, i+fuzz) if equ(lst1(icurs), lst2(j)), break, end icurs = icurs + 1; end if icurs <= n1 then if equ(lst1(icurs), lst2(j)) then // record element(s) missing from lst1 for p = i : icurs-1 this_diff = [lst1(p), string(-p)]; diff = [diff; this_diff]; end // re-sync i = icurs; end end jcurs = j; while jcurs <= min(n2, j+fuzz) if equ(lst1(i), lst2(jcurs)), break, end jcurs = jcurs + 1; end if jcurs <= n2 then if equ(lst1(i), lst2(jcurs)) then // record extra element(s) in lst2 for p = j : jcurs-1 this_diff = [lst2(p), '+' + string(p)]; diff = [diff; this_diff]; end // re-sync j = jcurs; end end end