Re: Ordenacion de arrays.
Posted in 1998
Jonathan Leffler wrote: > > On Tue, 13 Oct 1998, Juan Manuel Hernandez del Olmo wrote: > > Ordenacion de arrays. > > Necesitaria una funcion para ordenar los elementos de un array en 4GL. > > My Spanish isn't all that good (it's more like non-existent), but I'm > guessing you are asking for a function to sort the elements of an array > in I4GL. > > It isn't particularly easy to do; it is virtually impossible to write a > generic routine to sort the data. Because you can't pass arrays around, > they have to be module or global variables. You can find all sorts of > sorting algorithms in books; which one is sensible depends on how big the > arrays are (number of elements), the size of each element, the complexity > of the comparison, and on whether the sort needs to be stable or not. > When designing the comparison, don't forget to handle nulls sensibly. > > If you are dealing with a few tens of elements and the arrays are of > integers, then it is all pretty simple and even a bubble sort will do. > If you are dealing with thousands of elements and each element is a > 2 kB record and the sort criterion has 6 fields to be compared, then > it is rather important to keep both the number of moves and the number > of comparisons down -- and a bubble sort is probably not appropriate. > > > MUCHAS GRACIAS. > > Try: "Programming Pearls" and "More Programming Pearls" by Jon Bentley, > or consider Knuth Volume 3 "Sorting and Searching", or Sedgewick's > "Algorithms in X" (pick your language other than I4GL) books. Or any > half-way decent algorithms book; even K&R "The C Programming Language" > contains a shell sort which is reasonable for many applications. > > Yours, > Jonathan Leffler (jleffler@informix.com) #include <witticism.h> > Guardian of DBD::Informix v0.60 -- http://www.perl.com/CPAN > Informix IDN for D4GL & Linux -- http://www.informix.com/idn I attach a 4GL function of mine which includes a shellsort. I would not recommend a bubblesort under any circumstances. It runs very slowly. The simpler insertion sort (the way you sort a hand of cards) is superior in every way if you need a simple algorithm. Shellsort is a good general-purpose algorithm and is suitable for 4GL. Quicksort would be tricky in 4GL. An alternative would be to write the array out to a temporary table (with CREATE TEMP TABLE then INSERT) and use SELECT ... ORDER BY .... This would be seriously slower. ---------------- cut here ---------------------- { ----------------------------------------------------------------------------- pickitem - pick a file or directory returns directory name only called by - getfile only pre - int_flag = 0 side-effects - can change current directory note - could do this with a load into a temporary file followed by display use F3 to mark the files for multiple delete - need flag to allow multiple ----------------------------------------------------------------------------- } function pickitem(pickmode) define pickmode char(1) -- r=readable file, w=writeable file, d=dir define nfiles integer define picklist array[1000] of char(18) define pickname char(128) define i,j,h integer -- shellsort variables define v char(18) -- shellsort variable open window w_picklist at 6,58 -- fits with 2 at left, 1 at bottom with form "pickfile" attribute(border, form line first+1) -- read files/directories case (pickmode) when "d" display " Directories " at 1,1 attribute(reverse) when "r" display " Readable files " at 1,1 attribute(reverse) when "w" display " Writeable files " at 1,1 attribute(reverse) end case message " Wait ..." let status = open_dir(dirname clipped, pickmode) for nfiles = 1 to 1000 let picklist[nfiles] = read_dir() if (picklist[nfiles] is NULL) then let nfiles = nfiles - 1 exit for end if end for -- sort the array with shellsort (half time of insertion sort on 180 files) -- p98 in Algorithms by R Sedgewick, Addison-Wesley 1983, ISBN 0-201-06672-6 let h = 1 while (h <= nfiles) -- repeat h=3*h+1 until h>N let h = 3 * h + 1 end while while (h > 1) -- repeat ... until h==1 let h = h / 3 for i = h + 1 to nfiles let v = picklist[i] let j = i while (picklist[j-h] > v) let picklist[j] = picklist[j-h] let j = j - h if (j <= h) then -- not in algorithm, see text goto shell0 end if end while label shell0: let picklist[j] = v end for end while -- pick from list call set_count(nfiles) message " RETURN to select " attribute(reverse) call set_options_list() display array picklist to a_pickfile.* on key(F1) call showhelp(760) end display call set_options_input() if (int_flag or nfiles = 0) then initialize pickname to NULL else let nfiles = arr_curr() let pickname = picklist[nfiles] end if -- directory processing if (pickmode = "d") then let dirname = joinpath(dirname, pickname) let pickname = dirname end if let int_flag = 0 close window w_picklist return (pickname clipped) end function ---------------- cut here ---------------------- -- Peter Lancashire Information Systems Specialist, Bayer plc Eastern Way, Bury St Edmunds, Suffolk, IP32 7AH, UK Tel: +44-1635-562258, Fax: +44-1635-562281 --- If all else fails, read the instructions and the release notes. Join Infuse, the UK Informix User Group at http://www.infuse.org.uk/ ---