Algorithms in C++ |
||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||||||||||||
|
||||||||||||||
A collection of useful C++ Algorithms |
As I create code, I try to make everything as "lumpy" as possible and to make the lumps re-usable. I expect these classes to be of most interest to students who want to watch an algorithm work in their debugger. There are always other ways to achieve the same goal. Although Standard Template Library users will want to keep using the STL, my efforts are, to the best of my knowledge, the fastest and clearest solutions to each problem and not a reproduction of existing libraries. For example, where the STL uses a Red-Black Tree, I chose to create an AVL Tree class and make it able to morph to a linked list and back just because it was easy. My Linked list class should be as fast as writing an inline linked list and has iterators that can move nodes between them, even between different lists. It's fast. Other classes like itow (integer to words - 123 becomes "one hundred and twenty three") are just hard to get right and don't exist in things like STL!
Constants and Basics
The following will help beginners with C++ fundamentals. Most are already defined in C++ systems and so this actual list isn't necessarily useful!#define _USE_MATH_DEFINES // Exposes M_PI and M_SQRT2 from math.h #include <math.h> // For sqrt, hypot, M_PI and M_SQRT2 #define M_SQRT3 1.7320508075688772935274463415059 // add a couple more defines suitable for long double #define M_GOLD 1.6180339887498948482045868343656 // The Golden Ratio (used in my Graphics section) // If you are using doubles to hold real-world values you must use a tolerance when comparing two of the values: bool Equal (double a, double b) {return fabs(a-b)<1e-6;} // fabs is in <math.h> bool LessThan (double a, double b) {return a<b-1e-6;} bool GreaterThan(double a, double b) {return a>b+1e-6;} double Degrees2Radians(double a) {return (PI*a)/180;} double Radians2Degrees(double a) {return (180*a)/PI;} double Fahrenheit2Celsius(double F) {return 5.0/9.0*(F-32.0);} double Celsius2Fahrenheit(double C) {return 9.0/5.0* C+32.0 ;} // A quick example of how to use templated types: template <typename T> T min(T a, T b) {return a<b ? a : b;} template <typename T> T max(T a, T b) {return a>b ? a : b;} template <typename T> int sgn(T a) {return a<0 ? -1 : a>0;} template <typename T> void Swap(T& a, T& b) {T tmp=b; b=a; a=tmp;} double abs(double a) {return (a<0) ? -a : a;} long abs(long a) {return (a<0) ? -a : a;} int NearestOne(double a) {return (int)(a+(a<0 ? -0.5 : 0.5));} double NearestTen(double a) {return ((int)(a+=5)-((int)a)%10);} // 10*(int)(a/10+0.5);} double Quad(double a, double b) {return hypot(a,b);} // Quadrature: sqrt(a*a+b*b);} double QuadMi(double a, double b) {return sqrt(a*a-b*b);} // Quadrature Minus int GreatestCommonDivisor(int i, int j) { while(i!=j) if(i>j) i-=j; else j-=i; return i; } // Tick,Tick Boom! When code must do something just once after a wait (OnTick may be called by a timer or event). // Used for Tool-tips and other pop-ups, comms time-outs etc. // Usage example: // static int Wait=2; // Boom() will be called during the second OnTick() call. To call Boom() again, Wait must be set to non-zero. // void Cancel () {Wait=0;} // bool IsWaiting(int* Counter) {return *Counter;} // void Restart() {Wait=2;} // Called by OnMouseOver for ToolTips. Like a sprug suction-pad toy: keep pushing it down every now and again and it stays down. // void OnTick () {if(TimeUp(&Wait)) Boom();} // Called by a 1 second timer. bool TimeUp(int* Counter) {return *Counter ? --*Counter==0 : false;} // For ASCII characters and null-terminated strings: char ToUpper(char c) {return c & ~0x20;} // Clear bit 5 char ToLower(char c) {return c | 0x20;} // Set bit 5 void strcpy(char* dst,const char* src) {while(*dst++=*src++);} // Copies up to a null-terminator int InStr(const char* ptr, int i, char c) { for(ptr+=i; *ptr!=c && *ptr++; ++i); return (*--ptr ? i : -1); } // Use structs or classes to remember to restore states by using the destructor: struct CWaitCursor { CWaitCursor() {SetMouseToHourGlass();} ~CWaitCursor() {SetMouseToPointer();} }; // The only technical difference between a class and struct is that a struct starts with an implied public: and a class with private. // Since CWaitCursor has no need for encapsulation it is a struct. class Remember2Free { void* Base; public: Remember2Free(void* Base) : Base(Base) {} ~Remember2Free() {try{delete[] Base;}catch(...){}} // Never let a destructor throw an exception! }; // Usage: bool ArrayThings() { char* Array=SomeAllocatingFunction(1234); Remember2Free That(Array); // do some things if(something) return false; // Array will be free'd by the Remember2Free destructor // do some more return true; }
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.