Parcourir la source

finished insert, working on delete

tarfeef101 il y a 7 ans
Parent
commit
c36902149c
2 fichiers modifiés avec 81 ajouts et 169 suppressions
  1. 75 166
      source3.h
  2. 6 3
      tasks.txt

+ 75 - 166
source3.h

@@ -95,6 +95,16 @@ class Triehard // compressed decimal trie
 					children[x] = node;
 				}
 				
+				bool isLeaf()
+				{
+					for (int i = 0; i < 10; ++i)
+					{
+						if (children[i]) return false;
+					}
+					
+					return true;
+				}
+				
 				int sumMag()
 				{
 					int result = magnitude;
@@ -194,7 +204,7 @@ class Triehard // compressed decimal trie
 			int pos = (*val)[0]; // represents what value your current node is
 			int curmag = curnode->getMag();
 			
-			for (int i = 0; i < val->size(); i++) // each iteration checks the current character for accuracy. it does not prepare for the next character like the preamble
+			for (int i = 0; i < val->size(); i++) // each iteration checks the current character for accuracy.
 			{
 				if ((*val)[i] == pos) // if we are on the correct node already
 				{
@@ -242,154 +252,76 @@ class Triehard // compressed decimal trie
 			return 0;
 		}
 		
-		// START WORK HERE
 		void insert(vector<int> * val) // assumes valid input
 		{
-			Trienode * curnode; // the node we are checking against our current value
-			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;
-			}
-			
+			Trienode * curnode = nodes[(*val)[0]];
+			int pos = (*val)[0]; // represents what value your current node is
 			int curmag = curnode->getMag(); // "remaining" magnitude of the current node
 			
-			for (int i = 0; i < val->size(); i++)
+			for (int i = 0; i < val->size(); i++) // each iteration validates against curnode for position i
 			{
-				if ((*val)[i]) // if current digit is 1
+				if ((*val)[i] == pos) // curnode matches current value
 				{
-					if (side) // if you're on the right
+					if (curmag) // curnode has magnitude left, just sub1 and continue
 					{
-						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()) && !(curnode->getCount())) // if there are no subtrees, just increase this node's magnitude
-						// also can't do that if the node is flagged, since it needs to retain that info, so check for this
-						{
-							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
-						// also works if the node is flagged and we just need a new node to represent the unflagged set of 1s
-						{
-							curnode = curnode->setRight(1, 0);
-							continue;
-						}
-						
+						--curmag;
+						continue;
 					}
-					else // we're on a left subtree, but have a 1 coming up
+					
+					if (curnode->getX(pos)) // curnode is exhausted, but we have the same child with mag >=1, so use that
 					{
-						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, curnode->getCount()); // this will be the second half of the big node
-							curnode->zeroCount(); // this and the passing of the count into newnode ensure count is not lost
-							
-							while (curmag) // fills newnode with the extra magnitude
-							{
-								curnode->subMag();
-								--curmag;
-								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, 0);
-							side = true;
-							continue;
-						}
+						curnode = curnode->getX(pos);
+						curmag = curnode->getMag() - 1;
+						continue;
+					}
+					
+					if (!(curnode->getCount()) && curnode->isLeaf()) // we aren't flagged and are a leaf, so add mag
+					{
+						curnode->addMag();
+						continue;
 					}
+					
+					curnode = curnode->setX(pos, 1, 0) // we must create a child with mag1, curmag is 0 so no change
+					continue;
 				}
-				else // next digit is a 0
+				else // curnode is not the same digit as val[i]
 				{
-					if (!side) // on a left subtree
+					if (curmag) // this means we are going to have to decompress
 					{
-						if (curmag) // still have 0s "remaining" at this node
+						Trienode * newnode = new Trienode(0, curnode->getCount()); // this'll be the second half of curnode-
+						curnode->zeroCount; // newnode should be flagged (if curnode was), not curnode
+						
+						while (curmag) // put extra magnitude into newnode
 						{
+							curnode->subMag();
 							--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()) && !(curnode->getCount())) // no subtrees and we're on the correct side, so add to this node's magnitude
-						// only if this node isn't flagged, since we must retain that info
-						{
-							curnode->addMag();
-							continue;
+							newnode->addMag();
 						}
-						else // no 0s remaining || we are flagged, no left subtree, and we are going to add one.
+						
+						for (int i = 0; i < 10; i++) // move children to newnode
 						{
-							curnode = curnode->setLeft(1, 0);
-							continue;
+							newnode->copyX(i, curnode->getX(i));
+							curnode->copyX(i, nullptr);
 						}
+						
+						curnode->copyX(pos, newnode); // put newnode in its place
+						curnode = curnode->setX((*val)[i], 1, 0); // insert new node for the string being inserted
+						curmag = curnode->getMag() - 1; // reset curmag
+						pos = (*val)[i]; // update pos
+						continue;
 					}
