<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>filetrans</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;&nbsp;&nbsp; </b></font><span lang="en-ca">
<font size="6" color="#FF0000"><b>Lempel-Ziv</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">the first trial of Lempel-Ziv compression algorithm and I only finished the encoding. The decoding is </span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>a bit complicated and only half-finished. I am very hungry for my brunch.</b></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 ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>How to compress a text 
file? Lempel-Ziv is said to be the algorithm used in &quot;winzip&quot;. </b></font>
</span></p>
<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">
  <p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>I used my favourite </b>
  </font></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>linked list to store each 
  character as I am strongly disagree to store each string in memory which 
  wastes not</b></font></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>only space but also 
  searching running time, especially strings are clustered with similarity. For 
  example, </b></font></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>strings like &quot;ABCDE&quot;, 
  &quot;ABC&quot;, &quot;ABCD&quot; will only be stored with the largest string &quot;ABCDE&quot;. </b></font>
  </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>กก</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">
  <pre><span lang="en-ca"><font size="4" color="#FF0000"><b>project client:</b></font></span></pre>
</div>
<div align="left">
  <pre><font size="3"><b>1<span lang="en-ca">. main.cpp</span></b></font></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: main.cpp</b></font></span></pre>
</div>
<pre>#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;stdio.h&gt;

const int MaxStringLength=128;
const int MaxBufferLength=1024;
const int MaxAlphabetNumber=3;
//assume alphabet is not case sensitive


struct Token
{
	char value;
	int index;
	Token* next[MaxAlphabetNumber];
};

class Lempel
{
private:
	char buffer[MaxStringLength];
	char codeBuf[MaxBufferLength];
	Token tokens[MaxAlphabetNumber];
	void initialize();
	FILE* in, *out;
	int curIndex;
	Token* createToken(char ch);
	void doDisplay(Token* ptr, int level);
	void releaseAll(Token* ptr);
	char readChar();
	bool doFindIndex(Token* ptr, int level, int index);
	bool findIndex(int index);
	void addStr(char* str);
	void findToken(char* str, Token*&amp; result);
	void openFile(char* fileName, char* outFile);

public:
	int readToken();
	~Lempel();
	Lempel();
	void encode(char* fileName);
	void decode(char* fileName);
	void display();

};


int main()
{
	Lempel L;
	L.encode(&quot;nick.txt&quot;);
	L.display();

	return 0;
}

void Lempel::openFile(char* fileName, char* outFile)
{
	if ((in=fopen(fileName, &quot;r&quot;))==NULL)
	{
		printf(&quot;wrong file name %s\n&quot;, fileName);
		exit(0);
	}
	if ((out=fopen(outFile, &quot;w&quot;))==NULL)
	{
		printf(&quot;unable write file %s\n&quot;, outFile);
		exit(0);
	}
}

void Lempel::findToken(char* str, Token*&amp; result)
{
	char* ptr=str;
	result=&amp;tokens[*ptr-'A'];
	ptr++;
	while (*ptr!='\0')
	{
		result=result-&gt;next[*ptr-'A'];
		ptr++;
	}
}

void Lempel::addStr(char* str)
{
	char temp[MaxStringLength];
	char ch;
	Token* ptr;
	int len=strlen(str);
	strcpy(temp, str);
	ch=temp[len-1];
	temp[len]='\0';
	findToken(temp, ptr);
	ptr=createToken(ch);
}





bool Lempel::findIndex(int index)
{
	int level;
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{
		level=0;
		if (doFindIndex(tokens+i, level, index))
		{
			//the string is stored in buffer
			return true;
		}
	}
	return false;
}




bool Lempel::doFindIndex(Token* ptr, int level, int index)
{	
	buffer[level]=ptr-&gt;value;
	if (ptr-&gt;index==index)
	{
		buffer[level+1]='\0';
		return true;
	}
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{
		if (ptr-&gt;next[i]!=NULL)
		{
			if (doFindIndex(ptr-&gt;next[i], level+1, index))
			{
				return true;
			}
		}
	}
	return false;
}





