Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 16:29 04 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MM2: Sorting fast with a CFunction

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 02:22am 19 Jan 2015
Copy link to clipboard 
Print this post

Inspired by factus10's thread I decided to create a simple cFunction sort which hopefully is generally useful.

I'm using a shell sort - code cribbed from rosettacode.org

The test script uses the large font table to create a test set of 1020 integers including negative numbers and 255 duplicates.

The cFunction returns in about 10msecs with a perfectly sorted result.

NOTE this code only runs correctly with firmware version 4.6A

In version 4.6 the sort works correctly but the test incorrectly reports errors as there is a bug in 4.6 relating to comparing integers > 30-bits long


option default integer
option explicit
dim integer test(1019)
dim integer i,j,l,k=peek(cfunaddr font)
for i=0 to 254 ' use
test(i)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)
test(i+255)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)+2
test(i+510)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)+2 'create lots of duplicates
test(i+765)= -(peek(word k+I*8)+(peek(word k+4+I*8)<<32)) 'create negative numbers
next i
timer=0
j=shellsort(test(),1020)
print "Time taken=",timer," msec"
j=&H8000000000000000 'maximum negative number possible
l=&H7FFFFFFFFFFFFFFF 'maximum positive number possible
test(512)=l ' create a spurious error
for i=0 to 1019
if test(i)<j then
if j=l then
print "Test error found", test(i),"<",j
else
print "ERROR!!!!!!!!!!!!", test(i),"<",j
endif
endif
j=test(i)
next i


