<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>template set</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><span lang="en-ca"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b></span>
<b>&nbsp;<span lang="en-ca">&nbsp;&nbsp; </span></b></font><span lang="en-ca">
<font size="6" color="#FF0000"><b>Template Set</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. <span lang="en-ca">First</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b><font size="3">This is <span lang="en-ca">an improved version of set which is implemented by template. My intention is to create a </span></font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>general purpose set class which is independent from its type. You see, set is just set. The operation </b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>of union, intersection, difference should all be the same even you have a different type of element.</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>So, it is ideal to implement it in a template class.</b></font></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<p><span lang="en-ca"><b>There are several problems:</b></span></p>
<p><span lang="en-ca"><b>1. How to pass user-defined methods for comparison and 
displaying of elements which may be a class </b></span></p>
<p><span lang="en-ca"><b>or a structure etc. My answer is the way I learned from 
Mr. Shaffer. Using a class which has some</b></span></p>
<p><span lang="en-ca"><b>static member function defined by user for each 
particular type of element.</b></span></p>
<p><span lang="en-ca"><b>2. How to define the &quot;Universe&quot; and &quot;Empty&quot; set? Surely 
it seems an easy question by assuming you </b></span></p>
<p><span lang="en-ca"><b>can declare two objects of set class. It is true for 
normal class, but false for a template class </b></span></p>
<p><span lang="en-ca"><b>because you cannot declare an object of template class 
unless you instantiate it with type. </b></span></p>
<p><span lang="en-ca"><b>However, this is the job of user! My way is to declare 
the pointer instead of object. And I use a</b></span></p>
<p><span lang="en-ca"><b>counter to count the total object created for the 
particular type of class. When the every first </b></span></p>
<p><span lang="en-ca"><b>object is created, I try to make some little trick in 
constructor such that I can dynamically </b></span></p>
<p><span lang="en-ca"><b>create both &quot;Universe&quot; and &quot;Empty&quot; objects. The similar 
trick is done inside destructor. But be</b></span></p>
<p><span lang="en-ca"><b>careful! You have to think clearly about what to do 
here, otherwise you will easily fall in </b></span></p>
<p><span lang="en-ca"><b>infinite loop!</b></span></p>
<p><span lang="en-ca"><b>3. The last question is crazy and I even sent a email 
to Mr. Shaffer for help. How to create </b></span></p>
<p><span lang="en-ca"><b>&quot;power set&quot; , which is the set of all its sub sets? Got 
the idea? See following example:</b></span></p>
<p><span lang="en-ca"><b>template &lt;class T, class methods&gt;</b></span></p>
<p><span lang="en-ca"><b>class MySet</b></span></p>
<p><span lang="en-ca"><b>{</b></span></p>
<p><span lang="en-ca"><b>private:</b></span></p>
<p><span lang="en-ca"><b>&nbsp;&nbsp;&nbsp;&nbsp; T members[MaxMemberSize];</b></span></p>
<p><span lang="en-ca"><b>&nbsp;&nbsp;&nbsp; int size;</b></span></p>
<p><span lang="en-ca"><b>...</b></span></p>
<p><span lang="en-ca"><b>};</b></span></p>
<p><span lang="en-ca"><b>What is the type of its power set? T? MySet&lt;T, 
methods&gt;? No! It is MySet&lt;MySet&lt;T,methods&gt;,methods&gt;</b></span></p>
<p><span lang="en-ca"><b>if you manage to use same &quot;methods&quot; class for both 
classes. But can you do this inside a template</b></span></p>
<p><span lang="en-ca"><b>class? It seems that you want to drive compiler to be 
insane! Can we pass template class itself</b></span></p>
<p><span lang="en-ca"><b>for the type parameter of another template class? At 
least VC++6.0 seems to be negative. However, </b></span></p>
<p><span lang="en-ca"><b>it is easy to work around after user instantiate the 
template class. Or I will try some &quot;special&quot;.</b></span></p>
<div align="left">
  <p ALIGN="LEFT">　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>A set is always a favourite topic of my programming. And 
  a set should be independent from its type.</b></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>The methods of union, intersection, and difference 
  should always be same no matter what type of </b></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>the type of the set is of.</b></span></div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>I will try to specialize the template class to remove the &quot;comparison class&quot;.</b></font></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left" style="width: 898; height: 86">
  <pre><font size="3"><b><span lang="en-ca">1. set</span>.</b></font><span lang="en-ca"><font size="3"><b>h</b></font></span></pre>
  <pre><span lang="en-ca"><font size="3"><b>2</b></font></span><font size="3"><b><span lang="en-ca">. set</span>.cpp</b></font></pre>
  <pre><span lang="en-ca"><font size="3"><b>3</b></font></span><font size="3"><b><span lang="en-ca">. methods</span>.<span lang="en-ca">h</span></b></font></pre>
  <pre><span lang="en-ca"><font size="3"><b>4</b></font></span><font size="3"><b><span lang="en-ca">. myset</span>.<span lang="en-ca">h</span></b></font></pre>
  <pre><span lang="en-ca"><font size="3"><b>5</b></font></span><font size="3"><b><span lang="en-ca">. main</span>.<span lang="en-ca">cpp</span></b></font></pre>
  <pre>　</pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: set</span>.<span lang="en-ca">h</span></b></font></pre>
  <pre>#ifndef SET_H
