c语言哈希表和链表的使用,对电影分类

 用c语言实现简单的哈希表,电影进行分类。

头文件

#pragma once 
#include<string.h>
#include<time.h>
#include<iostream>
#include<vector>
using namespace std;

//影片信息
typedef struct Film
{
	string FilmName;
	float score;//评分
	string AwardType;//获得奖项
	string FilmmakingState;//制片国家
	string Director;//导演
	string Performer;//演员列表
	string Type;//电影类别
	string BriefIntroduction;//简介
	string ReleaseTime;//上映时间
	int Clicks;//点击量
	string link;//链接
	Film()
	{
		memset(this, 0, sizeof(struct Film));//构造函数,初始化,清空内存;
	}
}Film;


//将时间字符串转化成time_t
time_t StrinToTime(string str_Time);


//单链表,存储从文件读取的电影的信息
//链表节点
typedef struct FilmNode
{
	int Number;//节点数
	Film* FilmInfo;//电影信息
	struct FilmNode * next;//指向后继
}Node;

//比较大小时用的结构体
typedef struct SortNode
{
	Node *pNode;//保存地址
	int Clicks;//点击量
 }SortNode;

typedef struct SortNodee
 {
	 Node *pNode;//保存地址
	time_t ReleaseTime;//上映时间
 }SortNodee;

typedef struct SortNodeee
{
	Node *pNode;//保存地址
	float flag;//评分
}SortNodeee;
//哈希节点
typedef struct HashLeafNode
{
	Node *pNode;//保存地址
	struct HashLeafNode *next;
}HashLeafNode;
//哈希表头
typedef struct HashNode
{
	string key;//键值
	HashLeafNode *LeafNode;//指向孩子节点
	struct HashNode *next;
	HashNode()
	{
		memset(this, 0, sizeof(HashNode));
	}
}HashNode;


//创建链表,返回头结点
Node* Creatlist();

//插入节点,尾插
bool InsertNod(Node* Head, Node* NewNode);

//电影名查找
SortNode* Find(Node* Head, string name);

把点击量和平份和节点地址放入数组
void ArrForList(Node*Head, SortNode **ArrHead, SortNodee **ArrHeade, SortNodeee **ArrHeadeee);

//按照点击量和评分排序(冒泡排序)
void sortForArr(void *ArrHard, int flag,int size);

//节点交换位置
void NodSwp(void *Node1, void *Node2, int size);

//简易的哈表
HashNode *CreatHashTab();

//给哈希表添加节点
bool InsertHashNod(string Key, HashNode * HashHead, HashLeafNode* LeafNode);

//读Excel表,读影片信息
void ReadMovInfo(Node* Head);

//中文的内容读出来后要进行编码的转换,这个为转换函数:wchar_t to char
char *w2c(char *pcstr, const wchar_t *pwstr, size_t len);

//按奖项分类
void ClassificationOfAwards(HashNode * Head, Node* HeadList,int flag);

//字符串拆分
void SplitStr(string str, int flag, vector<string>& Temp);

源文件,插入节点是用的了第三方库libxl读取Excel表的文件内容读取,将字段保存在结构体中

#include"libxlwin\libxlwin\libxl-3.6.5.0\include_cpp\libxl.h"
#include"Movies.h"
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>



time_t StrinToTime(string str_Time)//2018-09-07
{     
	char *str = (char*)str_Time.data();             // 将string转换成char*。
	tm tm_;                                    // 定义tm结构体。
	int year, month, day;// 定义时间的各个int临时变量。
	sscanf_s(str, "%d-%d-%d", &year, &month, &day);// 将str存储的日期时间,转换为int临时变量。
	tm_.tm_year = year - 1900;                 // 年,由于tm结构体存储的是从1900年开始的时间,所以tm_year为int临时变量减去1900。
	tm_.tm_mon = month - 1;                    // 月,由于tm结构体的月份存储范围为0-11,所以tm_mon为int临时变量减去1。
	tm_.tm_mday = day;                         // 日。
	tm_.tm_hour = 0;                        // 时。
	tm_.tm_min = 0;                       // 分。
	tm_.tm_sec = 0;                       // 秒。
	tm_.tm_isdst = 0;                          // 非夏令时。
	time_t t_ = mktime(&tm_);                  // 将tm结构体转换成time_t格式。
	return t_;                                 // 返回值。 
}


//创建链表,返回头结点
Node* Creatlist()
{
	Node* HeadList = new Node();
	HeadList->next = NULL;
	return HeadList;
}

//插入节点,尾插
bool InsertNod(Node* Head, Node* NewNode)
{
	if (NULL == Head || NULL == NewNode)
	{
		return false;
	}

	//找到尾节点,插入
	Node* Temp = Head;
	while (Temp->next)
	{
		Temp = Temp->next;//指针后移
	}
	
	Temp->next = NewNode;
	NewNode->next = NULL;
	Head->Number += 1;
	return true;
}

