码迷,mamicode.com
首页 > 编程语言 > 详细

算法之美_源代码发布(3)

时间:2016-01-27 10:54:12      阅读:317      评论:0      收藏:0      [点我收藏+]

标签:

本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社2016年出版)一书第4章之代码(P91~P117)。全文目录、“45个算法”目录“22个经典问题目录”,以及有奖捉虫活动详情请见如下链接:http://blog.csdn.net/baimafujinji/article/details/50484348

附录中的经典笔试、面试问题参考答案请见:

http://blog.csdn.net/baimafujinji/article/details/50484683

技术分享


内容简介:探秘算法世界,求索数据结构之道;汇集经典问题,畅享编程技法之趣;点拨求职热点,敲开业界名企之门。本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的四十余个经典算法,以及回溯法、分治法、贪婪法和动态规划等算法设计思想。在此过程中,本书也系统地讲解了链表(包括单向链表、单向循环链表和双向循环链表)、栈、队列(包括普通队列和优先级队列)、树(包括二叉树、哈夫曼树、堆、红黑树、AVL树和字典树)、图、集合(包括不相交集)与字典等常用数据结构。同时,通过对二十二个经典问题(包括约瑟夫环问题、汉诺塔问题、八皇后问题和骑士周游问题等)的讲解,逐步揭开隐匿在数据结构背后的算法原理,力图帮助读者夯实知识储备,激活思维技巧,并最终冲破阻碍编程能力提升的重重藩篱。辅有完整的C++源代码,并穿插介绍了STL中的各种容器。


网上书店:

China-pub中国互动出版网:http://product.china-pub.com/4911922

当当网:http://product.dangdang.com/23851244.html

亚马逊:http://www.amazon.cn/%E7%AE%97%E6%B3%95%E4%B9%8B%E7%BE%8E-%E9%9A%90%E5%8C%BF%E5%9C%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E8%83%8C%E5%90%8E%E7%9A%84%E5%8E%9F%E7%90%86-%E5%B7%A6%E9%A3%9E/dp/B01AGNUIE8/ref=sr_1_8?ie=UTF8&qid=1453527399&sr=8-8&keywords=%E5%B7%A6%E9%A3%9E


如果你是该书的读者,请务必加算法学习群(495573865),内有更多资源等你,而你在读书中遇到的疑问也将得到我第一时间的解答。更多关注本博客,我将陆续发布该书全部源代码至本博客。


P94:链表节点类


// #ifndef _LISTNODE_H_
// #define _LISTNODE_H_

template <class T> class ListNode {
          
	T data;
	ListNode<T>*  link;

public:

	ListNode() : link(NULL){}
	ListNode (T value) : link(NULL) , data(value) {}
	~ListNode(){};
	void SetLink(ListNode<T>* next);
	void SetData(T value);
	ListNode<T>*  GetLink ();
	T& GetData ();
};

template <class T>
void ListNode<T>::SetLink(ListNode<T>* next){ 
	link = next;
}

template <class T>
void ListNode<T>::SetData(T value){
	data = value;
}

template <class T>
ListNode<T>* ListNode<T>::GetLink(){
	return link;
}

template <class T>
T&  ListNode<T>::GetData(){//返回结点中的数据
	return data;
}

//#endif


P96:链表类


 #ifndef _LIST_H_
 #define _LIST_H_

#include "ListNode.h"

template <class T> class List{

ListNode<T>* head;
ListNode<T>* tail;

public:

	List ();
	virtual ~List ();

	bool AddTail (T value);
	bool RemoveTail ();
	bool InsertAt (int index , T value);
	bool RemoveAt (int index);

	T& GetAt (int index);
	bool IsEmpty ();
	int GetCount ();
	void RemoveAll ();

	ListNode<T>* GetHead();
	ListNode<T>* GetTail();
	ListNode<T>* GetNodeAt(int index);
	ListNode<T>* GetCur();
	ListNode<T>* TowardCur();
};