#define SET_H

#include &lt;iostream&gt;
#include &lt;bitset&gt;

using namespace std;


const int MaxAttrNumber=50;

class Set
{
	//this is a long-pain for me, I have no other way to 
	//let compiler recognize this &quot;friend&quot; function outside declaration
	friend ostream&amp; operator&lt;&lt;(ostream&amp; out, const Set&amp; dummy)	
	{
		for (int i=0; i&lt;dummy.size; i++)
		{
			if (dummy.theSet.test(i))
			{
				out&lt;&lt;'1';
			}
			else
			{
				out&lt;&lt;'0';
			}
		}
		return out;
	}
private:
	bitset&lt;MaxAttrNumber&gt; theSet;
	int size;
	int current;
public:
	void setSize(const Set&amp; dummy);
	int getSize(){ return size;}
	int next(int current) const;
	int first() const;	
	int count() const;
	Set intersection(const Set&amp; dummy) const;
	Set unionSet(const Set&amp; dummy) const;
	Set difference(const Set&amp; dummy) const;
	
	//I am crazy about operator overloading!!!:)
	Set operator-(const Set&amp; dummy) const;
	Set operator+(const Set&amp; dummy) const;
	Set operator*(const Set&amp; dummy) const;
	void operator=(const Set&amp; dummy);
	bool operator==(const Set&amp; dummy) const;
	bool operator!=(const Set&amp; dummy) const;
	bool operator&gt;(const Set&amp; dummy) const;
	bool operator&gt;=(const Set&amp; dummy) const;
	bool operator&lt;(const Set&amp; dummy) const;
	bool operator&lt;=(const Set&amp; dummy) const;
	void set(int pos);
	void forEachSubSet(Set&amp; dummy) const;//must be called before &quot;eachSub()&quot;
	bool eachSub(Set&amp; dummy) const;
	bool eachSub(Set&amp; dummy, const Set&amp; excluding) const;
	void set();
	void reset(int pos);
	void reset();
	bool test(int pos) const;
	bool isIn(const Set&amp; dummy) const;
	void setSize(int theSize) {size=theSize;}
	Set(int theSize=10);
};

#endif</pre>
  <pre>　</pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: set</span>.</b></font><span lang="en-ca"><font size="3" color="#FF0000"><b>cpp</b></font></span></pre>
  <pre>#include &quot;Set.h&quot;

bool Set::isIn(const Set&amp; dummy) const
{
	for (int i=0; i&lt;size; i++)
	{
		if (theSet.test(i))
		{
			if (!dummy.test(i))//here I use Set.test() instead of set.test()
			{
				return false;
			}
		}
	}
	return true;		
}