//把点击量和平份和节点地址放入数组
void ArrForList(Node*Head, SortNode **ArrHead, SortNodee **ArrHeade, SortNodeee **ArrHeadeee)//flag代表按照那种方式来进行排序
{
	SortNode *FristNode = new SortNode[Head->Number];
	SortNodee *FristNodee = new SortNodee[Head->Number];
	SortNodeee *FristNodeee = new SortNodeee[Head->Number];

	Node* Temp = Head->next;
	int loop = 0;
	while (Temp)
	{
		FristNode[loop].Clicks = Temp->FilmInfo->Clicks;
		FristNode[loop].pNode = Temp;
	
		FristNodee[loop].ReleaseTime = StrinToTime(Temp->FilmInfo->ReleaseTime);
		FristNodee[loop].pNode = Temp;

		FristNodeee[loop].flag = Temp->FilmInfo->score;
		FristNodeee[loop].pNode = Temp;

		Temp = Temp->next;
		loop++;
	}
	*ArrHead = FristNode;
	*ArrHeade = FristNodee;
	*ArrHeadeee = FristNodeee;
}

//按照点击量和评分排序(冒泡排序)
void sortForArr(void *ArrHard, int flag, int size)
{
	SortNode *FristNode = NULL;
	SortNodee *FristNodee = NULL;
	SortNodeee *FristNodeee = NULL;
	if (1 == flag)
	{
		FristNode = (SortNode *)ArrHard;
	}
	else if (2 == flag)
	{
		FristNodee = (SortNodee *)ArrHard;
	}
	else if (3 == flag)
	{
		FristNodeee = (SortNodeee *)ArrHard;
	}
	else
	{
	}
	for (int j = 0; j < size - 1; j++)
	{
		for (int i = 0; i < size - 1 - j; i++)
		{
			if (FristNodee)
			{
				if (FristNodee[i].ReleaseTime <= FristNodee[i + 1].ReleaseTime)
				{
					NodSwp(&FristNodee[i], &FristNodee[i + 1], sizeof(SortNodee));
				}
			}
			else if (FristNode)
			{
				if (FristNode[i].Clicks >= FristNode[i + 1].Clicks)
				{
					NodSwp(&FristNode[i], &FristNode[i + 1], sizeof(SortNode));
				}
			}
			else if (FristNodeee)
			{
				if (FristNodeee[i].flag <= FristNodeee[i + 1].flag)
				{
					SortNodeee * t = &FristNodeee[i];

					SortNodeee * t1 = &FristNodeee[i+1];
					NodSwp(&FristNodeee[i], &FristNodeee[i + 1], sizeof(SortNodeee));
				}
			}
		}
	}

}

//节点交换位置
void NodSwp(void *Node1, void *Node2, int size)
{
	void*temp = (void *)malloc(size);
	if (NULL == temp)
	{
		return;
	}

	memcpy(temp, Node1, size);
	memcpy(Node1, Node2, size);
	memcpy(Node2, temp, size);

	free(temp);
	temp = NULL;
}

//简易的哈表
HashNode *CreatHashTab()
{
	HashNode *HashHead = (HashNode *)malloc(sizeof(HashNode));
	if (HashHead)
	{
		/*HashHead->LeafNode = NULL;
		HashHead->next = NULL;
		HashHead->key = "1";*/
		memset(HashHead, 0, sizeof(HashNode));
		return HashHead;
	}
	else
	{
		return NULL;
	}
}

//给哈希表添加节点
bool InsertHashNod(string Key, HashNode * HashHead, HashLeafNode* LeafNode)
{
	if (NULL == HashHead || NULL == LeafNode)
	{
		return false;
	}

	HashNode *Temp = HashHead;
	
	while (Temp)
	{
		if (Temp->key == Key)
		{
			LeafNode->next = Temp->LeafNode;//头插
			Temp->LeafNode = LeafNode;
			return true;
		}
		Temp = Temp->next;
	}

	HashNode * NewNod = new HashNode();
	if (NULL == NewNod)
	{
		return false;
	}
	
	NewNod->key = Key;
	NewNod->LeafNode = LeafNode;
	NewNod->next = HashHead->next;
	HashHead->next = NewNod;
	//=
	return true;
}

//中文的内容读出来后要进行编码的转换,这个为转换函数:wchar_t to char
char *w2c(char *pcstr, const wchar_t *pwstr, size_t len)
{
	int nlength = wcslen(pwstr);
	//获取转换后的长度
	int nbytes = WideCharToMultiByte(0, 0, pwstr, nlength, NULL, 0, NULL, NULL);
	if (nbytes>len) nbytes = len;
	// 通过以上得到的结果,转换unicode 字符为ascii 字符
	WideCharToMultiByte(0, 0, pwstr, nlength, pcstr, nbytes, NULL, NULL);
	return pcstr;
}