'long long shellsort (long long a[], long long *nn) {
' long h, l, j, n=*nn;
' long long k;
' for (h = n; h /= 2;) {
' for (l = h; l < n; l++) {
' k = a;
' for (j = l; j >= h && k < a[j - h]; j -= h) {
' a[j] = a[j - h];
' }
' a[j] = k;
' }
' }
' return 0;
'}
CFunction shellsort
00000000
27bdfff8 afb10004 afb00000 8cad0000 10000032 01a01021 8df10000 8dea0004
01c2282a 14a00022 01c01821 03201821 8f060004 0146282a 14a00005 8f080000
14ca001a 0228282b 50a00019 01c01821 02002821 10000003 01c03821 00603821
01201821 000738c0 00873821 ace80000 ace60004 0062302a 14c0000d 006b4821
8ca80000 8ca60004 0146382a 14e0fff3 00ac2821 14ca0006 0228382b 14e0fff0
00603821 10000003 000318c0 01c01821 000318c0 00831821 ac710000 ac6a0004
25ce0001 27390001 25ef0008 27180008 01cd182a 1460ffd0 26100008 00021fc2
00621021 00021043 1040000e 004d182a 1060fffb 00021fc2 000278c0 008f7821
0080c021 00028023 001080c0 02006021 00908021 00407021 0000c821 1000ffbe
00025823 00001021 00001821 8fb10004 8fb00000 03e00008 27bd0008
End CFunction
'
CFunction font
00000000
00000000 00000000 4f5b3e00 00003e5b 4f6b3e00 00003e6b 7c3e1c00 00001c3e
7e3c1800 0000183c 7d571c00 00001c57 7f5e1c00 00001c5e 3c180000 00000018
c3e7ff00 0000ffe7 24180000 00000018 dbe7ff00 0000ffe7 3a060e00 00003048
79292600 00002629 05050700 0000407f 05253f00 0000407f e73c5a00 00005a3c
1c1c0800 00007f3e 1c3e7f00 0000081c 7f221400 00001422 005f5f00 00005f5f
7f017f00 00000609 89956a00 00000066 60606000 00006060 ffa29400 000094a2
7e040800 00000804 7e201000 00001020 2a1c0800 00000808 2a080800 0000081c
10101000 00001e10 0c1e0c00 00000c1e 3e383000 00003038 3e0e0600 0000060e
00000000 00000000 5f000000 00000000 00070000 00000007 147f1400 0000147f
7f2a1200 0000242a 08646200 00002313 56205000 00003649 07030000 00000008
22410000 0000001c 221c0000 00000041 7f1c2a00 00002a1c 3e080800 00000808
70300000 00000080 08080800 00000808 60600000 00000000 08040200 00002010
49453e00 00003e51 7f400000 00000042 49494600 00007249 494d3300 00002141
127f1000 00001814 45453900 00002745 49493100 00003c4a 11090700 00004121
49493600 00003649 49291e00 00004649 14000000 00000000 34000000 00000040
14224100 00000008 14141400 00001414 22140800 00000041 59090600 00000201
5d594e00 00003e41 11127c00 00007c12 49493600 00007f49 41412200 00003e41
41413e00 00007f41 49494100 00007f49 09090100 00007f09 41517300 00003e41
08087f00 00007f08 7f410000 00000041 413f0100 00002040 14224100 00007f08
40404000 00007f40 1c027f00 00007f02 08107f00 00007f04 41413e00 00003e41
09090600 00007f09 51215e00 00003e41 19294600 00007f09 49493200 00002649
7f010300 00000301 40403f00 00003f40 40201f00 00001f20 38403f00 00003f40
08146300 00006314 78040300 00000304 494d4300 00006159 41414100 0000007f
08102000 00000204 41417f00 00000041 01020400 00000402 40404000 00004040
07080000 00000003 54784000 00002054 44443800 00007f28 44442800 00003844
44287f00 00003844 54541800 00003854 7e090200 00000008 a49c7800 000018a4
04047800 00007f08 7d400000 00000044 403d0000 00002040 28440000 00007f10
7f400000 00000041 78047800 00007c04 04047800 00007c08 44443800 00003844
24241800 0000fc18 2418fc00 00001824 04040800 00007c08 54542400 00004854
3f442400 00000404 40207c00 00003c40 40201c00 00001c20 30403c00 00003c40
10284400 00004428 90907c00 00004c90 544c4400 00004464 36410000 00000008
77000000 00000000 36080000 00000041 02040200 00000201 23263c00 00003c26
a1611200 00001ea1 40207a00 00003a40 54555900 00003854 55794100 00002155
54784200 00002254 54784000 00002155 55794000 00002054 52721200 00000c1e
55555900 00003955 54545900 00003954 54545800 00003955 457c4100 00000000
457d4200 00000002 457c4000 00000001 11127d00 00007d12 2528f000 0000f028
55450000 00007c54 547c5400 00002054 097f4900 00007c0a 49493200 00003249
44443a00 00003a44 48483000 0000324a 41217a00 00003a41 40207800 00003a42
a0a07d00 0000009d 42423d00 00003d42 40403d00 00003d40 ff242400 00003c24
49436600 0000487e fc2f2b00 00002b2f 29f62000 0000ff09 7e090300 0000c088
54794100 00002054 447d4100 00000000 484a3200 00003048 40227a00 00003840
0a0a7200 0000007a 19317d00 00007d0d 292f2800 00002629 29292600 00002629
4d402000 00003048 08080800 00003808 08083800 00000808 c8acba00 00002f10
2834fa00 00002f10 7b000000 00000000 2a142200 00000814 2a140800 00002214
5500aa00 0000aa00 aa55aa00 0000aa55 00ff0000 00000000 10ff0000 00001010
14ff0000 00001414 ff00ff00 00001010 f010f000 00001010 14fc0000 00001414
f700ff00 00001414 ff00ff00 00000000 f404fc00 00001414 17101f00 00001414
1f101f00 00001010 141f0000 00001414 10f00000 00001010 001f1000 00000000
101f1000 00001010 10f01000 00001010 00ff1000 00000000 10101000 00001010
10ff1000 00001010 00ff1400 00000000 ff00ff00 00000000 1f101700 00000000
fc04f400 00000000 17101700 00001414 f404f400 00001414 ff00f700 00000000
14141400 00001414 f700f700 00001414 14171400 00001414 1f101f00 00001010
14f41400 00001414 f010f000 00001010 1f101f00 00000000 001f1400 00000000
00fc1400 00000000 f010f000 00000000 ff10ff00 00001010 14ff1400 00001414
101f0000 00001010 00f01000 00000000 ffffff00 0000ffff f0f0f000 0000f0f0
ff000000 0000ffff 00ffff00 00000000 0f0f0f00 00000f0f 44384400 00003844
4a4a3400 0000fc4a 02060600 00007e02 027e0200 0000027e 49416300 00006355
443c0400 00003844 201e2000 0000407e 7e020200 00000602 e7a59900 000099a5
492a1c00 00001c2a 01724c00 00004c72 4d4d3000 0000304a 78483000 00003048
5a463d00 0000bc62 49490000 00003e49 01017e00 00007e01 2a2a2a00 00002a2a
5f444400 00004444 4a444000 00004051 4a514000 00004044 ff010300 00000000
ff000000 0000e080 6b6b0800 00000808 36243600 00003612 090f0600 0000060f
18180000 00000000 10100000 00000000 ff010100 00003040 01011e00 0000001f
1d171200 00000019 3c3c3c00 0000003c 00000000 00000000
End CFunction