bool Set::test(int pos) const
{
	return (pos&lt;size&amp;&amp;theSet.test(pos));
}

//current=-1;//initialize to -1 to prepare for being called
int Set::next(int current) const
{
	for (int i=current+1; i&lt;size; i++)//include situation current&gt;=size
	{
		if (theSet.test(i))
		{
			return i;
		}
	}
	return -1;//not found
}

bool Set::operator !=(const Set&amp; dummy)const
{
	return !(this-&gt;operator ==(dummy));
}

bool Set::operator &lt;(const Set&amp; dummy)const
{
	return (this-&gt;isIn(dummy)&amp;&amp;this-&gt;operator !=(dummy));
}

bool Set::operator &lt;=(const Set&amp; dummy)const
{
	return isIn(dummy);
}

bool Set::operator &gt;(const Set&amp; dummy)const
{
	return !(this-&gt;operator &lt;=(dummy));
}

bool Set::operator &gt;=(const Set&amp; dummy)const
{
	return !(this-&gt;operator &lt;(dummy));
}

bool Set::operator ==(const Set&amp; dummy)const
{
	for (int i=0; i&lt;(size&gt;dummy.size?size:dummy.size); i++)
	{
		if (test(i)^dummy.test(i))
		{
			return false;
		}
	}
	return true;
}

void Set::setSize(const Set&amp; dummy)
{
	size=dummy.size;
}

void Set::operator =(const Set&amp; dummy)
{
	size=dummy.size;
	for (int i=0; i&lt;size; i++)
	{
		if (dummy.test(i))
		{
			theSet.set(i);
		}
		else
		{
			theSet.reset(i);
		}
	}
}


Set::Set(int theSize)
{
	size=theSize;
	reset();
}

void Set::reset()
{
	for (int i=0; i&lt;size; i++)
	{
		theSet.reset(i);
	}
}

void Set::reset(int pos)
{
	if (pos&lt;size)
	{
		theSet.reset(pos);
	}
}

void Set::set()
{
	theSet.set();
}

void Set::set(int pos)
{
	theSet.set(pos);
}
	
void Set::forEachSubSet(Set&amp; dummy) const
{
	dummy.size=size;
	dummy.reset();//emptyset
}

bool Set::eachSub(Set&amp; dummy, const Set&amp; excluding) const
{
	int index=first();//starting from very first

	while (index!=-1)//not exceeding boundery
	{
		if (!excluding.test(index))//exluding this set
		{
			if (dummy.test(index))
			{
				dummy.reset(index);				
			}
			else
			{
				dummy.set(index);
				//return true;
							
				if (dummy&lt;*this)//only return the proper subset
				{
					return true;
				}			
			}
		}
		index=next(index);

	}
	return false;
}


bool Set::eachSub(Set&amp; dummy) const
{
	int index=first();//starting from very first

	while (index!=-1)//not exceeding boundery
	{
		if (dummy.test(index))
		{
			dummy.reset(index);
			index=next(index);
		}
		else
		{
			dummy.set(index);
			//return true;
						
			if (dummy&lt;*this)
			{
				return true;
			}			
		}
	}
	return false;
}

int Set::first()const
{
	return next(-1);
}

int Set::count()const
{
	return theSet.count();
}

Set Set::unionSet(const Set&amp; dummy) const
{
	Set result;
	result.size=size&gt;dummy.size?size:dummy.size;
	for (int i=0; i&lt;result.size; i++)
	{
		if (test(i)||dummy.test(i))
		{
			result.set(i);
		}
	}
	return result;//this is a temparory object;
}

Set Set::difference(const Set&amp; dummy) const
{
	Set result;
	result.size=size&gt;dummy.size?size:dummy.size;
	for (int i=0; i&lt;result.size; i++)
	{
		if (test(i)&amp;&amp;!dummy.test(i))
		{
			result.set(i);
		}
	}
	return result;
}

