#2.数据结构C语言-队列、定长顺序串-最大字符平台

题目:一个字符串中的任意一个子序列,若子序列中各字符值均相同,则称为字符平台。编写一算法,输入任意一字符串S。输出S中长度最大的所有字符平台的起始位置及所含字符。注意,最大字符平台有可能不止一个。

例如,字符串aabcbbbbdccccaaa的最大的字符平台是bbbb和cccc。
 

一个全是注释的代码:

#pragma once
#include <stdio.h>

#define MAXSIZE 20
#define OK 1
#define FALSE 0

typedef struct SeqStringing {
	char ch[MAXSIZE];                /*用定长字符数组存储字符串*/
	int len;                          /*字符串长度*/
}SeqString;                           /*定义定长顺序串类型*/

void InitString(SeqString* s);          /*初始化顺序串,将顺序串长度置0,并将所有字符置为'\0'*/
void CreateString(SeqString* s);           /*根据输入创建一个字符串,输入'$'或输入超过字符串最大长度时停止*/
//void PrintString(SeqString* s);     /*打印字符串,目的是检查字符串输入函数是否正确*/

typedef  char QueueElemType;
typedef struct TempNode {
	QueueElemType ch;             /*用于存储字符平台中的字符符号*/
	int pos;                      /*存储字符平台在主串中的位置*/
	struct TempNode* next;        /*用于构建链表的next指针*/
}TempNode;                        /*定义链队列节点类型*/
typedef struct TempQueue {
	TempNode* head;                    /*队头指针*/
	TempNode* tail;                    /*队尾指针*/
}*TempQueue;                           /*定义链队列类型*/
int InitNode(TempNode** tn);                                    /*初始化队列结点,分配空间并置其next指针为NULL*/
int InitQueue(TempQueue* tq);                                   /*初始化队列,创建一个头结点,使队头指针和队尾指针指向它*/
void EnterQueue(TempQueue tq, QueueElemType val, int pos);       /*入队函数,将字符符号为val、位置为pos的字符平台加入临时队列tq*/
//int DeleteQueue(TempQueue tq, QueueElemType* x, int* y);      /*一个没用到的出队函数,也没测试它的正确性*/
int ClearQueue_1(TempQueue tq);                                   /*清除队列,使头尾指针指向头结点,并释放其他结点占用的内存空间*/
void PrintQueue(TempQueue tq, int max_len);                     /*打印存储着最大字符平台长度为max_len的队列tq*/

TempQueue GetContinuousRepeatCharacters(SeqString* str, int* max_len);   /*找到字符串str中长度为*max_len的最大字符平台返回其地址*/
 
void InitString(SeqString* s) /*初始化顺序串,将顺序串长度置0,并将所有字符置为'\0'*/
{
	int i;
	for (i = 0; i < MAXSIZE; ++i)
	{
		s->ch[i] = '\0';
	}
	s->len = 0;
}
void CreateString(SeqString* s) /*根据输入创建一个字符串,输入'$'或输入超过字符串最大长度时停止*/
{
	char tch;                   /*用来临时存放输入字符符号的字符变量*/
	int flag = 1;            
	int i = 0;
	rewind(stdin);
	while (flag)
	{
		tch = getchar();
		if (tch != '$' && i < MAXSIZE)          /* 输入'$'或输入超过字符串最大长度时停止*/
		{
			s->ch[i++] = tch;
	    }
		else
		{
			flag = 0;
			s->len = i;                    /*输入结束时将字符串长度更改为输入字符串的数量*/
		}
    }

}
//void PrintString(SeqString* s)   /*打印字符串,目的是检查字符串输入函数是否正确*/
//{
//	int i = 0;
//	while (i < s->len)
//	{
//		printf("%c", s->ch[i++]);
//	}
//	printf("\n\n");
//}
int InitNode(TempNode** tn)       /*初始化队列结点,分配空间并置其next指针为NULL*/
{
	*tn = (TempNode*)malloc(sizeof(TempNode));
	if ((*tn) == NULL)
	{
		return FALSE;
	}
	(*tn)->next = NULL;
	return OK;
}
int InitQueue(TempQueue* tq)    /*初始化队列,创建一个头结点,使队头指针和队尾指针指向它*/
{
	TempNode* tn;
	InitNode(&tn);                              /*初始化头结点*/
	*tq = (TempQueue)malloc(sizeof(TempQueue));
	if ((*tq) == NULL)
	{
		return FALSE;
	}
	(*tq)->head = tn;
	(*tq)->tail = tn;                      /*使队头指针和队尾指针指向头结点*/
	return OK;
}
void EnterQueue(TempQueue tq, QueueElemType val, int pos)    /*入队函数,将字符符号为val、位置为pos的字符平台加入临时队列tq*/
{
	TempNode* tn;
	InitNode(&tn);                          /*初始化一个新结点*/
	tn->ch = val;
	tn->pos = pos;                         /*赋值*/
	tq->tail->next = tn;
	tq->tail = tn;                         /*修改队尾指针*/
	
}
//int DeleteQueue(TempQueue tq, QueueElemType* x, int* y) /*一个没用到的出队函数,也没测试它的正确性*/
//{
//	TempNode* tn;
//	tn = tq->head->next;
//	*x = tn->ch;
//	*y = tn->pos;
//	if (tn->next == NULL)
//	{
//		tq->tail = tq->head;
//	}
//	tq->head->next = tn->next;
//	free(tn);
//	
//}