Edited by matherp 2015-01-20
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 724
Posted: 11:38am 19 Jan 2015
Copy link to clipboard 
Print this post

Hi, i miss the Ccode;-)..
THX
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 11:51am 19 Jan 2015
Copy link to clipboard 
Print this post

In the comments
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 01:01pm 19 Jan 2015
Copy link to clipboard 
Print this post

That is brilliant. Do you mind if I add it to the standard Micromite distribution zip?

Geoff
Geoff Graham - http://geoffg.net
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 01:49pm 19 Jan 2015
Copy link to clipboard 
Print this post

  Quote  Do you mind if I add it to the standard Micromite distribution zip?


Of course, no problem

 
factus10
Regular Member

Joined: 30/12/2014
Location: United States
Posts: 45
Posted: 01:59pm 19 Jan 2015
Copy link to clipboard 
Print this post

Very nice!

You might want to give the comb sort a go too. I used code from rosettacode for the version I implemented in 4.5

David
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 04:29pm 19 Jan 2015
Copy link to clipboard 
Print this post

Have you thought of a string sort?
That would be useful also.

Geoff
Geoff Graham - http://geoffg.net
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 10:45pm 19 Jan 2015
Copy link to clipboard 
Print this post

  Quote  Have you thought of a string sort?


What does it do?
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1568
Posted: 12:48am 20 Jan 2015
Copy link to clipboard 
Print this post

Good job!

  matherp said  
  Quote  Have you thought of a string sort?


What does it do?


sorting strings (sequences of characters)?

IMHO comb sort seems to be more efficient than shell sort.

Regards
MichaelEdited by twofingers 2015-01-21
causality ≠ correlation ≠ coincidence
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 02:18am 20 Jan 2015
Copy link to clipboard 
Print this post

11msec for comb, 10 for shell, but presumably data dependent.

Still unsure of the objective of string sort, do you want to know "fred" is greater than "bert" or sort the letters inside a string? Is "small" bigger then "smaller"? What is it for? I need a proper spec


option default integer
option explicit
dim integer test(1019)
dim integer i,j,l,k=peek(cfunaddr font)
for i=0 to 254 ' use
test(i)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)
test(i+255)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)+2
test(i+510)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)+2 'create lots of duplicates
test(i+765)= -(peek(word k+I*8)+(peek(word k+4+I*8)<<32)) 'create negative numbers
next i
timer=0
j=shellsort(test(),1020)
print "Time taken=",timer," msec"
j=&H8000000000000000 'maximum negative number possible
l=&H7FFFFFFFFFFFFFFF 'maximum positive number possible
test(512)=l ' create a spurious error
for i=0 to 1019
if test(i)<j then
if j=l then
print "Test error found", test(i),"<",j
else
print "ERROR!!!!!!!!!!!!", test(i),"<",j
endif
endif
j=test(i)
next i
for i=0 to 254 ' use
test(i)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)
test(i+255)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)+2
test(i+510)=peek(word k+I*8)+(peek(word k+4+I*8)<<32)+2 'create lots of duplicates
test(i+765)= -(peek(word k+I*8)+(peek(word k+4+I*8)<<32)) 'create negative numbers
next i
timer=0
j=Combsort11(test(),1020)
print "Time taken=",timer," msec"
j=&H8000000000000000 'maximum negative number possible
l=&H7FFFFFFFFFFFFFFF 'maximum positive number possible
test(512)=l ' create a spurious error
for i=0 to 1019
if test(i)<j then
if j=l then
print "Test error found", test(i),"<",j
else
print "ERROR!!!!!!!!!!!!", test(i),"<",j
endif
endif
j=test(i)
next i
end


'long long combsort(long long a[], long long *nn)
'{
' long l, j, gap, swapped = 1,nElements=*nn;
' long long temp;
'
' gap = nElements;
' while (gap > 1 || swapped == 1)
' {
' gap = gap * 10 / 13;
' if (gap == 9 || gap == 10) gap = 11;
' if (gap < 1) gap = 1;
' swapped = 0;
' for (l = 0, j = gap; j < nElements; l++, j++)
' {
' if (a > a[j])
' {
' temp = a;
' a = a[j];
' a[j] = temp;
' swapped = 1;
' }
' }
' }
'}