template<class T>  
List<T>::List()  
{  
    head=new ListNode<T>();  
    tail=head;  
    tail->SetLink (NULL);  
} 

template<class T>  
List<T>::~List()  
{  
    RemoveAll();  
    delete head;  
} 

template <class T> 
bool List<T> :: AddTail (T value){ 
	ListNode<T>* add = new ListNode<T> (value);
	tail->SetLink (add);    	//把新建结点链入表尾,成为新表尾
	tail = tail->GetLink();		//移动表尾指 针置新表尾处
	tail->SetLink (NULL); 
	if (tail != NULL)
		return true;
	else  
		return false;
}

template <class T > 
bool List< T >::InsertAt ( int index,T value ) {
	//判断索引值是否正确
	if(index > this->GetCount ()-1 || index<0 ) {  
		cout<<"A wrong position!\n";
		return false;
	}

	ListNode<T>* current = head; 		//从头开始寻找出入地点

	while(index) {
         current = current->GetLink ();  //如果没找到,则顺序移动cur
		 --index;
	}

	ListNode<T>* add = new ListNode<T> (value); 
	add->SetLink (current->GetLink ());           //将新建结点链入链表
	current->SetLink (add);

	if (current->GetLink () != NULL)
		return true;
	else
		return false;
}

template <class T> 
bool List<T>::RemoveTail() {//删除表尾结点
	//利用RemoveAt(int index)实现
	return RemoveAt(this->GetCount()-1);
}

template <class T> 
bool List<T>::RemoveAt(int index){ //按照索引值删除结点
	if(index > this->GetCount ()-1 || index<0){    
		cout<<"A wrong position!\n";
		return false;
	}

	//用两个结点指针协作完成删除。其中,cur指向要删除结点的前一个结点
	//preCur指向要删除的结点
	ListNode<T>* cur,* curPre;
	cur = head;                	//从链表头开始寻找index 指向的结点
	curPre = cur->GetLink();    //置preCur到cur 后

	while(index){
		cur = cur->GetLink();   //如果没找到,则cur 与preCur继续后移
		curPre = curPre->GetLink();
		--index;
	}

    //如果要删除的结点位于链表尾,则把cur 置为新的表尾
	if(tail == curPre)
		tail = cur;
	cur->SetLink (curPre->GetLink());  //将被删除结点从链表中摘下
	delete curPre;

	if(curPre != NULL)
		return true;
	else
		return false;
}

template <class T> 
T&  List<T>::GetAt(int index) {    //返回索引值结点中的 value
	if (index > this->GetCount()-1 || index<0) {
		cout<<"A wrong position!\n";
	}
	
	ListNode<T>* cur;
	cur = head->GetLink();
	while(index){            //如果没找到,cur顺序后移
		cur = cur->GetLink();  
		--index;
	}
	return cur->GetData (); //返回结点中的 value
}

template <class T> 
bool List< T >::IsEmpty ( ) { //判空函数
	return head ->GetLink()==NULL ;
}
 
template <class T> 
int List< T >::GetCount() {		//返回链表中结点的个数(表头结点除外)
	int count = 0;             	//用count记录结点个数
	//初始化指针指向第一个结点(不是表头结点)
	ListNode<T>* current = head->GetLink ( );
	while(current != NULL) { 
		++count; 
		current = current->GetLink ( );  //顺序移动cur 
	}
	return count;  
}

template <class T> 
void List< T >::RemoveAll() { //删除所有结点
	ListNode<T>* cur;
    //当表头结点后还有其他结点时,删除这些结点
	while(head->GetLink() != NULL) {
		cur = head->GetLink(); 
		head->SetLink (cur->GetLink()); 
		delete cur;
	}
	tail = head; //置表尾为表头处
}

template <class T> 
ListNode<T>* List<T>::GetHead(){//返回头指针
	return head;
}

template <class T> 
ListNode<T>* List<T>::GetTail(){//返回尾指针
	return tail;
}