Set Set::operator +(const Set&amp; dummy) const
{
	return unionSet(dummy);
}

Set Set::operator -(const Set&amp; dummy) const
{
	return difference(dummy);
}

Set Set::intersection(const Set&amp; dummy) const
{
	Set result;
	result.size=size&lt;dummy.size?size:dummy.size;
	for (int i=0; i&lt;result.size; i++)
	{
		if (test(i)&amp;&amp;dummy.test(i))
		{
			result.set(i);
		}
	}
	return result;
}

Set Set::operator *(const Set&amp; dummy) const
{
	return intersection(dummy);
}

</pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: board</span>.<span lang="en-ca">h</span></b></font></pre>
  <pre>#include &quot;cluster.h&quot;
#include &quot;node.h&quot;


class Board
{
	friend class Cluster;
private:
	int board [BoardSize][BoardSize];
	bool map[BoardSize][BoardSize];
	bool restrict[BoardSize][BoardSize];
	Cluster path;
	int size;
	void initialize();
	bool valid(const Coord&amp; pos);
	Direction findDir(const Coord&amp; start, const Coord&amp; end);
	Direction findNextDir(const Coord&amp; curr, Direction dir);
	bool impasse(const Coord&amp; curr, Direction dir);
	bool doPathFinding(const Coord&amp; curr, const Coord&amp; end, Direction dir);
public:
	Board(int theSize=BoardSize);
	void display();
	void displayPath(bool showPath=true);
	bool pathFinding(const Coord&amp; start, const Coord&amp; end);
	bool pathFinding(const Coord&amp; end);
	bool pathFinding2(const Coord&amp; start, const Coord&amp; end);
	void setRestrict(const Coord&amp; pos);
	void resetRestrict(const Coord&amp; pos);
};


</pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: methods</span>.<span lang="en-ca">cpp</span></b></font></pre>
  <pre>#ifndef METHODS_H
#define METHODS_H
#include &lt;stdio.h&gt;
#include &quot;myset.h&quot;

class IntMethods
{
public:
	static bool eq(int x, int y){ return x==y;}
	static void assign(int&amp; target, int operand){ target=operand;}
	static void display(int x){printf(&quot;%d&quot;, x);}
};


class IntSetMethods
{
public:
	static bool eq(int x, int y){ return x==y;}
	static void assign(int&amp; target, int operand){ target=operand;}
	static void display(int x){printf(&quot;%d&quot;, x);}
	static bool eq(const MySet&lt;int, IntSetMethods&gt;&amp; source,
		const MySet&lt;int, IntSetMethods&gt;&amp; other);
	static void assign(MySet&lt;int, IntSetMethods&gt;&amp; source, 
		const MySet&lt;int, IntSetMethods&gt;&amp; other);
	static void display(const MySet&lt;int, IntSetMethods&gt;&amp; source);
};


bool IntSetMethods::eq(const MySet&lt;int, IntSetMethods&gt;&amp; source, 
					   const MySet&lt;int, IntSetMethods&gt;&amp; other)
{
	return source==other;
}

void IntSetMethods::assign(MySet&lt;int, IntSetMethods&gt;&amp; source, 
						   const MySet&lt;int, IntSetMethods&gt;&amp;other)
{
	source=other;
}

void IntSetMethods::display(const MySet&lt;int, IntSetMethods&gt;&amp; source)
{
	printf(&quot;name:%s{ &quot;, source.getName());	
	source.display();
	printf(&quot;}&quot;);
}

#endif</pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: myset</span>.<span lang="en-ca">h</span></b></font></pre>
  <pre>#ifndef MYSET_H
#define MYSET_H

#include &lt;stdio.h&gt;
#include &quot;set.h&quot;

const int MaxSetMember=50; 
const int MaxNameLength=30;
const int UniverseIndex=0;
const int EmptyIndex=1;


