How to code and use commonly used algorithms

Started by
65 comments, last by Nice Coder 19 years, 1 month ago
Description: recursive function for filling up a map[x][y]

What to use it for: filling up an area in a map, example:
*****************************************************************###########################*********###########################*#*************************#*********#*************************#*#*************************##########**************************#*#*************************************************************#*#*************************************************************#*#*************************************************************#*#*****############********************************************#*#*****#**********#********###########*************************#*#*****#*#########*********#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#*****************#*********#*************************#*#*****#*#********#########**********#*************************#*#*****#*#********#******************#*************************#*#*****#*#********#******************#*************************#*#*****#*#********#******************#*************************#*#*****#*#********#******************#*************************#*#*****#*#********#******************#*************************#*######**#########*******************##########################*


What not to use it for: filling up a map which is not limited by walls

Why you should use it: because it's very compact and quick; can also be optimalised very effectively using the stack in combination with in-line assembly

Problems with using it: none

How to use:
void fill(unsigned int x, unsigned int y){  if(map[x][y] == '*'){    map[x][y] = '#';    fill(x-1,y); fill(x+1,y); fill(x,y-1); fill(x,y+1);  }}


For a how-it-works and more information, see:
http://www.gamedev.net/community/forums/topic.asp?topic_id=291495

Bas
Advertisement
Wikipedia also has a nice list.
---New infokeeps brain running;must gas up!
Imalc: no offence taken. I just usually hand out psudocode that isn't as optimised. Nice code. Too.

Maybe We should also have mini-contests on who can make the most optimised code for the algorithms?

