July 10, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to okibi | okibi wrote: > I couldn't get your function to compile. I get the following error: > > Error: need 'this' to access member getNumericPart > > On the line: > > return getNumericPart(a)>getNumericPart(b); > > Any ideas? That's odd. Try this instead, maybe there's a conflict with the sort attribute. sort(array, function(char[] a, char[] b) { return getNumericPart(a)>getNumericPart(b); }); |
July 10, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | Same issue.
torhu Wrote:
> okibi wrote:
> > I couldn't get your function to compile. I get the following error:
> >
> > Error: need 'this' to access member getNumericPart
> >
> > On the line:
> >
> > return getNumericPart(a)>getNumericPart(b);
> >
> > Any ideas?
>
> That's odd. Try this instead, maybe there's a conflict with the sort attribute.
>
> sort(array, function(char[] a, char[] b) {
> return getNumericPart(a)>getNumericPart(b);
> });
|
July 11, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to okibi | okibi wrote:
> Well, the following comment made it seem like it won't work:
>
>>> // comparing sorting algorithm goes here. See wikipedia for examples.
>>> // Quicksort should do nicely and is easy to implement.
Oops, sorry, yeah that code isn't using the builtin array sort operation.
import std.c.stdlib;
and you should be able to call the C qsort() function. That can be a bit of a nightmare in itself so give it a go and post if you have trouble.
Regan
|
July 11, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to okibi | okibi wrote: > I couldn't get your function to compile. I get the following error: > > Error: need 'this' to access member getNumericPart > > On the line: > > return getNumericPart(a)>getNumericPart(b); > > Any ideas? > > downs Wrote: > > >>okibi wrote: >> >>>Is there an easy way to sort an array with elements such as "12 - Some text" or "241 - Other Text"? >>> >>>I want to sort in order of the numbers. Is this possible? >>> >>>Thanks! >> >>// Sort array via comparison operator. >>// 'bigger' returns if 'value' is bigger than 'than'. >>void sort(T)(ref T[] array, bool function(T value, T than) bigger) { >> // comparing sorting algorithm goes here. See wikipedia for examples. >> // Quicksort should do nicely and is easy to implement. >>} >> >>long getNumericPart(char[] inp) { >> if (!input.length) return long.max+1; // no number is very small. >> size_t numlen=0; >> while (numlen<inp.length)&&(inp[numlen]>='0')&&(inp[numlen]<='9')) >> ++numlen; >> return inp[0..numlen]; >>} >> >>void main() { >> char[][] array=getArray(); // array is read >> array.sort(function(char[] a, char[] b) { >> return getNumericPart(a)>getNumericPart(b); >> }); >>} >> >>Didn't try, obviously, but it should work. >>Have fun! :D >> --downs > > I think the problem is that getNumericPart is outside the scope of that function literal, so it needs a context to access it. That's a screw-up on GDC/DMD's part though, since global functions should be unambiguous. void main() { char[][] array=getArray(); // array is read array.sort(function(char[] a, char[] b) { long getNumericPart(char[] inp) { if (!input.length) return long.max+1; // no number is very small. size_t numlen=0; while (numlen<inp.length)&&(inp[numlen]>='0')&&(inp[numlen]<='9')) ++numlen; return inp[0..numlen]; } return getNumericPart(a)>getNumericPart(b); }); } should work. Oh also, here's quicksort ^^ /* From Wikipedia function partition(array, left, right, pivotIndex) pivotValue := array[pivotIndex] swap( array, pivotIndex, right) // Move pivot to end storeIndex := left for i from left to right-1 if array[i] <= pivotValue swap( array, storeIndex, i) storeIndex := storeIndex + 1 swap( array, right, storeIndex) // Move pivot to its final place return storeIndex */ void swap(ref T a, ref T b) { T c=a; a=b; b=c; } size_t partition(T)(T[] array, size_t left, size_t right, size_t pivotIndex, bool function(T a, T than) comp) { auto pivotValue=array[pivotIndex]; swap(array[pivotIndex], array[right]); // move pivot to end auto storeIndex=left; foreach (inout value; array[left..right]) { if (!comp(value, pivotValue)) swap(array[storeIndex++], value); swap(array[right], array[storeIndex]); // move pivot to its final place return storeIndex; } /* Actual algorithm from Wikipedia function quicksort(array, left, right) if right > left select a pivot index (e.g. pivotIndex = left) pivotNewIndex := partition(array, left, right, pivotIndex) quicksort(array, left, pivotNewIndex-1) quicksort(array, pivotNewIndex+1, right) */ import std.random; void quicksort(T)(T[] array, size_t left, size_t right, bool function(T a, T than) comp) { if (right>left) { // select random pivot index size_t pivotIndex=rand%(right-left)+left; auto pivotNewIndex=array.partition(left, right, pivotIndex, comp); array.quicksort(left, pivotNewIndex-1, comp); array.quicksort(pivotNewIndex+1, right, comp); } I didn't test it, but it should work. ... I hope. Good luck! :D --downs |
July 11, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to okibi | okibi skrev: > This does seem like the best way, but I'm not sure how I would go about implement Quicksort into that code. Could you please give me some pointers? http://www.csc.kth.se/~ol/array.d http://www.csc.kth.se/~ol/array.html contains a quicksort implementation like that. -- Oskar |
July 11, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | > void swap(ref T a, ref T b) { T c=a; a=b; b=c; }
Oopsie. Should be void swap(T)(ref T a, ref T b)
|
July 11, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | Thanks! I got it working now and have a better understanding of how arrays work.
Thanks for everyone's help!
downs Wrote:
> > void swap(ref T a, ref T b) { T c=a; a=b; b=c; }
> Oopsie. Should be void swap(T)(ref T a, ref T b)
|
July 11, 2007 Re: Sorting an Array | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | torhu wrote:
> okibi wrote:
>> This does seem like the best way, but I'm not sure how I would go about implement Quicksort into that code. Could you please give me some pointers?
>
> I often use C's quicksort, found in std.c.stdlib.
>
> void sort(T)(T[] array, bool function(T a, T b) compare) {
>
> // wrap compare in a C function
> static extern(C) int cmp(void* a, void* b) {
> return compare(*cast(T*)a, *cast(T*)b);
> }
>
> qsort(array.ptr, array.length, array[0].sizeof, &cmp);
> }
>
> compare has to return a negative number if a is smaller, positive is b is smaller, or zero if they are equal.
Someone pointed out that this example doesn't work, since cmp can't access sort's arguments directly. So I had to fix it. cmp could obviously call compare through a local, static pointer, but for performance reasons I made qsort call the comparison function directly. A quick test showed that this matters a whole lot in this case.
This code is tested, no worries.
---
import std.c.stdlib;
import std.stdio;
extern (C) void sort(T)(T[] array, int function(T* a, T* b) compare)
{
alias extern (C) int function (void* a, void* b) ftype;
qsort(array.ptr, array.length, array[0].sizeof, cast(ftype)compare);
}
extern(C) int compareInts(int* a, int* b) {
return *a - *b;
}
void main()
{
int[] a = [3, 14, 1];
a.sort(&compareInts);
writefln(a); // prints '[1,3,14]'
}
---
|
Copyright © 1999-2021 by the D Language Foundation