template&lt;class T, class methods&gt;
class MySet
{
private:
	static int setIndex;
	static MySet&lt;T, methods&gt;* UNIVERSE;
	static MySet&lt;T, methods&gt;* EMPTY;
	int index;
	T members[MaxSetMember];
	int size;
	Set marker;
	Set receiver;
	//MySet&lt;MySet&lt;T,methods&gt;, methods&gt; power;
	char name[MaxNameLength];
	void initialize();
	void uninitialize();
	void internalAdd(const T&amp; element);//specially for UNIVERSE
	MySet&lt;T, methods&gt; retrieve(const Set&amp; mark);
public:
	MySet&lt;T, methods&gt;();
	~MySet&lt;T, methods&gt;();
	void forEachSubset();	
	bool eachSub(MySet&lt;T, methods&gt;&amp; dummy);
	int getSize(){return size;}
	void clear(){ size=0;}
	void setName(const char* theName);
	const char* getName() const{return name;}
	const MySet&lt;T, methods&gt;&amp; remove(const MySet&lt;T, methods&gt;&amp; other);
	const MySet&lt;T, methods&gt;&amp; remove(const T&amp; element);
	const MySet&lt;T, methods&gt;&amp; add(const T&amp; element);
	const MySet&lt;T, methods&gt;&amp; add(const MySet&lt;T, methods&gt;&amp; other);
	bool includes(const MySet&lt;T, methods&gt;&amp; other) const;
	bool includes(const T&amp; element) const;
	bool operator&gt;(const T&amp; element) const;
	bool operator&gt;(const MySet&lt;T, methods&gt;&amp; other) const;
	bool operator&gt;=(const MySet&lt;T, methods&gt;&amp; other) const;
	bool operator&lt;(const MySet&lt;T, methods&gt;&amp; other) const;
	bool operator&lt;=(const MySet&lt;T, methods&gt;&amp; other) const;
	bool operator ==(const MySet&lt;T, methods&gt;&amp; other) const;
	bool operator !=(const MySet&lt;T, methods&gt;&amp; other) const;
	const MySet&lt;T, methods&gt;&amp; operator=(const MySet&lt;T, methods&gt;&amp; other);
	MySet&lt;T, methods&gt; operator+(const MySet&lt;T, methods&gt;&amp; other);//union	
	MySet&lt;T, methods&gt; operator-(const MySet&lt;T, methods&gt;&amp; other);//difference
	MySet&lt;T, methods&gt; operator*(const MySet&lt;T, methods&gt;&amp; other);//intersection
	MySet&lt;T, methods&gt; operator!();
	//void calcPower();
	//void displayPower();

	void display() const;
};



template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt;* MySet&lt;T, methods&gt;::UNIVERSE=NULL;

template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt;* MySet&lt;T, methods&gt;::EMPTY=NULL;


/*
template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; UNIVERSE;

template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; EMPTY;
*/

template&lt;class T, class methods&gt;
int MySet&lt;T, methods&gt;::setIndex=-1;


/*
template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::displayPower()
{	 
	power.display();
}


template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::calcPower()
{	 
	MySet&lt;T, methods&gt; dummy;
	power.clear();
	forEachSubset();
	while (eachSub(dummy))
	{
		power.add(dummy);
	}	
}
*/


template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; MySet&lt;T, methods&gt;::retrieve(const Set&amp; mark)
{
	MySet&lt;T,methods&gt; result;
	int i=0;
	i=mark.first();
	while (i!=-1)
	{
		result.add(members[i]);
		i=mark.next(i);
	}
	return result;
}

template&lt;class T, class methods&gt;
void MySet&lt;T,methods&gt;::forEachSubset()
{
	marker.setSize(size);
	marker.set();//set all to be 1
	marker.forEachSubSet(receiver);
}

template&lt;class T, class methods&gt;
bool MySet&lt;T,methods&gt;::eachSub(MySet&lt;T,methods&gt;&amp; dummy)
{	
	while (marker.eachSub(receiver))
	{
		dummy= retrieve(receiver);
		return true;
	}
	return false;
}