int ClearQueue_1(TempQueue tq)  /*清除队列,使头尾指针指向头结点,并释放其他结点占用的内存空间*/
{
	TempNode* tmp;                    /*用于暂时存储即将被释放的空间位置*/
	TempNode* pos;                     /*遍历队列*/
	if (tq->head->next == NULL)
	{
		return OK;
	}                          /*少加了这个判断,导致链表原本为空时tmp指向空,此时“pos=tmp->next”语句出错*/
	tmp = tq->head->next;
	pos = tmp->next;
	while (pos)
	{
		free(tmp);
		tmp = pos;
		pos = pos->next;
	}                            
	free(tmp);                /*循环结束时pos为空,tmp指向最后一个结点,故还需要释放此时tmp所指空间*/
	tq->head->next = NULL;
	tq->tail = tq->head;
	return OK;
}               /*也可以使用出队函数来清空链表,实现如下*/
/*首先需要定义队列判空函数,定义如下*/
/*int IsEmpty(TempQueue tq)
{
	if (tq->head == tq->tail)
	{
		return OK;
	}
	return FALSE;
}*/
/*使用出队函数来清空链表,定义如下*/
/*void ClearQueue_2(TempQueue tq)        
{
	int tmpa, tmpb;
	while (!IsEmpty(tq))         
	{
		DeleteQueue(tq, &tmpa, &tmpb);
	}
}*/  
void PrintQueue(TempQueue tq, int max_len)   /*打印存储着最大字符平台长度为max_len的队列tq*/
{
	TempNode* pos = tq->head->next;
	while (pos)
	{
		printf("start position: %2d | ", pos->pos+1);
		printf("element: %c\n",pos->ch);
		pos = pos->next;
	}                                           /*打印字符平台的符号和在主串中的位置*/
	printf("max character platform length: %d", max_len);    /*打印字符平台的长度*/
	printf("\n");
}

TempQueue GetContinuousRepeatCharacters(SeqString* str, int* max_len) /*找到字符串str中长度为*max_len的最大字符平台返回其地址*/
{
	TempQueue pq;                   /*声明一个队列用于存储字符平台*/
	//TempNode* pn;              /*多声明了一个变量*/
	int spos = 0, epos = 0;             /*用于遍历字符串,spos为字符平台开始位置,epos为字符平台最后一个字符的下一位置*/
	*max_len = 0;                       /*字符平台最大长度*/
	InitQueue(&pq);                   /*初始化队列*/
	while (spos <= str->len - 1)       /*结束条件为遍历完最后一个字符平台,此时spos等于字符串长度减一*/
	{
		while (str->ch[spos] == str->ch[epos])   /*循环结束时字符串str的ch[spos]到ch[epos]之间即是一个字符平台*/
		{
			epos++;
		}
		if (*max_len < epos - spos)          /*如果新字符平台长度大于之前字符平台的最大长度*/
		{
			*max_len = epos - spos;               /*更新字符平台最大长度*/
			ClearQueue_1(pq);                     /*清空原队列*/
			EnterQueue(pq, str->ch[spos], spos);  /*记录新的最大字符平台*/
		}
		else if (*max_len == epos - spos)    /*如果新字符平台长度等于之前字符平台的最大长度*/
		{
			EnterQueue(pq, str->ch[spos], spos);  /*在队列中添加一个新纪录*/
		}
		spos = epos;
		epos++;                       /*修改变量遍历下一个字符平台*/
	}
	return pq;            /*忘了添加返回值*/
}
void Test()            /*完整实现题目功能的函数*/
{
	/*int i = 0;*/           /*注释掉的语句为测试函数功能语句*/
	int len;                 /*用于带出最大字符平台的长度*/
	/*char ch;*/
	SeqString* ss;            /*声明字符串*/
	TempQueue tq;             /*声明队列,存放最大字符平台信息*/
	ss = (SeqString*)malloc(sizeof(SeqString)); /*为顺序字符串分配空间*/
	InitString(ss);            /*初始化字符串*/
	CreateString(ss);           /*通过输入创建字符串*/
	/*PrintString(ss);*/
	tq = GetContinuousRepeatCharacters(ss, &len);  /*用tq记录最大字符平台信息*/
	/*InitQueue(&tq);
	rewind(stdin);
	while (i < 10)
	{
		ch = getchar();
		EnterQueue(tq, ch, i);
		i++;
	}*/
	PrintQueue(tq,len);                     /*打印最大字符平台信息*/
	/*ClearQueue(tq);
	PrintQueue(tq);*/
}
int main()
{
	Test();                 /*调用测试函数*/
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值