using namespace libxl;
//读Excel表,读影片信息
void ReadMovInfo(Node* Head)
{
	Book* book = xlCreateXMLBook();
	book->setKey(L"Halil Kural", L"**********************");
	if (book->load(L"myMoviesIfo.xlsx"))
	{
		//从exce中读取球队消息
		Sheet * sheet1 = book->getSheet(0);
		if (sheet1)
		{
			for (int loop = 1; loop < 100; loop++)
			{
				Film *MITemp = new Film();
				for (int looT = 0; looT < sheet1->lastCol(); looT++)
				{
					const wchar_t * t = sheet1->readStr(loop, looT);
					if (NULL == t)
					{
						break;
					}
					char *pcstr = (char *)malloc(sizeof(char)*(2 * wcslen(t) + 1));
					memset(pcstr, 0, 2 * wcslen(t) + 1);
					w2c(pcstr, t, 2 * wcslen(t) + 1);
					if (0 == looT)
						MITemp->FilmName = pcstr;
					if (1 == looT)
						MITemp->score = atof(pcstr);
					if (2 == looT)
						MITemp->AwardType = pcstr;
					if (3 == looT)
						MITemp->Type = pcstr;
					if (4 == looT)
						MITemp->Director = pcstr;
					if (5 == looT)
						MITemp->Performer = pcstr;
					if (6 == looT)
						MITemp->FilmmakingState = pcstr;
					if (7 == looT)
						MITemp->BriefIntroduction = pcstr;
					if (8 == looT)
						MITemp->ReleaseTime = pcstr;
					if (9 == looT)
						MITemp->link = pcstr;
					free(pcstr);
					pcstr = NULL;
				}
				Node *Temp = new Node();
				Temp->FilmInfo = MITemp;
				InsertNod(Head, Temp);
			}

		}

	}
}

//按奖项分类
void ClassificationOfAwards(HashNode * Head, Node* HeadList, int flag)
{
	if (NULL == Head || NULL == HeadList)
	{
		return;
	}

	vector<string> Temp;
	Node*TempHeadList = HeadList->next;
	HashNode * TempHead = Head;

	while (TempHeadList)
	{
		switch (flag)
		{
		case 1:
		{
			HashLeafNode* LeafNode = new HashLeafNode();
			LeafNode->next = NULL;
			LeafNode->pNode = TempHeadList;
			InsertHashNod(TempHeadList->FilmInfo->Director, Head, LeafNode);
		}
			break;
		case 2:
		{
				  SplitStr(TempHeadList->FilmInfo->AwardType, 1, Temp);
				  for (int loop = 0; loop < Temp.size(); loop++)
				  {
					  HashLeafNode* LeafNode = new HashLeafNode();
					  LeafNode->next = NULL;
					  LeafNode->pNode = TempHeadList;
					  TempHeadList->FilmInfo->AwardType = Temp.at(loop);
					  InsertHashNod(Temp.at(loop), Head, LeafNode);
				  }
					  
		}
			break;
		case 3:
		{
				  SplitStr(TempHeadList->FilmInfo->Type, 2, Temp);
				  for (int loop = 0; loop < Temp.size(); loop++)
				  {
					  HashLeafNode* LeafNode = new HashLeafNode();
					  LeafNode->next = NULL;
					  LeafNode->pNode = TempHeadList;
					  InsertHashNod(Temp.at(loop), Head, LeafNode);
				  }

		}
			break;
		case 4:
		{
				  SplitStr(TempHeadList->FilmInfo->FilmmakingState, 3, Temp);
				  for (int loop = 0; loop < Temp.size(); loop++)
				  {
					  HashLeafNode* LeafNode = new HashLeafNode();
					  LeafNode->next = NULL;
					  LeafNode->pNode = TempHeadList;
					  InsertHashNod(Temp.at(loop), Head, LeafNode);
				  }

		}
			break;
		default:
			break;
		}
		TempHeadList = TempHeadList->next;
		vector<string>().swap(Temp);
	}

}

//字符串拆分
void SplitStr(string str, int flag, vector<string>& Temp)
{
	switch (flag)
	{
	case 1:
		if (string::npos == str.find_first_of("("))
		{
			Temp.push_back(str);
		}
		else
		{
			Temp.push_back(str.substr(0, str.find_first_of("(") - 1));
		}
		break;
	case 2:

	{
			  string c = ";";
			  string::size_type pos1, pos2;
			  pos2 = str.find(";");
			  pos1 = 0;
			  while (string::npos != pos2)
			  {
				  Temp.push_back(str.substr(pos1, pos2 - pos1));

				  pos1 = pos2 + c.size();
				  pos2 = str.find(c, pos1);
			  }
			  if (pos1 != str.length())
				  Temp.push_back(str.substr(pos1));
	}
		break;
	case 3:
	{
			  string c = "/";
			  string::size_type pos1, pos2;
			  pos2 = str.find("/");
			  pos1 = 0;
			  while (string::npos != pos2)
			  {
				  Temp.push_back(str.substr(pos1, pos2 - pos1));

				  pos1 = pos2 + c.size();
				  pos2 = str.find(c, pos1);
			  }
			  if (pos1 != str.length())
				  Temp.push_back(str.substr(pos1));
	}
	default:
		break;
	}
}

//电影名查找
SortNode*  Find(Node* Head, string name)
{
	Node* Temp = Head->next;
	while (Temp->next)
	{
		if (string::npos != Temp->FilmInfo->FilmName.find(name))
		{
			SortNode* G = new SortNode();
			G->pNode = Temp;
			return G;
		}
		Temp = Temp->next;//指针后移
	}
	return NULL;
}

保存电影信息的Excel文件

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值