//* means intersection
template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; MySet&lt;T, methods&gt;::operator *(const MySet&lt;T, methods&gt;&amp; other)
{
	MySet&lt;T, methods&gt; result;
	result=UNIVERSE - this-&gt;operator!() - !other;
	return result;
}

template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; MySet&lt;T, methods&gt;::operator !()
{
	MySet&lt;T, methods&gt; result;
	result=UNIVERSE - *this;
	return result;
}


template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; MySet&lt;T, methods&gt;::operator -(const MySet&lt;T, methods&gt;&amp; other)
{
	MySet&lt;T, methods&gt; result;
	result=*this;
	for (int i=0; i&lt;other.size; i++)
	{
		result=remove(other.members[i]);
	}
	return result;
}

template&lt;class T, class methods&gt;
const MySet&lt;T, methods&gt;&amp; MySet&lt;T, methods&gt;::remove(const MySet&lt;T, methods&gt;&amp; other)
{
	for (int i=0; i&lt;other.size; i++)
	{
		remove(other.members[i]);
	}
	return *this;
}


template&lt;class T, class methods&gt;
const MySet&lt;T, methods&gt;&amp; MySet&lt;T, methods&gt;::remove(const T&amp; element)
{	
	bool found=false;
	for (int i=0; i&lt;size; i++)
	{
		if (!found)
		{
			if (methods::eq(members[i], element))
			{
				found=true;
				size--;//then we have to check if
				if (i&lt;size)
				{
					//even we already shrink the size, still better not to copy
					methods::assign(members[i], members[i+1]);		
				}
				
			}
		}
		else
		{
			//just shift array
			methods::assign(members[i], members[i+1]);			
		}
	}
	return *this;
}

template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt; MySet&lt;T, methods&gt;::operator +(const MySet&lt;T, methods&gt;&amp; other)
{
	MySet&lt;T, methods&gt; result;
	result=*this;
	for (int i=0; i&lt;other.size; i++)
	{
		result.add(other.members[i]);
	}
	return result;
}

template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::setName(const char* theName)
{
	strcpy(name, theName);
}


template&lt;class T, class methods&gt;
const MySet&lt;T, methods&gt;&amp; MySet&lt;T, methods&gt;::operator =(const MySet&lt;T, methods&gt;&amp; other)
{
	size=other.size;
	for (int i=0; i&lt;size; i++)
	{
		methods::assign(members[i], other.members[i]);
	}
	return *this;
}



template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator &lt;(const MySet&lt;T, methods&gt;&amp; other) const
{
	//return other.&gt;*this &amp;&amp; !this-&gt;operator&gt;other;
	//return other&gt;*this;
	return other.includes(*this)&amp;&amp;!includes(other);
}

template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator &lt;=(const MySet&lt;T, methods&gt;&amp; other) const
{
	return other.includes(*this);
}

template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator ==(const MySet&lt;T, methods&gt;&amp; other) const
{
	return includes(other)&amp;&amp; other.includes(*this);
}

template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator !=(const MySet&lt;T, methods&gt;&amp; other) const
{
	return !this-&gt;operator==(other);
}


template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator &gt;(const T&amp; element) const
{
	return includes(element);
}

template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator &gt;(const MySet&lt;T, methods&gt;&amp; other) const
{
	return includes(other)&amp;&amp;!other.includes(*this);
}

template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::operator &gt;=(const MySet&lt;T, methods&gt;&amp; other) const
{
	return includes(other);
}

template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt;::~MySet&lt;T, methods&gt;()
{
	uninitialize();
}


template&lt;class T, class methods&gt;
MySet&lt;T, methods&gt;::MySet&lt;T, methods&gt;()
{
	initialize();
}