//返回指向索引值为index 的结点的指针
template <class T > 
ListNode< T >* List< T >::GetNodeAt(int index){

	//判断索引值是否正确
	if(index > this->GetCount()-1 || index<0){
		cout<<"A wrong position!\n";
	}  
	//handle 即为所求指针,它指向索引值是index 的结点。
	ListNode< T >* handle = head->GetLink();
	while(index){ //寻找索引值为index 的结点
		handle = handle->GetLink();
		--index;
	}
	return handle;
}

template <class T> 
ListNode<T>* List<T>::GetCur(){
	return cur;
}

template <class T>  
ListNode<T>* List<T>::TowardCur(){
	cur = cur->GetLink();
	return cur
}

#endif

链表类测试程序


#include "stdafx.h"
#include "List.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	List<int> list;
	for(int i = 0; i <9; i++)
		list.AddTail(i);

	cout<<list.GetCount()<<endl;

	cout<<list.GetAt(3)<<endl;

	list.RemoveAt(3);

	cout<<list.GetCount()<<endl;
	cout<<list.GetAt(3)<<endl;

	list.RemoveAll();
	cout<<list.GetCount()<<endl;

	system("PAUSE");
	return 0;
}

P101:有序链表的合并


#include "stdafx.h"
#include "List.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//创建两个链表listFirst, listSecond
	List<int> listFirst;
	List<int> listSecond;

	//初始化链表listFirst
	listFirst.AddTail(1);
	listFirst.AddTail(6);
	listFirst.AddTail(8);
	listFirst.AddTail(9);
	listFirst.AddTail(13);

	//初始化链表listSecond
	listSecond.AddTail(0);
	listSecond.AddTail(3);
	listSecond.AddTail(4);
	listSecond.AddTail(6);
	listSecond.AddTail(11);
	listSecond.AddTail(17);

	while (listSecond.GetCount() != 0){ //当listSecond 非空时持续循环
		int indexFirst = 0;
		//每次把listSecond 中的第一个数按序插入到listFirst 中
		//用while循环语句寻找插入位置
		while (listSecond.GetAt(0)>listFirst.GetAt(indexFirst)){
			++indexFirst;
			//如果listFirst 已到链表尾,结束本次循环
			if (indexFirst == listFirst.GetCount()){
				break;
			}
		}
		if (indexFirst == listFirst.GetCount()){//插入位置在listFirst 链表尾
			listFirst.AddTail(listSecond.GetAt(0));
			listSecond.RemoveAt(0);
		}
		else{//插入位置在listFirst 链表中
			listFirst.InsertAt(indexFirst, listSecond.GetAt(0));
			listSecond.RemoveAt(0);
		}
	}

	ListNode<int> * curNode = listFirst.GetHead();
	while (curNode != listFirst.GetTail())
	{
		curNode = curNode->GetLink();
		cout << curNode->GetData() << endl;
	}
	

	system("PAUSE");

	return 0;
}



P104:单向循环链表类


//#ifndef _CIRLIST_H_
//#define _CIRLIST_H_

#include "ListNode.h"

template <class T > class CirList{

	ListNode<T>* head;
	ListNode<T>* tail;
	ListNode<T>* cur;

public :
	CirList();
	~CirList();

	bool AddTail(T value);
	void RemoveThis();
	void RemoveAll();
	void SetBegin();
	int GetCount();
	ListNode<T>* GetCur();

	bool IsEmpty();
	T GetNext();
};

template <class T >  
CirList<T>::CirList(){//默认的构造函数
	head = tail = new ListNode<T>; //新建结点,并初始化head 与 tail 
	cur = head; 
	head->SetLink(head);
}

template <class T>  
CirList<T>::~CirList(){
	RemoveAll();
	delete head;
}

template <class T> 
bool CirList< T >::AddTail(T value){ //在链表尾插入新结点
    //新建结点,存储数据 value 
	ListNode<T>* add = new ListNode<T>(value);

	tail->SetLink(add);			//把新结点链入链表
	tail = tail->GetLink();		//移动tail 至新表尾处
	tail->SetLink(head);		//使表尾指针指向表头

	if(tail != NULL)
		return true;
	else
		return false;
}