Register int32 l = 0Register int32 r = nRegister Int32 m = 0Register int32 f = findwhile (l < r) {	m = (l + r) >> 1	if (a[m] < f)		l = m++;	else		r = m--; // -- needed here, to make sure that it terminates.}if (a[m] == f)	return m;else	return NOT_FOUND;


Its a little better. tho it could be a little quicker.

blizzard999 -> Actually it is o(n / m), the origional algorithm.

Because once it hits a letter that isn't in the query string, it jumps the length of the string its trying to find. it then starts again.

For eg.
int *indexchar string[strlen]char find[findlen]char *flen = find[findlen]char *ftoint strl = *string[strlen]index = &string + findlen;while (index < strl) {if (index != fto) {	*Index = &index + findlen;	*fto = &flen    	Continue;} else {    if (&fto > &find) {        *fto = &fto--	Continue;    };    // sucess    return &index - &string    };};};


Now do you see? This is the simple case, in C++. (it should work, but i don't know much C++, there might be some pointer dereferencing needed, just PM me if theres anything wrong with it.).

This is the simple case, it uses pointer arithmatic, to do the string search.

How does it do this?
from the loop

while (index < strl) {if (index != fto) {	*Index = &index + findlen;	*fto = &flen    	Continue;} else {    if (&fto > &find) {        *fto = &fto--	Continue;    };    // sucess    return &index - &string    };};};

So, as long the pointer for index, is smaller then the pointer for the upper bound of the string, do.
If the character at the current pointer to index is not equal to the character that fto points to (one of the characters in the find string, usually the last, exept when it gets matches).
The previous (length of find string) characters cannot be the find string, because the last character is bad.
So, move ahead (length of find string) characters and try again.

Now once you've got a match, (the else clause)
If the pointer for fto is greater then the start of the string (so we don't keep going, past the beginning of the string)
We decrement the pointer, so that it now points to the character before what it used to.
Now if the previous statement is false, then fto is exactly equal to the beginning of the find string
So we have checked the entire string, so, we have found the string and we give back its index
We calculate that by, how much larger the current intex is then the string.


From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by Flarelocke
Wikipedia also has a nice list.
NIST has some too.
Quote:Original post by Extrarius at 1/2/2005 4:16:16 AM
There is also the sometimes-helpful National Institute of Standards and Technology's Dictionary of Algorithms and Data Structures
Quote:Original post by flangazor at 1/2/2005 7:00:04 PM
Quote:Original post by Flarelocke
Wikipedia also has a nice list.
NIST has some too.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
A hash table.

When to use it:
When you need constant time reads/writes.

When not to use it: when your dealing with a small amount of data

Psudocode:

Table() Struct for Elements in table:	Entries()	Struct for elements in entries		Pointer Entry		Integer FullHash	Function hashtableretrieve(key)hsh = hash(key)chsh = hsh modulo Tablesizepointer ctable = pointer to table(chsh).entriesFind hsh, in ctable, using binary search.Return either the entry (pointer), or falure of the search fails.end functionfunction hashtableadd(key, value)h = hashtableretrieve(key)if h is not equal to falure then	return falureend ifhsh = hash(key)chsh = hsh molulo TablesizePointer ctable = pointer to table(chsh).entriesAdd a new element to ctable,	In that elemsnt, make Element.entry equal to value	And Fullhash equal to hshSort ctableend functionfunction hashtableremove(key)hsh = hash(key)chsh = hsh modulo Tablesizepointer ctable = pointer to table(chsh).entriesFind hsh, in ctable, using binary search.Remove the element in which it is found.end function


From,
Nice coder

[Edited by - Nice Coder on January 2, 2005 11:34:52 PM]
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by Nice Coder
Imalc: no offence taken. I just usually hand out psudocode that isn't as optimised. Nice code. Too.
Yeah I thought it might be just to show the principle, never mind.
Quote:

	if (a[m] < f)		l = m++;	else		r = m--; // -- needed here, to make sure that it terminates.
There's actually a big a problem with that. It's my fault I suppose, there's something I forgot to mention...
In that first if-statement the true case handles just < which means that the lower bound is definately above m (hence the +1). HOWEVER, the else case handles >=, so because that includes the equal case we include m in the range, hence it is actually correct to not be subtracting one. (Yes that's right, even the subtracting one has been cunningly optimised out!)

It will still always terminate because even though we set r to m, we know that l is less than r (loop condition), so the truncation in (l+r)/2 will round m down, hence m will always be less than the original r.
The code you posted will not work in ALL cases.

I should have said that what I posted was in fact already throughly tested and optimised, bug-free code. In fact I very much doubt an assembly version would squeeze much more performance out of it.
I can tell you didn't try the change out, by the missing semi-colons. It's quite an understandable mistake, given my lack of explanation.

My original version did have an explicit shift instead of the divide as well, but I changed it in what I posted, I don't know why really.
I didn't use ++ because there was no need to store the result back into m.
	if (a[m] < f)		l = m+1;	else		r = m; // -1 NOT needed here, It does terminate!!
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
I just noticed one other thing in your hash table psuedo code:
Quote:Find hsh, in ctable, using binary search.
Unfortunately items in a hash table aren't guaranteed to be in order, hence a binary search wouldn't always work. Or am I missing something? I did skim over it pretty quick.

Maybe someone else should post code for some interesting algorithm so it doesn't look like I'm picking on Nice Coder![smile]

Hmmm, how about a non-recursive binary tree insertion routine?
//'head' is the binary tree pointer.//'ins' is caller allocated and already contains the data to be inserted.//operator < must be overloaded.template <class TNode>void TreeInsert(TNode *&head, TNode *ins) {	TNode *curr = head;	ins->left = ins->right = NULL;	if (head == NULL) {		head = ins;	} else do {		if (*ins < *curr) {			//it goes somewhere in the left sub-tree			if (curr->left == NULL) {				curr->left = ins;				break;			}			curr = curr->left;		} else {			//it goes somewhere in the right sub-tree			if (curr->right == NULL) {				curr->right = ins;				break;			}			curr = curr->right;		}	} while (true);}
This is actually another extract from my sorting demo program (part of tree-sort) I plan to release the full code eventually, just not yet.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Nice imalc.

Yeah i didn't test it... (without the --)

:)

I've been thinking about an o(n) sorting algorithm. i might pm you about it later. I'm horrendus at finding faults in my own ideas.

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by Nice Coder
A hash table.

When to use it:
When you need constant time reads/writes.

When not to use it: when your dealing with a small amount of data

Psudocode:

Table() Struct for Elements in table:	Entries()	Struct for elements in entries		Pointer Entry		Integer FullHash	Function hashtableretrieve(key)hsh = hash(key)chsh = hsh modulo Tablesizepointer ctable = pointer to table(chsh).entriesFind hsh, in ctable, using binary search.Return either the entry (pointer), or falure of the search fails.end function
You're confused. The hash won't be unique to the element. In fact, hsh = hsh modulo Tablesize for all sensible hash functions (one of which, is in fact modulo). When the hashes collide, you search for key, rather than its hash.

And using binary search is overkill. The most important part is that it imposes an additional constraint on the keys (that they be ordered), but it also requires your addition function to insert in order. If your table's generating enough collisions to make such a thing worth implementing, it's broken.
---New infokeeps brain running;must gas up!

This topic is closed to new replies.

Advertisement