template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::uninitialize()
{
	//MySet&lt;T, methods&gt;* temp;
	if (setIndex==EmptyIndex+1)
	{
		setIndex=-1;
		delete UNIVERSE;
		delete EMPTY;
	}
	else
	{
		if (setIndex!=-1)
		{
			setIndex--;
		}
	}
/*
	if (UNIVERSE!=NULL)
	{
		temp=UNIVERSE;
		UNIVERSE=NULL;
		delete temp;
		
	}
	if (EMPTY!=NULL)
	{
		temp=EMPTY;
		EMPTY=NULL;
		delete EMPTY;		
	}
	*/
}

template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::initialize()
{
	//only run once to initialize universe and empty
	if (setIndex==-1)
	{
		setIndex++;
		index=EmptyIndex+1;;//set index=2
		UNIVERSE=new MySet&lt;T, methods&gt;;	
		UNIVERSE-&gt;setName(&quot;UNIVERSE&quot;);
		UNIVERSE-&gt;index=0;
		EMPTY=new MySet&lt;T, methods&gt;;
		EMPTY-&gt;index=1;
		EMPTY-&gt;setName(&quot;EMPTY&quot;);	
		sprintf(name, &quot;name:no. %d&quot;, index);
		size=0;
		setIndex=3;
	}
	else
	{
		//when setIndex==0
		if (setIndex==UniverseIndex)//these are for universe and empty
		{
			size=0;	
		}
		else
		{
			index=setIndex++;
			sprintf(name, &quot;name:no. %d&quot;, index);
			size=0;	
		}
	}
}


template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::includes(const T&amp; element) const
{
	for (int i=0; i&lt;size; i++)
	{
		if (methods::eq(members[i], element))
		{
			return true;
		}
	}
	return false;
}

template&lt;class T, class methods&gt;
bool MySet&lt;T, methods&gt;::includes(const MySet&lt;T, methods&gt;&amp; other) const
{
	for (int i=0; i&lt;other.size; i++)
	{
		if (!includes(other.members[i]))
		{
			return false;
		}
	}
	return true;
}


//these are what the name suggests, alter the set itself
template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::internalAdd(const T&amp; element)
{
	if (!includes(element))
	{
		methods::assign(members[size++], element);
	}
}

template&lt;class T, class methods&gt;
const MySet&lt;T, methods&gt;&amp; MySet&lt;T, methods&gt;::add(const T&amp; element)
{
	if (!includes(element))
	{
		methods::assign(members[size++], element);
		UNIVERSE-&gt;internalAdd(element);//make sure it is in universe set
	}
	return *this;
}

template&lt;class T, class methods&gt;
const MySet&lt;T, methods&gt;&amp; MySet&lt;T, methods&gt;::add(const MySet&lt;T, methods&gt;&amp; other)
{
	for (int i=0; i&lt;other.size; i++)
	{
		add(other.members[i]);
	}
	return *this;
}


template&lt;class T, class methods&gt;
void MySet&lt;T, methods&gt;::display() const
{
	//cout&lt;&lt;name&lt;&lt;&quot;:{&quot;;
	printf(&quot;%s\n{&quot;, name);
	for (int i=0; i&lt;size; i++)
	{
		methods::display(members[i]);
		if (i!=size-1)
		{
			printf(&quot;,&quot;);
		}
	}
	//cout&lt;&lt;&quot;}\n&quot;;
	printf(&quot;}\n&quot;);
}

#endif</pre>
  <pre>　</pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: main</span>.<span lang="en-ca">cpp</span></b></font></pre>
</div>
<pre>#include &lt;iostream&gt;
#include &quot;myset.h&quot;
#include &quot;methods.h&quot;

using namespace std;

const int DataLength=5;


#define IntSet MySet&lt;int, IntSetMethods&gt;
#define IntSetSet MySet&lt;IntSet, IntSetMethods&gt;

int data[DataLength]={3,2,4,7,1,};
 
void calcPower(IntSet&amp; dummy, IntSetSet&amp; result);