template <class T> 
void CirList<T>::RemoveThis(){//把cur 指向的结点删除
	if(cur == head){
    	//如果当前cur在head 处,由于表头结点不可删除,顺序移动cur 至下一结
		//点处。
	    cur = cur->GetLink();
	}
 
	//用指针preCur标记cur的前一结点, node_del标记要删除的结点
	ListNode<T>* node_del = cur;
	ListNode<T>* preCur = cur;
    //寻找cur的前一结点,并用preCur记录下来
	for(int i=0;i<this->GetCount();i++){
	    preCur = preCur->GetLink();
	}

    //使cur前一结点的指针指向cur后一结点,即跳过cur所在的结点
	preCur->SetLink(cur->GetLink());
	delete node_del;
    //删除后cur顺序移动一个结点。
	cur = preCur->GetLink();
	preCur = NULL;
}

template <class T> 
void CirList< T >::RemoveAll(){//删除所有结点
    SetBegin();//开始从第一个结点删除
	int length = GetCount();//获取链表长度
	for(int i=0;i<length;i++){ 
		RemoveThis();
	}
	cur = head;  //置cur 到head 处
}

template <class T> 
void CirList< T >::SetBegin(){//置cur 到head 处,表示链表的开始
	cur = head;
}

template <class T> 
int CirList<T>::GetCount(){//获得链表长度
	int num = 0;
	if (cur==NULL)
		this->SetBegin();
	ListNode<T>* here = cur;  //记录当前结点位置
	while(cur->GetLink() != here){ //遍历整个链表,记录结点个数
		cur = cur->GetLink();
		++num;
	}
	//cur = cur->GetLink();//使cur 回到遍历前的位置
	cur = here;
	return 
		num;
}

template <class T> 
ListNode<T>* CirList< T >::GetCur(){//返回当前指针 cur
	return cur;
}

template <class T > 
bool CirList< T >::IsEmpty(){//判断链表是否为空
	return 
		head->GetLink() == head;
}

//返回当前结点中的数据,并使cur顺序移动一个位置
template <class T> 
T CirList< T >::GetNext(){
	if(cur == head){
        //跳过表头结点,因为表头结点中不存储有效数据
		cur = cur->GetLink();
	}
	T num = cur->GetData();	//获得数据
	cur = cur->GetLink();	//顺序移动cur 至下一个结点
	return 	
	num; 
}

//#endif

P107:约瑟夫环问题


#include "stdafx.h"
#include "CirList.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	CirList<int> jos; //新建单向循环链表,模拟约瑟夫问题
	
	//向链表中加入1~15 ,代表编号为1~15 的人
	for(int i=1;i<16;i++){
		jos.AddTail(i);
	}

	jos.SetBegin();//开始模拟约瑟夫问题

	//记录原始队列的人数,用此人数减一即可得到要删去多少人
	//本题中要删去14人
	int length = jos.GetCount();
	for(int i=1;i<length;i++)
	{
		for(int j=0;j<3;j++)
			jos.GetNext();
		jos.RemoveThis();
	}
	
	cout<<jos.GetNext()<<endl;

	system("PAUSE");
	return 0;
}


P108:魔术师发牌问题


#include "stdafx.h"
#include "CirList.h"
#include <iostream>
//#include "vld.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	CirList<int> poker;
	for(int i=0;i<13;i++){
		poker.AddTail(0);			//创建循环链表,存储13张扑克牌
	}
	cout<<poker.GetCount()<<endl;

	poker.SetBegin();
	poker.GetCur()->GetLink()->SetData(1);
	for(int i=2;i<14;i++){
		for(int j=0;j<i;j++){
			poker.GetNext();                //寻找插牌位置
			if(poker.GetCur()->GetData() != 0){
				j--;			//若当前位置中已有牌,则顺序查找下一个位置
			}
		}
		poker.GetCur()->SetData(i);
	}

	poker.SetBegin();
	for(int i=0;i<13;i++){
		cout<<poker.GetNext()<<"*";
	}
	cout<<endl;

	system("PAUSE");
	return 0;
}

