<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>Sort 
Machine</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 <span lang="en-ca">my first edition of a sort machine which is a class doing both trimming and sorting of a string.</span></b></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>
<div align="left">
  <span lang="en-ca"><b>Write a function to sort a character string in ascending 
  alphabetic order.</b></span></div>
<div align="left">
  <span lang="en-ca"><b><br>
  The function should also convert all lower case letter to upper case letter.
  </b></span></div>
<div align="left">
  <span lang="en-ca"><b><br>
  You should remove all characters that are not alphabetic (i.e. take out 
  spaces,</b></span></div>
<div align="left">
  <span lang="en-ca"><b><br>
  numbers, and punctuation).<br>
  <br>
  The function must receive a pointer to the string, and return a pointer to </b>
  </span></div>
<div align="left">
  <span lang="en-ca"><b><br>
  the string. Recall that strings end in '\0' and you should not sort this 
  character.<br>
  <br>
  For example the string &quot;This is a string!&quot;, should be sorted as &quot;AGHIIINRSSSTT&quot;.<br>
  <br>
  (Hint: You can use the bubble sort algorithm.)<br>
  <br>
  Write a driver program to test your function.</b></span></div>
<div align="left">
  กก</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">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">
  <pre><span lang="en-ca"><b>There are two major feature about my class as mentioned in the remark part of my program:</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>1. I made the storage of string flexible by implementing it like dynamic array so that it can increase length</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>according to input. I defined constant &quot;MaxLength&quot; for class which must be passed in and initialized before</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>constructor. Then by record number of &quot;relocating&quot;, I can increase one &quot;MaxLength&quot; every time my string found</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>out it need more memory. At destructor, the dynamic allocated memory is freed.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>2. I made several flags for my class so that programmer can choose different sorting algorithms like bubble</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>sort, quick sort etc. and sorting type as ascending or descending. </b></span></pre>
</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><b>1. char* SortMachine::trimStr(const char* const str)</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>It first trims off all other char except letters, also make all them big cases. As the passing parameter str </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>can not be changed in any way, I made both the contents and pointer itself const. During trimming, it checks</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>the length of input string, see if the length exceeds size of my array, a &quot;relocate&quot; is called by add more </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>space to original array. So it is like the way of dynamic array.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>2. SortMachine::SortMachine(const char* const str, int defaultLength)</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>This constructor with defaultLength which is used to initialize the constant &quot;MaxLength&quot;.</b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b>1. add more sorting algorithms<span lang="en-ca">.  </span></b></pre>
</div>
<div align="left">
  <pre><b>2. make it more general so that any type of data can be sort,<span lang="en-ca"> </span>not only char<span lang="en-ca">.</span></b></pre>
</div>
<pre>กก</pre>
<pre>/***************************************************************************
////Author: Qingzhe Huang
////Date: Jul 13, 2003
////Name of program: Sorting Machine
///////////////////////////////////////////////////////////////////////////

I arbitarily made my program a class, as I see some opportunity that it is fairly 
a common job to do sorting for a string, plus some extra job like &quot;trimming&quot;.
And what's more I made my string a kind of &quot;dynamic&quot; array which can increase 
length according input by &quot;realloc&quot; new length of mem to sting pointer.
Basically there two major features of my class:
	1. In my class, I set up several flag to enable it to sort in different algorithms, 
	like bubble sort, quick sort and maybe more in future. Also, I make it possible to
	sort it in both ascending and descending by open a method called &quot;setParam&quot; which 
	allow program to set all sorting parameters---sortType, isAscending, maybe more in
	future.
	2. For the trimming part, I made a my array like dynamic array so that it can increase 
	automatically realloc memory by adding  20 bytes more to old size. So, I defined a
	constant &quot;MaxLength&quot; and use the method introduced in lecture to initialize it 
	before constructor. A &quot;relocCounter&quot; to record how many times reloc is invoked, so
	by increment this counter, 20 more bytes are added to &quot;reallocate&quot; for string.
	And this 20bytes is passed by default in constructor to set the constant &quot;MaxLength&quot;, 
	so it is also changeable by programmer.
	At destructor, the dynamic allocated memory is freed.
/////////////////////////////////////////////////////////////////////////////
////Possible improvement: 
// 1. add more sorting algorithms
// 2. make it more general so that any type of data can be sort,not only char
****************************************************************************/

#include &lt;iostream&gt;

using namespace std;

enum SortType
{BubbleSort, QuickSort};

class SortMachine
{
private:
	const int MaxLength; //default pre-allocate array length
	int relocCounter;//record number of reloc in case string length is longer than size
	char* myStr;
	bool ascending;  //default is ascending, however, you can set by setParam
	SortType sortType; //enum indicate bubbleSort or quickSort
	int size; //it is the size of mem alloc for str, not length, 
	int length;//this is indeed the length of myStr
	void doQuickSort(int start, int end);
	int partition(int start, int end); //I am not sure if it is better to put in protected
	void swap(int i, int j);//because like these functions should be deriveable in child class
	bool smaller(int i, int j);//this is an ackward method to implement descending 
	bool smallerEqual(int i, int j);
protected:
	//I put all initialize part here instead of constructor, simply because it is a painful
	//in c++ that you cannot control the constructor of parent class, they are always called
	//not like in Delphi,you can have fully control of ancestor's constructor
	//so, in this case, all derived class can have opportunity to modify the ancestor's
	//initialize method, where if put in constructor, you cannot do it.
	void initialize();
	//the passed parameter should not be changed either value or pointer itself
	char* trimStr(const char* const str);
	void relocStr();
	void quickSort();
	void bubbleSort();
public:
	SortMachine(int defaulLength = 20);
	SortMachine(const char* const str, int defaultLength =20);
	~SortMachine();
	void setStr(const char* const str);//it trims and assign to myStr
	void setParam(SortType mySortType = BubbleSort, bool isAscending = true);
	const char* getStr() { return myStr;}
	void sortStr();
};