void Lempel::decode(char* fileName)
{

	openFile(fileName, &quot;decoded.txt&quot;);


}


void Lempel::doDisplay(Token* ptr, int level)
{
	buffer[level]=ptr-&gt;value;
	buffer[level+1]='\0';
	printf(&quot;%s:%d\n&quot;, buffer, ptr-&gt;index);
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{		
		if (ptr-&gt;next[i]!=NULL)
		{
			doDisplay(ptr-&gt;next[i], level+1);			
		}
	}

}


void Lempel::display()
{
	int level;
	Token* curPtr;
	printf(&quot;\nNow display the table\n&quot;);
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{
		curPtr=&amp;tokens[i];
		level=0;
		//buffer[level]=curPtr-&gt;value;
		doDisplay(curPtr, level);	
	}
}

Lempel::Lempel()
{
	initialize();
}

char Lempel::readChar()
{
	char ch;
	ch=fgetc(in);
	while (ch&gt;('A'+MaxAlphabetNumber)||ch&lt;'A')
	{
		ch=fgetc(in);
		if (feof(in))
		{
			break;
		}
	}
	return ch;
}

void Lempel::releaseAll(Token* ptr)
{
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{
		if (ptr-&gt;next[i]!=NULL)
		{
			releaseAll(ptr-&gt;next[i]);
			delete ptr-&gt;next[i];
			ptr-&gt;next[i]=NULL;
		}		
	}
}


Lempel::~Lempel()
{
	Token* ptr;
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{
		ptr=&amp;tokens[i];
		releaseAll(ptr);
	}
}


void Lempel::initialize()
{
	for (int i=0; i&lt;MaxAlphabetNumber; i++)
	{
		tokens[i].value='A'+i;
		tokens[i].index=i;
		for (int j=0; j&lt;MaxAlphabetNumber; j++)
		//memset(tokens[i].next, NULL, MaxAlphabetNumber);
		{
			tokens[i].next[j]=NULL;
		}
	}
	curIndex=i;
}

int Lempel::readToken()
{
	char ch;
	Token* ptr, *nxt;
	ch=readChar();
	if (feof(in))
	{
		return -1;
	}
	ptr=&amp;tokens[ch-'A'];
	do
	{
		ch=readChar();
		//the last known token found
		if (feof(in))
		{
			return ptr-&gt;index;
		}
		nxt=ptr-&gt;next[ch-'A'];
		if (nxt==NULL)
		{
			break;
		}
		else
		{
			ptr=nxt;
		}
		
	}while (true);
	ptr-&gt;next[ch-'A']=createToken(ch);
	fseek(in, -1, SEEK_CUR);
	return ptr-&gt;index;
}

Token* Lempel::createToken(char ch)
{
	Token* result=new Token;
	result-&gt;value=ch;
	result-&gt;index=curIndex++;
	
	for (int j=0; j&lt;MaxAlphabetNumber; j++)
		//memset(tokens[i].next, NULL, MaxAlphabetNumber);
	{
		result-&gt;next[j]=NULL;
	}
	
	//memset(result-&gt;next, NULL, MaxAlphabetNumber);
	return result;
}


void Lempel::encode(char* fileName)
{
	//char outName[30];
	int code;
	openFile(fileName, &quot;encoded.txt&quot;);	
	while ((code=readToken())!=-1)
	{
		//fprintf(out, &quot;%d,&quot;, code);
		printf(&quot;%d,&quot;, code);
	}
	fclose(in);
	fclose(out);
}








</pre>
<pre><span lang="en-ca"><font color="#0000FF"><b>How to run?</b></font></span></pre>
<pre><span lang="en-ca">1. Copy a file &quot;nick.txt&quot; into the same path of this executable file. The contents of file is like this:</span></pre>
<pre><span lang="en-ca">	A B C AB BA ABA ABC CB BAB BABA ABCB BABAB BABC CBA</span></pre>
<pre><span lang="en-ca">The space between character is not necessary.</span></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="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">          


</p>

</body>

</html>