<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>Population</title>
</head>

<body>



<p align="center"><span lang="en-ca"><font size="6" color="#FF0000"><b>Relation</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>This is the <span lang="en-ca">first</span> edition of my </b><span lang="en-ca"><b>Relation class and it has been lingering in my mind for a long time. </b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Idea of program</b></font></span></pre>
</div>
<div align="left">
  <pre><b>1¡£ Basic idea: </b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>Relation is indeed a kind of Logic Set which use a pair of elements from set A and Set B to act as its elements</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>according to a certain condition. Or in other word, Relation is a set of element pairs of which the elements </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>of each pair comes from two other sets. So, it is quite natural to inherent from LogicSets. However, it is </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>much complicated than a LogicSet as a pair is an element of another set, we need to define a struct of pair, </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>and we need to add a condition.   </b></span></pre>
</div>
<div align="left">
  <pre><b>2¡£ Program design: </b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca">I used so many &quot;call-back&quot; global functions that I even feel hopeless to go on. It is a pain that I cannot use member function</span></pre>
  <pre><span lang="en-ca">as call back function, which in Delphi is a possible. (I think, but now memory is blurred.)</span></pre>
  <pre><b>3¡£ Major function</b></pre>
  <blockquote>
    <blockquote>
  <pre><b> A.<span lang="en-ca">  LogicSets* Relation::operator *(LogicSets&amp; B)</span></b></pre>
  <pre><span lang="en-ca">This is the only function I implemented. Simply overload * operator and in the call back function, I use a simple </span></pre>
  <pre><span lang="en-ca">condition to make sure element from A is bigger than element from B.</span></pre>
  <pre><b><span lang="en-ca">B. void LogicSets::forEach(void (*checkEach)(Elements* each, void* data1, void* data2),
    void* data1, void* data2)</span></b></pre>
  <pre><span lang="en-ca">This is a expanded version of forEach function, for which I add two more parameters, so that I can pass element from</span></pre>
  <pre><span lang="en-ca">A and Relation as two parameters when called from second Set. (Confusing? I think it is really unnecessary since</span></pre>
  <pre><span lang="en-ca">I limiting myself by forbidding access private data of LogicSets, so I have to use call back function to visit </span></pre>
  <pre><span lang="en-ca">each elements in relation.</span></pre>
    </blockquote>
  </blockquote>
  <pre><b><font size="2">4¡£ Further improvement£º</font></b></pre>
  <pre><b>	A. <span lang="en-ca">This is actually not like a class!!! What have I done???</span></b></pre>
</div>
<pre>#include &lt;iostream&gt;

using namespace std;

template&lt;class T&gt;
class mylist
{
private:
	T *flist;
	int LENGTH;
	int SIZE;
	int counter;
protected:
	void uninitialize();
	void initialize();
	bool checksize();
	void expand();
	int locate(T ptr);
public:
	mylist();
	~mylist();
	void add(T ptr);
	bool find(T ptr);
	void display();
	int count();
	T&amp; items(int index);
	void insert(int index, T ptr);

};

//actually sets and elements are just like problem of &quot;egg&quot; and &quot;chicken&quot;, we do
//know who comes first, they should always comes together, except the emptySets who has 
//no elements at all

class LogicSets;//forward definition

class Elements
{
	void* data;
	long ID;  //plan to use address to represent as ID
	char* name;
	LogicSets* parent;
public:
	LogicSets* belong() { return parent; }
	void setData(void* newData) {data = newData;}
	void* getData() { return data;}
	char* getName() { return name;}
	void setName(const char* givenName);
	bool belong(LogicSets* father){ return father== parent;}
	void setParent(LogicSets* father) { parent = father;}
	Elements(LogicSets* father);
	Elements();
	~Elements();	
};



class LogicSets 
{
private:
	mylist&lt;Elements*&gt; lst;
	//I don't want programmer to use this method
	void create(char* givenName);
public:
	bool include(Elements* pElement);
	void add(Elements* pElement);	
	//call back function &quot;for all&quot;
	bool forAll( bool (*checkEach)(Elements* each)); 
	//call back function &quot;exist&quot;
	bool exists( bool (*checkEach)(Elements* each)); 
	//call back function for general purpose
	void forEach( void (*checkEach)(Elements* each)); 
	//a more powerful call-back function for inputting user data
	void forEach(void (*checkEach)(Elements* each, void* data1, void* data2),  void* data1, void* data2);
	~LogicSets();
};

void destroyElements(Elements* each)
{
	//this is a programmer's job to destroy each element by his own way.
	//I just leave it for an example as following:
	delete((void*)(each));	
}

struct Pair
{
	Elements* x;
	Elements* y;
};

class Relation: public LogicSets
{
public:
	LogicSets* operator*(LogicSets&amp; B); //AxB
	~Relation();
};

void putY(Elements* yPtr, void* xPtr, void* rln)
{
	int *a, *b;
	a = (int*)(((Elements*)(xPtr))-&gt;getData());
	b = (int*)(yPtr-&gt;getData());
	if (*a &gt; *b)
	{
		Elements* rlnElement= new Elements((LogicSets*)(rln));
		Pair* pair = new Pair;

		pair-&gt;x = (Elements*)(xPtr);
		pair-&gt;y = yPtr;
		rlnElement-&gt;setData((void*)(pair));
		((Relation*)(rln))-&gt;add(rlnElement);
	}
}

void destroyPair(Elements* each)
{
	free(each-&gt;getData());
}

void putX(Elements* x, void* setB, void* rln)
{
	LogicSets* setPtr;
	setPtr = (LogicSets*)(setB); 
	setPtr-&gt;forEach(putY, (void*)(x), rln);
}


//to check all if all are string like &quot;this is no.5&quot;
bool allCheck(Elements* each)
{
	//this function should be user or programme defined
	return strcmp(each-&gt;getName(), &quot;this is no.5&quot;) == 0;
}

bool existCheck(Elements* each)
{
	//this function should be user or programme defined
	return strcmp(each-&gt;getName(), &quot;this is no.5&quot;) == 0;
}

void showEach(Elements* each)
{
	//this function should be user or programme defined
	cout&lt;&lt;&quot;\n&quot;&lt;&lt;each-&gt;getName()&lt;&lt;&quot; is &quot;;
	cout&lt;&lt;*((int*)(each-&gt;getData()))&lt;&lt;endl;
}

void showPair(Elements* each)
{
	Pair* p;
	p = (Pair*)(each-&gt;getData());
	cout&lt;&lt;&quot;\nthis pair is:\n&quot;;
	cout&lt;&lt;p-&gt;x-&gt;getName()&lt;&lt;&quot; is &quot;&lt;&lt;*((int*)(p-&gt;x-&gt;getData()))&lt;&lt;&quot;\t&quot;;
	cout&lt;&lt;p-&gt;y-&gt;getName()&lt;&lt;&quot; is &quot;&lt;&lt;*((int*)(p-&gt;y-&gt;getData()))&lt;&lt;endl;
}


int main()
{
	const Number = 5;
	Relation A, B;
	Relation *C;
	Elements elementA[Number];
	Elements elementB[Number];
	int dataA[Number];
	int dataB[Number];
	char bufferA[4];
	char bufferB[4];
	char buffer[3];

	for (int i=0; i&lt; Number; i++)
	{
		dataA[i] = rand()%100;
		dataB[i] = rand()%200;
		elementA[i].setData((void*)(dataA+i));
		itoa(i, buffer, 10);
		strcpy(bufferA, &quot;A&quot;);
		strcpy(bufferB, &quot;B&quot;);
		strcat(bufferA, buffer);
		strcat(bufferB, buffer);
		elementA[i].setName(bufferA);
		elementB[i].setName(bufferB);
		elementB[i].setData((void*)(dataB+i));
		A.add(elementA+i);
		B.add(elementB+i);
	}
	C = (Relation*)(A*B);
	cout&lt;&lt;&quot;Now show set A\n&quot;;
	A.forEach(showEach);
	cout&lt;&lt;&quot;Now show set B\n&quot;;
	B.forEach(showEach);
	cout&lt;&lt;&quot;Now show Relation C\n&quot;;
	C-&gt;forEach(showPair);

	return 0;
}


Relation::~Relation()
{
	//forEach(destroyPair);
}

LogicSets* Relation::operator *(LogicSets&amp; B)
{
	LogicSets* R = new LogicSets;
	this-&gt;forEach(putX, (void*)(&amp;B), (void*)(R));
	return R;
}

void LogicSets::forEach(void (*checkEach)(Elements* each, void* data1, void* data2),
						void* data1, void* data2)
{
	for (int i=0; i&lt; lst.count(); i++)
	{
		checkEach(lst.items(i), data1, data2);
	}
}




LogicSets::~LogicSets()
{
	/*
	for (int i=0; i&lt;lst.count(); i++)
	{
		delete lst.items(i);
	}
	*/
}

void LogicSets::forEach(void (*checkEach)(Elements* each))
{
	for (int i = 0; i&lt; lst.count(); i++)
	{
		checkEach(lst.items(i));
	}
}


Elements::~Elements()
{
	if (name!=NULL)
	{
		free(name);
	}
	
}


void Elements::setName(const char* givenName)
{
	name = (char*)malloc(strlen(givenName)+1);
	strcpy(name, givenName);
}

Elements::Elements()
{
	parent = NULL;
	data = NULL;
	ID = 0;
	setName(&quot;no name, no father&quot;);
}
Elements::Elements(LogicSets* father)
{
	parent = father; 
	data = NULL;
	ID = (long)(this); //use add as ID
	setName(&quot;no name&quot;);
}

//nobody should use this method, otherwise nobody will do  the retrieve mem job
void LogicSets::create(char* givenName)
{
	Elements* ptr;
	ptr = new Elements(this);
	ptr-&gt;setParent(this);
	ptr-&gt;setName(givenName);
	lst.add(ptr);
}

void LogicSets::add(Elements* pElement)
{
	lst.add(pElement);
	pElement-&gt;setParent(this);
}

bool LogicSets::forAll(bool (*checkEach)(Elements* each))
{
	for (int i=0; i&lt; lst.count() - 1; i++)
	{
		if (!checkEach(lst.items(i)))
		{
			return false;
		}
	}
	return true;
}

bool LogicSets::exists(bool (*checkEach)(Elements* each))
{
	for (int i=0; i&lt; lst.count() - 1; i++)
	{
		if (checkEach(lst.items(i)))
		{
			return true;
		}
	}
	return false;
}



//dynamic list

template&lt;class T&gt;
void mylist&lt;T&gt;::insert(int index, T ptr)
{
	if (!checksize())
		expand();

	if (counter == 0)
	{
		items(0) = ptr;
		counter++;
	}
	else
	{
		if (index&gt;=0&amp;&amp; index&lt;=counter)
		{
			int i=index;
			T hold1 = items(index), hold2= items(index+1);
			while (i&lt;counter)
			{	
				hold2 = items(i+1);
				items(i+1) = hold1;
				hold1 = hold2;				
				i++;
			}
			items(index) = ptr; //any exception trap???
			counter++;
		}
	}
}
			
template&lt;class T&gt;
int mylist&lt;T&gt;::locate(T ptr)
{
	int index = 0;
	while (items(index) &lt;ptr &amp;&amp;index &lt;counter)
	{
		index++;
	}
	return index;
}



template&lt;class T&gt;
bool mylist&lt;T&gt;::find(T ptr)
{
	int index = 0;

	index = locate(ptr);
	if (index == counter)
	{
		return false;
	}
	else
	{
		return (items(index) == ptr);
	}
}


template&lt;class T&gt;
int mylist&lt;T&gt;::count()
{
	return counter;
}

template&lt;class T&gt;
T&amp; mylist&lt;T&gt;::items(int index)
{
	return flist[index];
}


template&lt;class T&gt;
void mylist&lt;T&gt;::display()
{
	cout&lt;&lt;setiosflags(ios::showpoint|ios::fixed);
	for (int i = 0; i &lt; counter; i ++)
	{
		cout&lt;&lt;&quot;Number &quot;&lt;&lt;i&lt;&lt;&quot; item is:&quot;&lt;&lt;flist[i]&lt;&lt;endl;
	}
}

template&lt;class T&gt;
void mylist&lt;T&gt;::uninitialize()
{
	free(flist);
}

template&lt;class T&gt;
mylist&lt;T&gt;::~mylist()
{
	uninitialize();
}


template&lt;class T&gt;
void mylist&lt;T&gt;::add(T ptr)
{ 
	int index;
	index = locate(ptr);
	if (items(index)!=ptr)
	{
		insert(index, ptr);
	}
}

template&lt;class T&gt;
void mylist&lt;T&gt;::initialize()
{
	LENGTH = 10;
	SIZE = LENGTH;
	if ((flist =(T*)(malloc(sizeof(T) * SIZE)))==NULL)
		cout&lt;&lt;&quot;Unable malloc memory for size of &quot;&lt;&lt;SIZE&lt;&lt;endl;  //exception need to be handled here!!
	counter = 0;
}

template&lt;class T&gt;
bool mylist&lt;T&gt;::checksize()
{
	return (counter &lt; SIZE);
}

template&lt;class T&gt;
void mylist&lt;T&gt;::expand()
{
	SIZE += LENGTH;
	if ((flist = (T*)(realloc(flist, sizeof(T) * SIZE)))== NULL)
		cout&lt;&lt;&quot;Unable realloc memory for mylist of size &quot;&lt;&lt;SIZE&lt;&lt;endl;
}

template&lt;class T&gt;
mylist&lt;T&gt;::mylist()
{
	initialize();
}

</pre>
<pre>¡¡</pre>

<p><font color="#FF0000"><b> <span lang="en-ca">This simple output result demonstrate the 
relation actually choose all elements from A as first</span></b></font></p>

<p><span lang="en-ca"><font color="#FF0000"><b>element in each pair, and 
elements from B as second in each pair by condition that first element </b>
</font></span></p>

<p><span lang="en-ca"><font color="#FF0000"><b>is bigger that second element</b></font></span><font color="#FF0000"><b><span lang="en-ca">:</span></b></font></p>

<p><span lang="en-ca"> Now show set A<br>
<br>
A0 is 41<br>
<br>
A1 is 34<br>
<br>
A2 is 69<br>
<br>
A3 is 78<br>
<br>
A4 is 62<br>
Now show set B<br>
<br>
B0 is 67<br>
<br>
B1 is 100<br>
<br>
B2 is 124<br>
<br>
B3 is 158<br>
<br>
B4 is 64<br>
Now show Relation C<br>
<br>
this pair is:<br>
A3 is 78 B4 is 64<br>
<br>
this pair is:<br>
A3 is 78 B0 is 67<br>
<br>
this pair is:<br>
A2 is 69 B4 is 64<br>
<br>
this pair is:<br>
A2 is 69 B0 is 67<br>
<br>
¡¡</span></p>

<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="Monopoly.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">          


</p>

</body>

</html>