'long long shellsort (long long a[], long long *nn) {
' long h, l, j, n=*nn;
' long long k;
' for (h = n; h /= 2;) {
' for (l = h; l < n; l++) {
' k = a;
' for (j = l; j >= h && k < a[j - h]; j -= h) {
' a[j] = a[j - h];
' }
' a[j] = k;
' }
' }
' return 0;
'}


CFunction combsort
00000000
8ca30000 00603821 24080001 24050001 1000002c 2402000d 000738c0 00c73021
00c2001a 004001f4 00004012 2508fff7 2d080002 15000004 00003812 0007302a
10000002 00a6380a 2407000b 00e3302a 10c0001c 00004021 00804821 000730c0
00863021 00e05021 01207021 8d380000 8d2b0004 00c06821 8ccc0004 018b782a
15e00006 8cd90000 556c000a 254a0001 0338782b 51e00007 254a0001 add90000
adcc0004 adb80000 adab0004 00a04021 254a0001 25290008 0143582a 1560ffea
24c60008 28e60002 10c0ffd3 00073040 1105ffd2 000738c0 03e00008 00000000
End CFunction
'
CFunction shellsort
00000000
27bdfff8 afb10004 afb00000 8cad0000 10000032 01a01021 8df10000 8dea0004
01c2282a 14a00022 01c01821 03201821 8f060004 0146282a 14a00005 8f080000
14ca001a 0228282b 50a00019 01c01821 02002821 10000003 01c03821 00603821
01201821 000738c0 00873821 ace80000 ace60004 0062302a 14c0000d 006b4821
8ca80000 8ca60004 0146382a 14e0fff3 00ac2821 14ca0006 0228382b 14e0fff0
00603821 10000003 000318c0 01c01821 000318c0 00831821 ac710000 ac6a0004
25ce0001 27390001 25ef0008 27180008 01cd182a 1460ffd0 26100008 00021fc2
00621021 00021043 1040000e 004d182a 1060fffb 00021fc2 000278c0 008f7821
0080c021 00028023 001080c0 02006021 00908021 00407021 0000c821 1000ffbe
00025823 00001021 00001821 8fb10004 8fb00000 03e00008 27bd0008
End CFunction
'
CFunction font
00000000
00000000 00000000 4f5b3e00 00003e5b 4f6b3e00 00003e6b 7c3e1c00 00001c3e
7e3c1800 0000183c 7d571c00 00001c57 7f5e1c00 00001c5e 3c180000 00000018
c3e7ff00 0000ffe7 24180000 00000018 dbe7ff00 0000ffe7 3a060e00 00003048
79292600 00002629 05050700 0000407f 05253f00 0000407f e73c5a00 00005a3c
1c1c0800 00007f3e 1c3e7f00 0000081c 7f221400 00001422 005f5f00 00005f5f
7f017f00 00000609 89956a00 00000066 60606000 00006060 ffa29400 000094a2
7e040800 00000804 7e201000 00001020 2a1c0800 00000808 2a080800 0000081c
10101000 00001e10 0c1e0c00 00000c1e 3e383000 00003038 3e0e0600 0000060e
00000000 00000000 5f000000 00000000 00070000 00000007 147f1400 0000147f
7f2a1200 0000242a 08646200 00002313 56205000 00003649 07030000 00000008
22410000 0000001c 221c0000 00000041 7f1c2a00 00002a1c 3e080800 00000808
70300000 00000080 08080800 00000808 60600000 00000000 08040200 00002010
49453e00 00003e51 7f400000 00000042 49494600 00007249 494d3300 00002141
127f1000 00001814 45453900 00002745 49493100 00003c4a 11090700 00004121
49493600 00003649 49291e00 00004649 14000000 00000000 34000000 00000040
14224100 00000008 14141400 00001414 22140800 00000041 59090600 00000201
5d594e00 00003e41 11127c00 00007c12 49493600 00007f49 41412200 00003e41
41413e00 00007f41 49494100 00007f49 09090100 00007f09 41517300 00003e41
08087f00 00007f08 7f410000 00000041 413f0100 00002040 14224100 00007f08
40404000 00007f40 1c027f00 00007f02 08107f00 00007f04 41413e00 00003e41
09090600 00007f09 51215e00 00003e41 19294600 00007f09 49493200 00002649
7f010300 00000301 40403f00 00003f40 40201f00 00001f20 38403f00 00003f40
08146300 00006314 78040300 00000304 494d4300 00006159 41414100 0000007f
08102000 00000204 41417f00 00000041 01020400 00000402 40404000 00004040
07080000 00000003 54784000 00002054 44443800 00007f28 44442800 00003844
44287f00 00003844 54541800 00003854 7e090200 00000008 a49c7800 000018a4
04047800 00007f08 7d400000 00000044 403d0000 00002040 28440000 00007f10
7f400000 00000041 78047800 00007c04 04047800 00007c08 44443800 00003844
24241800 0000fc18 2418fc00 00001824 04040800 00007c08 54542400 00004854
3f442400 00000404 40207c00 00003c40 40201c00 00001c20 30403c00 00003c40
10284400 00004428 90907c00 00004c90 544c4400 00004464 36410000 00000008
77000000 00000000 36080000 00000041 02040200 00000201 23263c00 00003c26
a1611200 00001ea1 40207a00 00003a40 54555900 00003854 55794100 00002155
54784200 00002254 54784000 00002155 55794000 00002054 52721200 00000c1e
55555900 00003955 54545900 00003954 54545800 00003955 457c4100 00000000
457d4200 00000002 457c4000 00000001 11127d00 00007d12 2528f000 0000f028
55450000 00007c54 547c5400 00002054 097f4900 00007c0a 49493200 00003249
44443a00 00003a44 48483000 0000324a 41217a00 00003a41 40207800 00003a42
a0a07d00 0000009d 42423d00 00003d42 40403d00 00003d40 ff242400 00003c24
49436600 0000487e fc2f2b00 00002b2f 29f62000 0000ff09 7e090300 0000c088
54794100 00002054 447d4100 00000000 484a3200 00003048 40227a00 00003840
0a0a7200 0000007a 19317d00 00007d0d 292f2800 00002629 29292600 00002629
4d402000 00003048 08080800 00003808 08083800 00000808 c8acba00 00002f10
2834fa00 00002f10 7b000000 00000000 2a142200 00000814 2a140800 00002214
5500aa00 0000aa00 aa55aa00 0000aa55 00ff0000 00000000 10ff0000 00001010
14ff0000 00001414 ff00ff00 00001010 f010f000 00001010 14fc0000 00001414
f700ff00 00001414 ff00ff00 00000000 f404fc00 00001414 17101f00 00001414
1f101f00 00001010 141f0000 00001414 10f00000 00001010 001f1000 00000000
101f1000 00001010 10f01000 00001010 00ff1000 00000000 10101000 00001010
10ff1000 00001010 00ff1400 00000000 ff00ff00 00000000 1f101700 00000000
fc04f400 00000000 17101700 00001414 f404f400 00001414 ff00f700 00000000
14141400 00001414 f700f700 00001414 14171400 00001414 1f101f00 00001010
14f41400 00001414 f010f000 00001010 1f101f00 00000000 001f1400 00000000
00fc1400 00000000 f010f000 00000000 ff10ff00 00001010 14ff1400 00001414
101f0000 00001010 00f01000 00000000 ffffff00 0000ffff f0f0f000 0000f0f0
ff000000 0000ffff 00ffff00 00000000 0f0f0f00 00000f0f 44384400 00003844
4a4a3400 0000fc4a 02060600 00007e02 027e0200 0000027e 49416300 00006355
443c0400 00003844 201e2000 0000407e 7e020200 00000602 e7a59900 000099a5
492a1c00 00001c2a 01724c00 00004c72 4d4d3000 0000304a 78483000 00003048
5a463d00 0000bc62 49490000 00003e49 01017e00 00007e01 2a2a2a00 00002a2a
5f444400 00004444 4a444000 00004051 4a514000 00004044 ff010300 00000000
ff000000 0000e080 6b6b0800 00000808 36243600 00003612 090f0600 0000060f
18180000 00000000 10100000 00000000 ff010100 00003040 01011e00 0000001f
1d171200 00000019 3c3c3c00 0000003c 00000000 00000000
End CFunction
Edited by matherp 2015-01-21
 
