There is no spoon
Difference between revisions of "UE3:Insertion Sort Macro"
From Unreal Wiki, The Unreal Engine Documentation Site
m |
(improved algorithm... now only needs 1 operator) |
||
(8 intermediate revisions by 2 users not shown) | |||
Line 18: | Line 18: | ||
* local int foo; | * local int foo; | ||
* `sort(myArray); | * `sort(myArray); | ||
− | * } | + | * } |
+ | * | ||
+ | * Alternatively you can use the sorting with an different compare | ||
+ | * operator using: `sort_op(Myarray, <) | ||
+ | * The second argument is the operator to use. | ||
* | * | ||
− | * This sorting mechanism works for all types for which there is a > | + | * This sorting mechanism works for all types for which there is a > |
− | * operator. This is the case for most primitive types in the | + | * operator. This is the case for most primitive types in the |
− | * For other types you need to declare the > operator yourself. | + | * UnrealEngine. For other types you need to declare the > operator |
+ | * yourself. | ||
* | * | ||
* You are free to use this software as you like, as long as you don't | * You are free to use this software as you like, as long as you don't | ||
− | * claim owner or authorship. | + | * claim owner or authorship. |
+ | * | ||
+ | * Last update: 2009-09-17 20:34:29 | ||
*/ | */ | ||
Line 31: | Line 38: | ||
local int __InsertIndex`{tag}, __RemovedIndex`{tag}, __High`{tag}, __Closest`{tag}; | local int __InsertIndex`{tag}, __RemovedIndex`{tag}, __High`{tag}, __Closest`{tag}; | ||
− | `define | + | `define sort_m_op(array,tag,operator) \ |
for (__RemovedIndex`{tag} = 1; __RemovedIndex`{tag} < `{array}.length; ++__RemovedIndex`{tag}) { \ | for (__RemovedIndex`{tag} = 1; __RemovedIndex`{tag} < `{array}.length; ++__RemovedIndex`{tag}) { \ | ||
− | if ( `{array}[__RemovedIndex`{tag} - 1] | + | if ( `{array}[__RemovedIndex`{tag} - 1] `operator `{array}[__RemovedIndex`{tag}] ) { \ |
− | __InsertIndex`{tag} = 0; \ | + | __InsertIndex`{tag} = 0;\ |
__High`{tag} = __RemovedIndex`{tag} - 1; \ | __High`{tag} = __RemovedIndex`{tag} - 1; \ | ||
while (__InsertIndex`{tag} <= __High`{tag}) { \ | while (__InsertIndex`{tag} <= __High`{tag}) { \ | ||
__Closest`{tag} = (__InsertIndex`{tag} + __High`{tag}) / 2; \ | __Closest`{tag} = (__InsertIndex`{tag} + __High`{tag}) / 2; \ | ||
− | if ( `{array}[__Closest`{tag}] | + | if ( `{array}[__Closest`{tag}] `operator `{array}[__RemovedIndex`{tag}] ) { \ |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
__High`{tag} = __Closest`{tag} - 1; \ | __High`{tag} = __Closest`{tag} - 1; \ | ||
} \ | } \ | ||
− | else if ( `{array}[__RemovedIndex`{tag}] | + | else if ( `{array}[__RemovedIndex`{tag}] `operator `{array}[__Closest`{tag}] ) { \ |
__InsertIndex`{tag} = __Closest`{tag} + 1; \ | __InsertIndex`{tag} = __Closest`{tag} + 1; \ | ||
+ | } \ | ||
+ | else { \ | ||
+ | __InsertIndex`{tag} = __Closest`{tag}; \ | ||
+ | break; \ | ||
} \ | } \ | ||
} \ | } \ | ||
− | if ( __InsertIndex`{tag} < __RemovedIndex`{tag} && `{array}[__RemovedIndex`{tag}] | + | if ( __InsertIndex`{tag} < __RemovedIndex`{tag} && `{array}[__RemovedIndex`{tag}] `operator `{array}[__InsertIndex`{tag}] ) { \ |
++__InsertIndex`{tag}; \ | ++__InsertIndex`{tag}; \ | ||
} \ | } \ | ||
Line 63: | Line 70: | ||
} | } | ||
− | // | + | `define sort_m(array,tag) `sort_m_op(`array, `tag, >) |
+ | |||
+ | // These are the standard macros you would use, only use the "_m" macros | ||
+ | // in case of naming conflicts with the variables | ||
+ | |||
+ | // Declare the variables used for the sorting | ||
`define sort_decl `sort_decl_m(_) | `define sort_decl `sort_decl_m(_) | ||
− | `define sort(array) ` | + | |
+ | // Sort the given array | ||
+ | `define sort(array) `sort_m_op(`array, _, >) | ||
+ | |||
+ | // Sort using an alternative operator, for example use `sort_op(array,>) | ||
+ | // to perform reverse order sorting. | ||
+ | `define sort_op(array,op) `sort_m_op(`array, _, `op) | ||
</uscript> | </uscript> | ||
Line 96: | Line 114: | ||
`log(data[i]); | `log(data[i]); | ||
} | } | ||
+ | |||
+ | `sort_op(data, <); | ||
+ | |||
+ | `log("Reversed:"); | ||
+ | for (i = 0; i < data.length; ++i) | ||
+ | { | ||
+ | `log(data[i]); | ||
+ | } | ||
+ | } | ||
+ | </uscript> | ||
+ | |||
+ | == Custom type notice == | ||
+ | |||
+ | You can sort any array with this macro, as long as the greater than (<code>></code>) operator have been defined for that type. Or when you use the <code>sort_op(Array,Operator)</code> macro, the specified operator. | ||
+ | |||
+ | You can use the following template for implementing the operator for the type you want to sort: | ||
+ | <uscript> | ||
+ | static final operator(24) bool > ( MyCustomType A, MyCustomType B ) | ||
+ | { | ||
+ | // TODO: implement | ||
} | } | ||
</uscript> | </uscript> | ||
+ | It's best to define the operator as static and final, this improves the execution speed. | ||
== Related Topics == | == Related Topics == | ||
* [[Legacy:Insertion_Sort]] | * [[Legacy:Insertion_Sort]] |
Latest revision as of 11:38, 17 September 2009
Below is a macro that allows you to quickly implement the sorting of a dynamic array. The sorting is performed within the scope of the function where it is used. This reduces overhead created by function calling.
/** * Inline sorting algorithm, based on the Insertion Sort on the UnrealWiki * http://wiki.beyondunreal.com/Legacy:Insertion_Sort * * Usage: include this include file in a class where you want to use it * using `include(sorter.uci) * When in a function where you want to perform sorting add `sort_decl(); * right after the function declaration. Then at the place where you want * to sort a dynamic array use `sort(MyArray); * * For example: * function test(array<int> myArray) * { * `sort_decl(); * local int foo; * `sort(myArray); * } * * Alternatively you can use the sorting with an different compare * operator using: `sort_op(Myarray, <) * The second argument is the operator to use. * * This sorting mechanism works for all types for which there is a > * operator. This is the case for most primitive types in the * UnrealEngine. For other types you need to declare the > operator * yourself. * * You are free to use this software as you like, as long as you don't * claim owner or authorship. * * Last update: 2009-09-17 20:34:29 */ `define sort_decl_m(tag) \ local int __InsertIndex`{tag}, __RemovedIndex`{tag}, __High`{tag}, __Closest`{tag}; `define sort_m_op(array,tag,operator) \ for (__RemovedIndex`{tag} = 1; __RemovedIndex`{tag} < `{array}.length; ++__RemovedIndex`{tag}) { \ if ( `{array}[__RemovedIndex`{tag} - 1] `operator `{array}[__RemovedIndex`{tag}] ) { \ __InsertIndex`{tag} = 0;\ __High`{tag} = __RemovedIndex`{tag} - 1; \ while (__InsertIndex`{tag} <= __High`{tag}) { \ __Closest`{tag} = (__InsertIndex`{tag} + __High`{tag}) / 2; \ if ( `{array}[__Closest`{tag}] `operator `{array}[__RemovedIndex`{tag}] ) { \ __High`{tag} = __Closest`{tag} - 1; \ } \ else if ( `{array}[__RemovedIndex`{tag}] `operator `{array}[__Closest`{tag}] ) { \ __InsertIndex`{tag} = __Closest`{tag} + 1; \ } \ else { \ __InsertIndex`{tag} = __Closest`{tag}; \ break; \ } \ } \ if ( __InsertIndex`{tag} < __RemovedIndex`{tag} && `{array}[__RemovedIndex`{tag}] `operator `{array}[__InsertIndex`{tag}] ) { \ ++__InsertIndex`{tag}; \ } \ } \ else { \ __InsertIndex`{tag} = __RemovedIndex`{tag}; \ } \ if ( __RemovedIndex`{tag} != __InsertIndex`{tag} ) { \ `{array}.Insert(__InsertIndex`{tag}, 1); \ `{array}[__InsertIndex`{tag}] = `{array}[__RemovedIndex`{tag} + 1]; \ `{array}.Remove(__RemovedIndex`{tag} + 1, 1); \ } \ } `define sort_m(array,tag) `sort_m_op(`array, `tag, >) // These are the standard macros you would use, only use the "_m" macros // in case of naming conflicts with the variables // Declare the variables used for the sorting `define sort_decl `sort_decl_m(_) // Sort the given array `define sort(array) `sort_m_op(`array, _, >) // Sort using an alternative operator, for example use `sort_op(array,>) // to perform reverse order sorting. `define sort_op(array,op) `sort_m_op(`array, _, `op)
Save the above code as sorter.uci
.
Example[edit]
`include(sorter.uci) function intSorter() { `sort_decl(); local int i; local array<int> data; data.length = 10; data[0] = 4; data[1] = 7; data[2] = 10; data[3] = 3; data[4] = 5; data[5] = 9; data[6] = 2; data[7] = 8; data[8] = 1; data[9] = 6; `log("Before:"); for (i = 0; i < data.length; ++i) { `log(data[i]); } `sort(data); `log("After:"); for (i = 0; i < data.length; ++i) { `log(data[i]); } `sort_op(data, <); `log("Reversed:"); for (i = 0; i < data.length; ++i) { `log(data[i]); } }
Custom type notice[edit]
You can sort any array with this macro, as long as the greater than (>
) operator have been defined for that type. Or when you use the sort_op(Array,Operator)
macro, the specified operator.
You can use the following template for implementing the operator for the type you want to sort:
static final operator(24) bool > ( MyCustomType A, MyCustomType B ) { // TODO: implement }
It's best to define the operator as static and final, this improves the execution speed.