-					else // we're on a right subtree but have a 0 coming up
+					else if (curnode->getX((*val)[i])) // we have a child of the correct val
 					{
-						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, curnode->getCount()); // this will be the second half of the big node
-							curnode->zeroCount(); // This and the passing of getCount to newnode ensure count is not lost
-							
-							while (curmag) // fills newnode with the extra magnitude
-							{
-								curnode->subMag();
-								--curmag;
-								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, 0);
-							side = false;
-							continue;
-						}
+						pos = (*val)[i];
+						curnode = curnode->getX(pos);
+						curmag = curnode->getMag() - 1;
+						continue;
+					}
+					else // insert a child, curmag is still 0
+					{
+						pos = (*val)[i];
+						curnode = curnode->setX(pos, 1, 0)'
+						continue;
 					}
 				}
 			}
@@ -414,45 +346,29 @@ class Triehard // compressed decimal trie
 					newnode->addMag();
 				}
 				
-				// now we create the newnode on the appropriate side
-				newnode->copyLeft(curnode->getLeft());
-				newnode->copyRight(curnode->getRight());
-				
-				if (side)
+				for (int i = 0; i < 10; i++) // move children to newnode
 				{
-					curnode->copyLeft(nullptr);
-					curnode->copyRight(newnode);
-				}
-				else
-				{
-					curnode->copyLeft(newnode);
-					curnode->copyRight(nullptr);
+					newnode->copyX(i, curnode->getX(i));
+					curnode->copyX(i, nullptr);
 				}
+				
+				curnode->copyX(pos, newnode); // ensure newnode is actually linked to curnode
 			}
 		}
 		
 		void cut(vector<int> * val) // this is delete because i can't use delete :(
+		// NOT DONE AT ALL!!!!
 		{
 			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 pos; // represents the represented value of curnode (0-9)
+			int pos2; // previous node's side
+			side = (*val)[i];
+			side2 = side;
+			curnode = nodes[side];
 			int curmag = curnode->getMag();
 			
-			for (int i = 0; i < val->size(); i++) // each iteration checks the current character for accuracy. it does not prepare for the next character like the preamble
+			for (int i = 0; i < val->size(); i++) // each iteration checks the current character for accuracy.
 			{
 				if ((*val)[i]) // if next digit is 1
 				{
@@ -552,15 +468,7 @@ class Triehard // compressed decimal trie
 			// 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->subCount();
-				}
-				else
-				{
-					left->subCount();
-				}
-				
+				nodes(pos)->subCount();
 				return;
 			}
 			
@@ -568,6 +476,7 @@ class Triehard // compressed decimal trie
 			if (curnode->getCount()) return; // This means we aren't removing a node, so no compression is possible
 			
 			// Cases where nodes have to be removed/compressed
+			// THIS NEEDS A LOT OF WORK!!!
 			if (!(curnode->getLeft()) && !(curnode->getRight())) // if our node has no children, destroy it and change parent's reference to NULL
 			{
 				if (side)

+ 6 - 3
tasks.txt

@@ -1,14 +1,17 @@
 Notes/To Do:
 
 1) replace sending in strings of binary and lengths with:
-	a) only should need source2 for binary data, no need to not have the functionality it provides (replaced source1 with in-progress build)
+	a) only should need source2 for binary data, no need to not have the functionality it provides (replaced source1 with in-progress build, source3 with a base-10 in-progress)
 	b) any source should allow no length being provided, just a string (done in source1 with vectors)
 	c) one source should allow storage of ASCII strings, converting to binary in the backend
-	d) want a measure of compression (in progress in source1)
+	d) want a measure of compression (done in source1)
 		i) formula: nodes vs nodes in a normal trie
 		ii) formula: nodes vs total binary characters of all strings being stored (raw)
 2) error handling
 	a) throw error for deleting stuff that's not there
 	b) check/handle (and throw) when you cannot allocate space to do an operation
 	c) throw error for invalid input to functions
-		i) invalid characters in strings
+		i) invalid characters in strings
+
+for source3: can put a goto into insert to skip checking if pos==val[i] since we set it at the start
+for source3: bool isLeaf() can be handled by setting a flag during inserts/deletions, that way we don't need to calculate