factus10
Regular Member

Joined: 30/12/2014
Location: United States
Posts: 45
Posted: 02:42am 20 Jan 2015
Copy link to clipboard 
Print this post

Most folks want to be able to sort an array of strings, to put the items in the array in alpha (or inverse) order.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 02:51am 20 Jan 2015
Copy link to clipboard 
Print this post

Hi factus10

Still too many unknowns to code anything useful. What about upper and lower case? Sorting on ASCII code is easy but is it useful? And the string length question is still unclear.

 
factus10
Regular Member

Joined: 30/12/2014
Location: United States
Posts: 45
Posted: 03:28am 20 Jan 2015
Copy link to clipboard 
Print this post

Yep, true, lots of unknowns.

In my code, I changed the comparisons from numeric values to string values. I also added an option to make the string comparisons case insensitive. That's probably good enough for most folks.

I can definitely understand the desire to solve the problem once :)

Best,
David
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1568
Posted: 03:39am 20 Jan 2015
Copy link to clipboard 
Print this post

@Peter

That was fast! Cool!

  Quote  What about upper and lower case?

I think the first thing we need is sorting on ASCII code. (MMBasic: "peter" > "Peter")

  Quote  Sorting on ASCII code is easy but is it useful?

Yes! But it is not the universal solution.

  Quote  And the string length question is still unclear.