P109:拉丁方阵问题


#include "stdafx.h"
#include "CirList.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	int num;
	cout<<"请输入拉丁方阶数(2<=N<=9):";
	cin>>num;
	CirList<int> latin;
	for(int i=1;i <= num; i++){
		latin.AddTail(i);				//创建循环链表
	}

	latin.SetBegin();
	for(int i=1; i<=num; i++){
		for(int j=1; j<=num; j++){
			cout<<latin.GetNext()<<" ";	        //输出循环链表中数据
		}
		cout<<endl;
		latin.GetNext();				//顺序移动循环链表中所有数据
	}

	system("PAUSE");
	return 0;
}


P111:双向循环链表节点类


#ifndef _DOULISTNODE_H
#define _DOULISTNODE_H

template <class T > class DouListNode{

	T data;
	DouListNode<T>* link;
	DouListNode<T>* prior;

public :

	DouListNode() : link(NULL),prior(NULL){}
	DouListNode(T value) : link(NULL),prior(NULL),data(value){}
	~DouListNode(){};
	void SetLink(DouListNode<T>* next);
	void SetPrior(DouListNode<T>* pre);
	DouListNode<T>* GetLink();
	DouListNode<T>* GetPrior();
	T& GetData();
};


template <class T > 
void DouListNode< T >::SetLink( DouListNode<T>* next ){ //设置link 值
	link = next;
}

template <class T > 
void DouListNode< T >::SetPrior( DouListNode<T>* pre ){ //设置prior 值
	prior = pre;
}

//返回指向当前结点的后继结点的指针
template <class T > 
DouListNode<T>* DouListNode< T >::GetLink(){
	return link;
}

//返回指向当前结点的前驱结点的指针
template <class T > 
DouListNode<T>* DouListNode< T >::GetPrior(){
	return prior;
}

template <class T > 
T& DouListNode< T >::GetData(){//返回结点中保存的数据
	return data;
}

#endif

P114:双向循环链表类


#ifndef _DOULIST_H
#define _DOULIST_H

#include "DouListNode.h"

template <class T> class DouList{
	DouListNode<T>* head;
	DouListNode<T>* tail;
	DouListNode<T>* cur;

public :
	DouList();
 	~DouList();

	bool AddTail(T value);
	bool AddHead(T value);
	void RemoveThis(bool direction);
	void RemoveAll();
	void SetBegin();
	int GetCount();
	void TowardCur();
	void BackCur();
	DouListNode<T>* GetCur();
	DouListNode<T>* GetHead();
	DouListNode<T>* GetTail();
	void InsertAfter(T value);

	bool IsEmpty();
	T GetNext();
	T GetPrior();
};


template <class T>  
DouList<T>::DouList(){//默认的构造函数

	//创建表头结点,并初始化head 指针与tail 指针 
	head = tail = new DouListNode<T>; 
	cur = head; 
	head->SetLink(head); //创建初始循环。
	head->SetPrior(tail);
}

template <class T>  
DouList<T>::~DouList(){
	RemoveAll();
	delete head;
}

template <class T> 
bool DouList<T>::AddTail(T value){ //在表尾插入一个新结点

	//创建新结点,结点存储的数据由value 决定
	DouListNode<T>* add = new DouListNode<T>(value);
    tail->SetLink(add);  //使新结点成为表尾结点的后继结点
	add->SetPrior(tail);  
	tail = tail->GetLink(); 
	tail->SetLink(head);  //使表尾结点指向表头结点

	//设置表头结点的前驱为表尾结点,至此插入操作完成
	head->SetPrior(add);
    //如果新的表尾结点指针为空,则插入失败。
	if(tail != NULL){
		return true;
	}
	else 
		return false;
}