int main()
{
	SortMachine s;
	char str[80];
	cin.getline(str, 80);
	s.setStr(str);
	s.setParam(QuickSort, false);
	s.sortStr();
	cout&lt;&lt;s.getStr()&lt;&lt;endl;

	return 0;
}

//this is put into protected as derived class may need to modify
void SortMachine::initialize()
{
	//it is absurd to use this name to represent how many times reloc happened, 
	relocCounter =0; 
	ascending = true;
	sortType = BubbleSort;
	size = 0;
	myStr = NULL;
}

//this constructor with only a default size of 
SortMachine::SortMachine(int defaultLength)
:MaxLength(defaultLength) //initialize constant in class
{
	initialize();
}

//the constructor with both input str and default length of my array
SortMachine::SortMachine(const char* const str, int defaultLength)
:MaxLength(defaultLength)//initialize constant in class
{
	initialize();
	myStr = trimStr(str);
}

//we need to free the memory what allocated
SortMachine::~SortMachine()
{
	free((void*)(myStr));
}

void SortMachine::setStr(const char* const str)
{
	myStr = trimStr(str);
}

//as the str is not supposed to be changed either contents or itself, I made const both ways
char* SortMachine::trimStr(const char* const str)
{
	int counter =0;
	char* target;
	char* source;

	//first make sure user is not naughty
	if (str==NULL)
	{
		return NULL;
	}
	//this is the default size of mystr
	size = MaxLength;//at first it is MaxLength
	myStr =(char*)malloc(size);

	target = myStr;
	source = (char*)str;

	while (*source!=NULL)
	{
		if (*source&gt;='A'&amp;&amp;*source&lt;='Z')//I prefer not to use ASCII number for compatible reason
		{
			*target = *source;
			target++;
			counter++;
			
			//this means we must reloc mem for myStr, as NULL is not write at end
			if (counter==size)			
			{
				relocStr();
				target = myStr+counter; //restore position of target
			}
		}
		else
		{
			if (*source&gt;='a'&amp;&amp;*source&lt;='z')//I prefer not to use ASCII number for compatible
			{
				*target = *source + 'A' - 'a';//it is better not use ASCII number
				target++;
				counter++;
				if (counter==size)			
				{
					relocStr();
					target = myStr+counter; //restore position of target
				}
			}
		}
		source++;//in any case, we move to next char
	}
	*target = NULL; //write last NULL at end.
	length = counter;
	return myStr;
}

void SortMachine::relocStr()
{
	char* temp;
	relocCounter++;
	size = (1+relocCounter)*MaxLength;
	//better to test before assign myStr, so, if exception, we didn't destroy what we have
	//I read this from some book
	temp = (char*)realloc((void*)(myStr), size);
	if (temp!=NULL)
	{
		myStr = temp;
	}
	else
	{
		cout&lt;&lt;&quot;Fail to reloc!&quot;;
	}
}

void SortMachine::sortStr()
{
	switch (sortType)
	{
	case BubbleSort:
		bubbleSort();
		break;
	case QuickSort:
		quickSort();
		break;
	}
}

void SortMachine::setParam(SortType mySortType, bool isAscending)
{
	sortType = mySortType;
	ascending = isAscending;
}

void SortMachine::quickSort()
{
	doQuickSort(0, length-1);
}

void SortMachine::doQuickSort(int start, int end)
{
	int pos;
	if (start&lt;end)
	{
		pos = partition(start, end);
		doQuickSort(start, pos-1);
		doQuickSort(pos+1, end);
	}
}

int SortMachine::partition(int start, int end)
{
//	char ch;
	int i;
	i = start-1;
//	ch = myStr[end];
	for (int j=start; j&lt;end; j++)
	{
		//if (myStr[j]&lt;=ch)
		if (smallerEqual(j, end))
		{
			i++;
			swap(i,j);		
		}
	}
	swap(i+1, j);
	return i+1;
}

void SortMachine::bubbleSort()
{	
	for (int i=0; i&lt; length-1; i++)
	{
		for (int j=i+1; j&lt;length; j++)
		{
			//if (myStr[i]&gt;myStr[j])
			if (smaller(j, i))
			{
				//swap
				swap(i, j);
			}
		}
	}
}

void SortMachine::swap(int i, int j)
{
	char ch;
	if (i!=j)
	{
		ch = myStr[i];
		myStr[i] = myStr[j];
		myStr[j] = ch;
	}
}

//I made this to make descending sorting possible
bool SortMachine::smaller(int i, int j)
{
	if (ascending)
	{
		return myStr[i]&lt;myStr[j];
	}
	else
	{
		return myStr[i]&gt;=myStr[j];
	}
}

//I made this to make descending sorting possible
bool SortMachine::smallerEqual(int i, int j)
{
	if (ascending)
	{
		return myStr[i]&lt;=myStr[j];
	}
	else
	{
		return myStr[i]&gt;myStr[j];
	}
}




</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; <a href="WhoAmI.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>