int main()
{
	//MySet&lt;int, IntSetMethods&gt; A, B, C;
	IntSet A,B,C;
	//MySet&lt;MySet&lt;int, IntSetMethods&gt;, IntSetMethods&gt; P;
	IntSetSet P;
	A.setName(&quot;set name is A&quot;);
	B.setName(&quot;set name is B&quot;);
	P.setName(&quot;the Power set of A&quot;);
	for (int i=0; i&lt;DataLength; i++)
	{
		A.add(data[i]);
		if (i%2==0)
		{
			B.add(data[i]);
		}
	}
	A.display();
	B.display();
	calcPower(A, P);
	P.display();
	//A.calcPower();
	//A.displayPower();
/*
	if (A&lt;=B)
	{
		cout&lt;&lt;&quot;A&lt;=B\n&quot;;
	}
	else
	{
		if (B&lt;A)
		{
			cout&lt;&lt;&quot;B&lt;A\n&quot;;
		}
		if (B&lt;=A)
		{
			cout&lt;&lt;&quot;B&lt;=A\n&quot;;
		}
		if (A==B)
		{
			cout&lt;&lt;&quot;A==B\n&quot;;
		}
		if (A!=B)
		{
			cout&lt;&lt;&quot;A!=B\n&quot;;
		}
	}
		
	printf(&quot;for each subset\n&quot;);
	P.clear();
	A.forEachSubset();
	while (A.eachSub(C))
	{
		P.add(C);
		//C.display();
	}
	P.display();
*/	
	return 0;
}


void calcPower(IntSet&amp; dummy, IntSetSet&amp; result)
{
	IntSet temp;
	result.clear();
	dummy.forEachSubset();
	while (dummy.eachSub(temp))
	{
		result.add(temp);
	}
}
</pre>
<pre></pre>
<pre><b><font color="#0000FF"><span lang="en-ca"><a name="result"></a>The result is like following:</span></font></b></pre>

<pre>set name is A
{3,2,4,7,1}
set name is B
{3,4,1}
the Power set of A
{name:name:no. 5{ name:no. 5
{3}
},name:name:no. 6{ name:no. 6
{2}
},name:name:no. 7{ name:no. 7
{3,2}
},name:name:no. 8{ name:no. 8
{4}
},name:name:no. 9{ name:no. 9
{3,4}
},name:name:no. 10{ name:no. 10
{2,4}
},name:name:no. 11{ name:no. 11
{3,2,4}
},name:name:no. 12{ name:no. 12
{7}
},name:name:no. 13{ name:no. 13
{3,7}
},name:name:no. 14{ name:no. 14
{2,7}
},name:name:no. 15{ name:no. 15
{3,2,7}
},name:name:no. 16{ name:no. 16
{4,7}
},name:name:no. 17{ name:no. 17
{3,4,7}
},name:name:no. 18{ name:no. 18
{2,4,7}
},name:name:no. 19{ name:no. 19
{3,2,4,7}
},name:name:no. 20{ name:no. 20
{1}
},name:name:no. 21{ name:no. 21
{3,1}
},name:name:no. 22{ name:no. 22
{2,1}
},name:name:no. 23{ name:no. 23
{3,2,1}
},name:name:no. 24{ name:no. 24
{4,1}
},name:name:no. 25{ name:no. 25
{3,4,1}
},name:name:no. 26{ name:no. 26
{2,4,1}
},name:name:no. 27{ name:no. 27
{3,2,4,1}
},name:name:no. 28{ name:no. 28
{7,1}
},name:name:no. 29{ name:no. 29
{3,7,1}
},name:name:no. 30{ name:no. 30
{2,7,1}
},name:name:no. 31{ name:no. 31
{3,2,7,1}
},name:name:no. 32{ name:no. 32
{4,7,1}
},name:name:no. 33{ name:no. 33
{3,4,7,1}
},name:name:no. 34{ name:no. 34
{2,4,7,1}
}}
Press any key to continue</pre>

<pre><span lang="en-ca">				</span> <a href="game24.htm"><img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35"> </pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp;</p>

</body>

</html>