瀏覽代碼

Initial repository commit

= 7 年之前
當前提交
61695b7fed
共有 5 個文件被更改,包括 647 次插入0 次删除
  1. 二進制
      a.out
  2. 624 0
      source1.h
  3. 23 0
      test.cc
  4. 二進制
      test.exe
  5. 二進制
      test.obj

二進制
a.out


+ 624 - 0
source1.h

@@ -0,0 +1,624 @@
+#ifndef __source1_H__
+#define __source1_H__
+#include <iostream>
+using namespace std;
+class Triehard // compressed binary trie
+// constructor should make a left and right that are empty for search to work
+// magnitude is 1 for length 1, so it must be >= 1
+// flag means the value ending there is being stored
+{
+	private:
+	
+		class Trienode
+		{
+			private:
+				
+				int magnitude;
+				bool flag;
+				Trienode * left;
+				Trienode * right;
+				//Convenient method for printing.
+				//Returns a string to be able to chain
+				//printing more easily.
+				//Side is either 0 (left), or 1 (right)
+				string getNodeVal(int side){
+					string output = "";
+					for(int i = 0; i < magnitude; i ++){
+						output += to_string(side);
+					}
+					return output;
+				}
+				
+			public:
+			
+				Trienode(int magnitude, bool flag):
+				magnitude{magnitude}, flag{flag}
+				{
+					left = nullptr;
+					right = nullptr;
+				}
+				
+				~Trienode() // Unsure about syntax, if this will play nicely with delete method
+				{
+					delete left;
+					delete right;
+					delete this;
+				}
+			
+				int getMag()
+				{
+					return magnitude;
+				}
+
+				bool getFlag()
+				{
+					return flag;
+				}
+				//Side is 0 (left) or 1 (right)
+				void print(int side,string output = ""){
+					string val = getNodeVal(side);
+					if(getFlag()){
+						cout << output + val << endl;
+					}
+					if(left != nullptr){
+						left->print(0,output + val);
+					}
+					if(right != nullptr){
+						right->print(1,output + val);
+					}
+				}
+				
+				Trienode * getLeft()
+				{
+					return left;
+				}
+				
+				Trienode * getRight()
+				{
+					return right;
+				}
+				
+				void addMag()
+				{
+					++magnitude;
+				}
+				
+				void subMag()
+				{
+					--magnitude;
+				}
+				
+				void tFlag()
+				{
+					flag = true;
+				}
+				
+				void fFlag()
+				{
+					flag = false;
+				}
+				
+				Trienode * setLeft(int mag, bool flg)
+				{
+					left = new Trienode(mag, flg);
+					return left;
+				}
+				
+				Trienode * setRight(int mag, bool flg)
+				{
+					right = new Trienode(mag, flg);
+					return right;
+				}
+				
+				void copyLeft(Trienode * node)
+				{
+					left = node;
+				}
+				
+				void copyRight(Trienode * node)
+				{
+					right = node;
+				}
+		};
+		
+		Trienode * left;
+		Trienode * right;
+	
+	public:
+	
+		Triehard() // Initializes both sides as empty, but makes it searchable, mutatable
+		{
+			left = new Trienode(0, false);
+			right = new Trienode(0, false);
+		}
+		
+		~Triehard() // Same concern (syntax) as nodes, don't forget to write an erase method as well, maybe an empty/wipe
+		{
+			delete left;
+			delete right;
+			delete this;
+		}
+		
+		void print()
+		{
+			//Default param arg seems to be a bit different
+			//than i thought. Leaving it in the node print
+			//function, try to fix later perhaps?
+			if(left != nullptr)left->print(0);
+			if(right != nullptr)right->print(1);
+		}
+		
+		bool search(int * val, int len) // val is the string, len is its length
+		{
+			Trienode * curnode;
+			bool side; // represents if you are on the left or right (right being true)
+			if (val[0])
+			{
+				curnode = right;
+				side = true;
+			}
+			else
+			{
+				curnode  = left;
+				side = false;
+			}
+			
+			int curmag = curnode->getMag();
+			
+			for (int i = 0; i < len; i++) // each iteration checks the current character for accuracy. it does not prepare for the next character like the preamble
+			{
+				if (val[i]) // if next digit is 1
+				{
+					if (side) // if you're on the right
+					{
+						if (curmag) // if your current magnitude is >= 1 (still info "left" in this node)
+						{
+							--curmag;
+							continue;
+						}
+						
+						if (curnode->getRight()) // If current node is "exhausted", move on to next one
+						{
+							curnode = curnode->getRight();
+							curmag = curnode->getMag() - 1;
+							continue;
+						}
+						else
+						{
+							return false;
+						}
+						
+					}
+					else
+					{
+						if (curmag)
+						{
+							return false;
+						}
+						
+						if (curnode->getRight())
+						{
+							curnode = curnode->getRight();
+							curmag = curnode->getMag() - 1;
+							side = true;
+							continue;
+						}
+						else
+						{
+							return false;
+						}
+					}
+				}
+				else
+				{
+					if (!side)
+					{
+						if (curmag)
+						{
+							--curmag;
+							continue;
+						}
+						
+						if (curnode->getLeft())
+						{
+							curnode = curnode->getLeft();
+							curmag = curnode->getMag() - 1;
+							continue;
+						}
+						else
+						{
+							return false;
+						}
+					}
+					else
+					{
+						if (curmag)
+						{
+							return false;
+						}
+						
+						if (curnode->getLeft())
+						{
+							curnode = curnode->getLeft();
+							curmag = curnode->getMag() - 1;
+							side = false;
+							continue;
+						}
+						else
+						{
+							return false;
+						}
+					}
+				}
+			}
+			
+			return curnode->getFlag();
+		}
+		
+		void insert(int * val, int len) // assumes valid input
+		{						
+			Trienode * curnode;
+			bool side; // represents if you are on the left or right (right being true)
+			if (val[0])
+			{
+				curnode = right;
+				side = true;
+			}
+			else
+			{
+				curnode  = left;
+				side = false;
+			}
+			
+			int curmag = curnode->getMag();
+			
+			for (int i = 0; i < len; i++)
+			{
+				if (val[i]) // if next digit is 1
+				{
+					if (side) // if you're on the right
+					{
+						if (curmag) // if your current magnitude is >= 1 (still info "left" in this node)
+						{
+							--curmag;
+							continue;
+						}
+						else if (curnode->getRight()) // If current node is "exhausted", move on to next one
+						{
+							curnode = curnode->getRight();
+							curmag = curnode->getMag() - 1;
+							continue;
+						}
+						else if (!(curnode->getLeft())) // if there are no subtrees, just increase this node's magnitude
+						{
+							curnode->addMag();
+							continue;
+						}
+						else // we're on a "1" node, but it is depleted, and there is a left subtree. so, we create a new node to the right to represent this bit
+						{
+							curnode = curnode->setRight(1, false);
+							continue;
+						}
+						
+					}
+					else // we're on a left subtree, but have a 1 coming up
+					{
+						if (curmag) // this means we have a value here, so we need to split this node up, branching to the right will be handled by following code
+						{						
+							Trienode * newnode = new Trienode(0, false); // this will be the second half of the big node
+							
+							while (curmag) // fills newnode with the extra magnitude
+							{
+								curnode->subMag();
+								newnode->addMag();
+							}
+							
+							newnode->copyLeft(curnode->getLeft()); // move the children to the bottom half
+							newnode->copyRight(curnode->getRight());
+							curnode->copyLeft(newnode); // put new node at left of curnode
+							curnode->copyRight(nullptr); // nothing is in the right yet
+							goto SKIP1; // skip next if check since we know new right is NULL
+						}
+						
+						if (curnode->getRight()) // we can and should move to the right. once there, we sub 1 from magnitude and move on.
+						{
+							curnode = curnode->getRight();
+							curmag = curnode->getMag() - 1;
+							side = true;
+							continue;
+						}
+						else // we are on left, it is empty, and the right side is empty. create and set that node to curnode->
+						{
+							SKIP1:
+							curnode = curnode->setRight(1, false);
+							continue;
+						}
+					}
+				}
+				else // next digit is a 0
+				{
+					if (!side) // on a left subtree
+					{
+						if (curmag) // still have 0s "remaining" at this node
+						{
+							--curmag;
+							continue;
+						}
+						else if (curnode->getLeft()) // no 0s remaining, but there is a left subtree
+						{
+							curnode = curnode->getLeft();
+							curmag = curnode->getMag() - 1;
+							continue;
+						}
+						else if (!(curnode->getRight())) // no subtrees and we're on the correct side, so add to this node's magnitude
+						{
+							curnode->addMag();
+							continue;
+						}
+						else // no 0s remaining, no left subtree, and we are going to add one.
+						{
+							curnode = curnode->setLeft(1, false);
+							continue;
+						}
+					}
+					else // we're on a right subtree but have a 0 coming up
+					{
+						if (curmag) // this means we have a value here, so we need to split this node up and branch to the left before this point
+						{						
+							Trienode * newnode = new Trienode(0, false); // this will be the second half of the big node
+							
+							while (curmag) // fills newnode with the extra magnitude
+							{
+								curnode->subMag();
+								newnode->addMag();
+							}
+							
+							newnode->copyLeft(curnode->getLeft()); // move the children to the bottom half
+							newnode->copyRight(curnode->getRight());
+							curnode->copyLeft(nullptr); // nothing is in the left yet
+							curnode->copyRight(newnode); // put new node at right of curnode
+							goto SKIP2; // skip next if check since we know new left is NULL
+						}
+						
+						if (curnode->getLeft()) // we can and should move to the left. once there, we sub 1 from magnitude and move on.
+						{
+							curnode = curnode->getLeft();
+							curmag = curnode->getMag() - 1;
+							side = false;
+							continue;
+						}
+						else // we are on right, it is empty, and the left side is empty. create and set that node to curnode->
+						{
+							SKIP2:
+							curnode = curnode->setLeft(1, false);
+							continue;
+						}
+					}
+				}
+			}
+			
+			curnode->tFlag();
+		}
+		
+		void cut(int * val, int len) // this is delete because i can't use delete :(
+		{			
+			Trienode * curnode;
+			Trienode * prevnode = nullptr;
+			bool side; // represents if you are on the left or right (right being true)
+			bool side2; // previous node's side
+			if (val[0])
+			{
+				curnode = right;
+				side = true;
+				side2 = true;
+			}
+			else
+			{
+				curnode  = left;
+				side = false;
+				side2 = false;
+			}
+			
+			int curmag = curnode->getMag();
+			
+			for (int i = 0; i < len; i++) // each iteration checks the current character for accuracy. it does not prepare for the next character like the preamble
+			{
+				if (val[i]) // if next digit is 1
+				{
+					if (side) // if you're on the right
+					{
+						if (curmag) // if your current magnitude is >= 1 (still info "left" in this node)
+						{
+							--curmag;
+							side2 = side;
+							continue;
+						}
+						
+						if (curnode->getRight()) // If current node is "exhausted", move on to next one
+						{
+							prevnode = curnode;
+							curnode = curnode->getRight();
+							curmag = curnode->getMag() - 1;
+							side2 = side;
+							continue;
+						}
+						else // node doesn't exist
+						{
+							return;
+						}
+						
+					}
+					else
+					{
+						if (curmag) // node doesn't exist
+						{
+							return;
+						}
+						
+						if (curnode->getRight())
+						{
+							prevnode = curnode;
+							curnode = curnode->getRight();
+							curmag = curnode->getMag() - 1;
+							side = true;
+							side2 = false;
+							continue;
+						}
+						else // node doesn't exist
+						{
+							return;
+						}
+					}
+				}
+				else
+				{
+					if (!side)
+					{
+						if (curmag)
+						{
+							--curmag;
+							side2 = side;
+							continue;
+						}
+						
+						if (curnode->getLeft())
+						{
+							prevnode = curnode;
+							curnode = curnode->getLeft();
+							curmag = curnode->getMag() - 1;
+							side2 = side;
+							continue;
+						}
+						else // node doesn't exist
+						{
+							return;
+						}
+					}
+					else
+					{
+						if (curmag) // node doesn't exist
+						{
+							return;
+						}
+						
+						if (curnode->getLeft())
+						{
+							prevnode = curnode;
+							curnode = curnode->getLeft();
+							curmag = curnode->getMag() - 1;
+							side = false;
+							side2 = true;
+							continue;
+						}
+						else // node doesn't exist
+						{
+							return;
+						}
+					}
+				}
+			}
+			
+			// at this point, we have curnode being the "end" of our value
+			if (!(prevnode)) // if we are deleting one of the 2 base trees
+			{
+				if (side)
+				{
+					right->fFlag();
+				}
+				else
+				{
+					left->fFlag();
+				}
+			}
+			else if (curnode->getLeft() && curnode->getRight()) // we have shit to both sides, just unflag
+			{
+				curnode->fFlag();
+			}
+			else if (!(curnode->getLeft()) && !(curnode->getRight())) // if our node has no children, destroy it and change parent's reference to NULL
+			{
+				if (side)
+				{
+					delete curnode;
+					prevnode->copyRight(nullptr);
+				}
+				else
+				{
+					delete curnode;
+					prevnode->copyLeft(nullptr);
+				}
+			}
+			else if (side && curnode->getLeft() && prevnode->getLeft() && side2 && !(prevnode->getFlag()) && !(prevnode->getLeft()))
+			// we are on the right, we have shit to the left, and the parent has nothing to the left, and is not flagged
+			// this is a rare case where we do have to compress
+			{
+				while (curnode->getMag()) // Change mag to parent
+					{
+						curnode->subMag();
+						prevnode->addMag();
+					}
+					
+					prevnode->copyLeft(curnode->getLeft()); // Move left side up, delete old data
+					curnode->copyLeft(nullptr);
+					prevnode->copyRight(nullptr);
+					delete curnode;
+			}
+			else if (!(side) && curnode->getRight() && prevnode->getRight() && !(side2) && !(prevnode->getFlag()) && !(prevnode->getRight()))
+			// we are on the left, we have shit to the right, and the parent has nothing to the right, and is not flagged
+			// the same rare case as above
+			{
+				while (curnode->getMag()) // Change mag to parent
+					{
+						curnode->subMag();
+						prevnode->addMag();
+					}
+					
+					prevnode->copyRight(curnode->getRight()); // Move left side up, delete old data
+					curnode->copyRight(nullptr);
+					prevnode->copyLeft(nullptr);
+					delete curnode;
+			}
+			else if ((side && curnode->getLeft()) || (!(side) && curnode->getRight()))
+			// we are to the right and have shit to the left or vice versa
+			{
+				curnode->fFlag();
+			}
+			else if (side) // we are on the right and have shit to the right
+			{
+				Trienode * child = curnode->getRight();
+				while (child->getMag()) // moves magnitude from child to parent we are removing
+				{
+					child->subMag();
+					curnode->addMag();
+				}
+				
+				if (child->getFlag()) curnode->tFlag(); // Sets flag based on child
+				else curnode->fFlag();
+				
+				curnode->copyLeft(child->getLeft()); // moves child's children to our parent node
+				curnode->copyRight(child->getRight());
+				child->copyLeft(nullptr); // Change child's children to null to allow for safe deletion
+				child->copyRight(nullptr);
+				delete child;
+			}
+			else // we are on the left and have shit to the left
+			{
+				Trienode * child = curnode->getLeft();
+				while (child->getMag()) // moves magnitude from child to parent we are removing
+				{
+					child->subMag();
+					curnode->addMag();
+				}
+				
+				if (child->getFlag()) curnode->tFlag(); // Sets flag based on child
+				else curnode->fFlag();
+				
+				curnode->copyLeft(child->getLeft()); // moves child's children to our parent node
+				curnode->copyRight(child->getRight());
+				child->copyLeft(nullptr); // Change child's children to null to allow for safe deletion
+				child->copyRight(nullptr);
+				delete child;
+			}
+		}
+};
+
+#endif

+ 23 - 0
test.cc

@@ -0,0 +1,23 @@
+#include "source1.h"
+#include <iostream>
+using namespace std;
+
+int main()
+{
+	Triehard * test = new Triehard();
+	cout << "success!" << endl;
+	int x[4] = {0,1,1};
+	cout << "success!" << endl;
+	int y[5] = {1,0,1,1,0};
+	cout << "success!" << endl;
+	test->insert(x, 3);
+	cout << "success!" << endl;
+	test->print();
+	/*test->insert(y, 5);
+	cout << "success!" << endl;
+	test->cut(x, 4);
+	cout << "success!" << endl;
+	delete test;
+	cout << "success!" << endl;
+	while(1);*/
+}

二進制
test.exe


二進制
test.obj