The shorter strings should be first. (MMBasic: "Peter" is smaller than "Peters")
As in our telephone directory.

Regards
Michael
causality ≠ correlation ≠ coincidence
 
factus10
Regular Member

Joined: 30/12/2014
Location: United States
Posts: 45
Posted: 05:07am 20 Jan 2015
Copy link to clipboard 
Print this post

A simple comparison (strcmp(string1,string2)) will address string length.

Here's an example:
http://www.tutorialspoint.com/ansi_c/c_strcmp.htm
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 04:36pm 20 Jan 2015
Copy link to clipboard 
Print this post

And I think numerics come before alphas and non-alphanumerics come before numbers, like directory listings:

##@--
.
..
...
..00123456
..123456
0012346
01 Puff the magic dragon
Puff the magic dragon
Puff the #1 magic dragon

etc?

Greg
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 04:57pm 20 Jan 2015
Copy link to clipboard 
Print this post

Sorry, I have been away while this discussion continued and I should have been more specific in the first place.

I was thinking of sorting an array of strings. As it would be similar to a numeric sort it should be easy to do and would be another useful tool. Once you have a sorted array of strings you can do high speed binary searches, etc.

The syntax could be something like:
r = StringSort( ArrayOfStrings(), NbrOfStrings, MaxLengthOfString )

MMBasic stores arrays of strings in a similar fashion as arrays of integers and the CFunction would receive a pointer to the first byte of the first string in the array. The space allocated to each string defaults to 255 bytes but this can be changed with the LENGTH parameter in the DIM command. This is why I suggested the MaxLengthOfString parameter so that this info can be passed. Each string comes straight after the preceeding so you can step through the array using:
ptr = ptr + MaxLengthOfString


In MMBasic the actual length of the string is stored in the first byte and can range from zero to MaxLengthOfString. The 2nd, 3rd, etc bytes store the characters of the string.

Most string sorts treat upper case and lower case as different and I think that this would be sufficient. However, if you wanted to go overboard you could have a fourth parameter to the CFunction that would specify a case independent sort.

GeoffEdited by Geoffg 2015-01-22
Geoff Graham - http://geoffg.net
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 12:02am 21 Jan 2015
Copy link to clipboard 
Print this post

Geoff

If I have a string s$= "fred" length 10, can I assume anything about the contents of the 6 unused bytes or are these just going to contain whatever.

So if I then go s$="fr" do the 3rd and 4th bytes stay as "ed" and just the length get changed?

Peter
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 01:55am 21 Jan 2015
Copy link to clipboard 
Print this post

No, you cannot assume anything about the unused bytes, they contain junk.

As you said the 3rd and 4th bytes would hold whatever was left over from the previous contents but this is not guaranteed.

So, when you compare strings you must take into account the length stored in the first byte.

This is the code used in the MMBasic source:


// compare two MMBasic style strings
// returns 1 if s1 > s2 or 0 if s1 = s2 or -1 if s1 < s2
int Mstrcmp(unsigned char *s1, unsigned char *s2) {
register int i;
register unsigned char *p1, *p2;

// get the smaller length
i = *s1 < *s2 ? *s1 : *s2;

// skip the length byte and point to the char array
p1 = s1 + 1; p2 = s2 + 1;

// compare each char
while(i--) {
if(*p1 > *p2) return 1;
if(*p1 < *p2) return -1;
p1++; p2++;
}
// up to this point the strings matched
// make the decision based on which one is shorter
if(*s1 > *s2) return 1;
if(*s1 < *s2) return -1;
return 0;
}



Geoff
Geoff Graham - http://geoffg.net
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025