//此函数用来向表头结点与链表中第一个结点之间插入新结点
template <class T> 
bool DouList<T>::AddHead(T value){

    //创建新结点,保存数据value 
	DouListNode<T>* add = new DouListNode<T>(value);
	add->SetPrior(head);          
	add->SetLink(head->GetLink()); 

	//置链表中第一个结点的前驱为add
        //此时add 成为链表中第一个结点
	head->GetLink()->SetPrior(add);
	head->SetLink(add);      

 	//如果对空链表应用这个函数,则应该更新尾指针tail 
	if(tail == head){
		tail = head->GetLink();
	}
	if(add != NULL){
		return true;
	}
	else 
	    return false;
}

//把当前cur 指向的结点删除,删除后cur 的移动方向由direction 决定
template <class T>
void DouList<T>::RemoveThis(bool direction){
    //如果当前cur 位于表头处,由于表头结点不能被删除,顺序移动cur
    //至下一个位置
	if(cur == head){
		//如果direction==0,顺着link 方向移动cur
		if(direction == 0)
	    	cur = cur->GetLink();
		//如果direction==1,顺着prior 方向移动 cur
		if(direction == 1)
			cur = cur->GetPrior();
	}
	
 	//新建指针preCur 与 nextCur。
	//preCur 指向cur 的前驱结点
	//nextCur 指向 cur 的后继结点
	DouListNode<T>* preCur = NULL;
	DouListNode<T>* nextCur = NULL;
	preCur = cur->GetPrior();        
	nextCur = cur->GetLink(); 
	DouListNode<T>* node_del = cur;
	preCur->SetLink(cur->GetLink());  //使cur 的前驱结点直接指向后继结点
	nextCur->SetPrior(cur->GetPrior()); //是cur 的后继结直接指向前驱结点
 
    //根据direction 的值判断cur 的移动方向
    //若direction ==0,则向link 方向移动cur 
	if(direction == 0)
		cur = nextCur;
	//若direction ==1,则向prior 方向移动cur
	if(direction == 1)
		cur = preCur;
	delete node_del;
}

template <class T > 
void DouList<T>::RemoveAll(){//删除所有结点(保留表头结点)

	SetBegin();            //从头开始删除
	int length = GetCount();  //记录当前链表长度
	for(int i=0;i<length;i++){ //循环删除
		RemoveThis(0);
	}
	cur = head;
}

template <class T > 
void DouList<T>::SetBegin(){//置cur 到表头处
	cur = head;
}

//获得当前链表中结点个数(不计表头结点)
template <class T > 
int DouList<T>::GetCount(){
	int num = 0;   //记录链表长度的变量
	DouListNode<T>* here = cur; //用here 指针完成对链表的遍历
	while(cur->GetLink() != here){ //遍历链表
		cur = cur->GetLink();
		++num;
	}

	cur = cur->GetLink();    //遍历完成后,置cur到原来的位置
	//返回链表长度
	return num;
}

template <class T> 
void DouList<T>::TowardCur(){//使cur向link方向移动
	cur = cur->GetLink();
}

template <class T > 
void DouList<T>::BackCur(){//使cur向prior方向移动
	cur = cur->GetPrior();
}

template <class T > 
DouListNode<T>* DouList<T>::GetCur(){//返回指针cur 
	return 
		cur;
}

template <class T > DouListNode<T>* DouList<T>::GetHead(){
	return 
		head;
}

template <class T > DouListNode<T>* DouList<T>::GetTail(){
	return 
		tail;
}

//判断链表是否为空。
template <class T > 
bool DouList<T>::IsEmpty(){
	//链表为空的条件是链表仅有表头结点
	return 
		head->GetLink() == head;
}

//向cur 指向的结点后插入一个数据成员为value 的新结点
//当对空链表应用这个函数时,作用相当于AddTail( T value )
template <class T > 
void DouList<T>::InsertAfter(T value){

	DouListNode<T>* add = new DouListNode<T>(value);
	DouListNode<T>* nextCur = cur->GetLink();  //获得cur 的后继结点
	cur->SetLink(add);    //置cur 的后继结点为要加入的结点
	add->SetLink(nextCur); 
    nextCur->SetPrior(add); //置cur 后继结点的前驱为新加结点
	add->SetPrior(cur);   

	if(cur==tail){
		tail = cur->GetLink();
	}
}

//获得cur指向的结点中的数据,并将cur 向link 方向移动
template <class T > 
T DouList<T>::GetNext(){
    //如果cur位于表头处,则顺序移动cur
	if(cur == head){
		cur = cur->GetLink();
	}
	T num = cur->GetData();  //返回当前结点中的数据
	cur = cur->GetLink();//返回数据后移动cur(link 方向)
	return 	
		num;
}

//获得cur指向的结点中的数据,并将cur 向prior 方向移动
template <class T > 
T DouList<T>::GetPrior(){
	//如果cur位于表头处,则顺序移动cur
	if(cur == head){
		cur = cur->GetPrior();
	}
	T num = cur->GetData(); //返回当前结点中的数据
	cur = cur->GetPrior();   //返回数据后移动cur (prior 方向)
	return 
		num;
}

#endif



P115:维吉尼亚加密问题


#include "stdafx.h"
#include "DouListNode.h"
#include "DouList.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	DouList<char> planText;
	DouList<char> cryptograph;
	DouList<int> key;
	DouList<char> trans;
	planText.SetBegin();
	planText.AddTail(‘y‘);
	planText.AddTail(‘o‘);
	planText.AddTail(‘u‘);
	planText.AddTail(‘a‘);
	planText.AddTail(‘r‘);
	planText.AddTail(‘e‘);
	planText.AddTail(‘i‘);
	planText.AddTail(‘n‘);
	planText.AddTail(‘d‘);
	planText.AddTail(‘a‘);
	planText.AddTail(‘n‘);
	planText.AddTail(‘g‘);      
	planText.AddTail(‘e‘);
	planText.AddTail(‘r‘);

	planText.SetBegin();
	cout<<"明文:"<<‘\t‘;
        for(int z=0;z<planText.GetCount();z++){
		cout<<planText.GetNext()<<" ";
	}
	cout<<endl<<endl;

       key.SetBegin(); //产生密钥链表
       for(int i=0;i<6;i++){
	   key.AddTail(1+rand()%9);
       }

	cout<<"密钥:"<<‘\t‘;
	for(int i=0;i<key.GetCount();i++){
		cout<<key.GetNext()<<" ";
	}
	cout<<endl<<endl;

	planText.SetBegin();
	key.SetBegin();
	cryptograph.SetBegin();
	for(int i=0;i<planText.GetCount();i++){

		char c = planText.GetNext();
		int num = key.GetNext();
		if(‘a‘<=c&&c<=‘z‘-num)
			c=c+num;
		else if(‘z‘-num<c&&c<=‘z‘)
			c = c+num-1-‘z‘+‘a‘;
		cryptograph.AddTail(c);
	}

	cryptograph.SetBegin();
	cout<<"密文:"<<‘\t‘;
        for(int j=0; j<cryptograph.GetCount(); j++){
		cout<<cryptograph.GetNext()<< " ";
	}
	cout<<endl<<endl;

	trans.SetBegin();
	planText.SetBegin();
	key.SetBegin();
	for(int k=0; k<planText.GetCount(); k++){


		char c = cryptograph.GetNext();
		int num = key.GetNext();
		if(‘a‘<=c-num && c-num<=‘z‘)
			c=c-num;
		else if(‘a‘>c-num && c>=‘a‘)
			c = ‘z‘-(‘a‘-c+num)+1;

		cryptograph.AddTail(c);
		trans.AddHead(c);
	}

	trans.SetBegin();
	cout<<"解密:"<<‘\t‘;
        for(int k=0;k<trans.GetCount();k++){
		cout<<trans.GetPrior()<<" ";
	}
	cout<<endl<<endl;

	system("PAUSE");
	return 0;
}





算法之美_源代码发布(3)

标签:

原文地址:http://blog.csdn.net/baimafujinji/article/details/50485557

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!