/* maxsubstring.c 输出最长不重复子串*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 50
typedef struct LNODE{
struct LNODE *nextp;
char* sub;
}LNode;
LNode *rootp = NULL;
void add_node(char *s);
void empty_node(void);
void print_node(void);
char *str_dup(char *s);
void create_node(char *s);
int main(void)
{
char queue[MAXSIZE];
char sub[MAXSIZE];
int front, rear, maxlen;
int i, j, ch, flag = 1;
queue[0] = getchar(); /* 读取第一个字符,不读取程序没办进行比较 */
front = rear = maxlen = 0; /* front,rear分别为队列第一,最后一个字符的下标 */
while((ch = getchar()) != '\n' && maxlen < MAXSIZE){
for(i = 0; i < rear + 1; i++) /* 长度为rear+1的数组内查找相同的字符 */
if(queue[i] == ch){ /* 如果找到了,则进行如下计算 */
front = i + 1;
for(j = 0; j < (rear - i); j++) /* 从j开始,把rear-i个字符移动到队首 */
queue[j] = queue[front++];
rear -= i; /* 重置队列尾部 */
queue[rear] = ch; /* 把新读取的字符添加在尾部 */
flag = 0;
break;
}
if(flag) /* 如果数组内没有找到相同的字符,则把新字符添加在队列尾部 */
queue[++rear] = ch;
else
flag = 1;
if(maxlen < rear + 1){ /* 保存数组最长记录*/
maxlen = rear + 1;
for(i = 0; i < maxlen; i++) /* 记录下最长的子字符串 */
sub[i] = queue[i];
sub[i] = '\0';
empty_node();
create_node(str_dup(sub));
}else if(maxlen == rear + 1){
for(i = 0; i < maxlen; i++) /* 记录下相同长度的子字符串 */
sub[i] = queue[i];
sub[i] = '\0';
printf("%s", sub);
add_node(str_dup(sub));
}
front = 0;
// for(i = 0; i <= rear; i++) /* 此三行为调试用代码 */
// printf("%c", queue[i]);
// printf("\trear = %d\n",rear);
}
printf("最长的不重复字符串为:");
// for(i = 0; i <maxlen; i++)
// printf("%c", sub[i]);
print_node();
printf("共有%d个字符\n", maxlen);
empty_node();
return 0;
}
void add_node(char *s) // 添加新节点
{
LNode *np, *newp, *previous;
if((newp = (LNode *)malloc(sizeof(LNode))) == NULL){
printf("申请内存失败,无法添加新节点\n");
exit(1);
}
newp->sub = s;
newp->nextp = NULL;
np = rootp;
while(np != NULL){
previous = np;
np = np->nextp;
}
previous->nextp = newp;
}
void empty_node(void) // 清空链表,释放内存
{
LNode *np, *temp;
for(np = rootp; np != NULL; free(temp) ){
temp = np;
free(temp->sub);
np = np->nextp;
}
rootp = NULL;
}
void print_node(void) //打印链表
{
LNode *np;
for(np = rootp; np != NULL; np = np->nextp )
printf("\"%s\",",np->sub);
}
void create_node(char *s) // 创建新的链表
{
if(rootp != NULL){
printf("链表未清空!\n");
exit(2);
}
if((rootp = (LNode *)malloc(sizeof(LNode))) == NULL){
printf("申请内存失败,无法添加新节点\n");
exit(1);
}
rootp->sub = s;
rootp->nextp = NULL;
}
char *str_dup(char *s) /* 复印S到某个位置 */
{
char *p;
p = (char *)malloc(strlen(s) + 1);
if(p != NULL)
strcpy(p, s);
return p;
}
// 用链表实现保存多个相同长度字符串,感觉整得越来越复杂了,不过通过这个例子学会了如何操控队列和简单链表。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 50
typedef struct LNODE{
struct LNODE *nextp;
char* sub;
}LNode;
LNode *rootp = NULL;
void add_node(char *s);
void empty_node(void);
void print_node(void);
char *str_dup(char *s);
void create_node(char *s);
int main(void)
{
char queue[MAXSIZE];
char sub[MAXSIZE];
int front, rear, maxlen;
int i, j, ch, flag = 1;
queue[0] = getchar(); /* 读取第一个字符,不读取程序没办进行比较 */
front = rear = maxlen = 0; /* front,rear分别为队列第一,最后一个字符的下标 */
while((ch = getchar()) != '\n' && maxlen < MAXSIZE){
for(i = 0; i < rear + 1; i++) /* 长度为rear+1的数组内查找相同的字符 */
if(queue[i] == ch){ /* 如果找到了,则进行如下计算 */
front = i + 1;
for(j = 0; j < (rear - i); j++) /* 从j开始,把rear-i个字符移动到队首 */
queue[j] = queue[front++];
rear -= i; /* 重置队列尾部 */
queue[rear] = ch; /* 把新读取的字符添加在尾部 */
flag = 0;
break;
}
if(flag) /* 如果数组内没有找到相同的字符,则把新字符添加在队列尾部 */
queue[++rear] = ch;
else
flag = 1;
if(maxlen < rear + 1){ /* 保存数组最长记录*/
maxlen = rear + 1;
for(i = 0; i < maxlen; i++) /* 记录下最长的子字符串 */
sub[i] = queue[i];
sub[i] = '\0';
empty_node();
create_node(str_dup(sub));
}else if(maxlen == rear + 1){
for(i = 0; i < maxlen; i++) /* 记录下相同长度的子字符串 */
sub[i] = queue[i];
sub[i] = '\0';
printf("%s", sub);
add_node(str_dup(sub));
}
front = 0;
// for(i = 0; i <= rear; i++) /* 此三行为调试用代码 */
// printf("%c", queue[i]);
// printf("\trear = %d\n",rear);
}
printf("最长的不重复字符串为:");
// for(i = 0; i <maxlen; i++)
// printf("%c", sub[i]);
print_node();
printf("共有%d个字符\n", maxlen);
empty_node();
return 0;
}
void add_node(char *s) // 添加新节点
{
LNode *np, *newp, *previous;
if((newp = (LNode *)malloc(sizeof(LNode))) == NULL){
printf("申请内存失败,无法添加新节点\n");
exit(1);
}
newp->sub = s;
newp->nextp = NULL;
np = rootp;
while(np != NULL){
previous = np;
np = np->nextp;
}
previous->nextp = newp;
}
void empty_node(void) // 清空链表,释放内存
{
LNode *np, *temp;
for(np = rootp; np != NULL; free(temp) ){
temp = np;
free(temp->sub);
np = np->nextp;
}
rootp = NULL;
}
void print_node(void) //打印链表
{
LNode *np;
for(np = rootp; np != NULL; np = np->nextp )
printf("\"%s\",",np->sub);
}
void create_node(char *s) // 创建新的链表
{
if(rootp != NULL){
printf("链表未清空!\n");
exit(2);
}
if((rootp = (LNode *)malloc(sizeof(LNode))) == NULL){
printf("申请内存失败,无法添加新节点\n");
exit(1);
}
rootp->sub = s;
rootp->nextp = NULL;
}
char *str_dup(char *s) /* 复印S到某个位置 */
{
char *p;
p = (char *)malloc(strlen(s) + 1);
if(p != NULL)
strcpy(p, s);
return p;
}
// 用链表实现保存多个相同长度字符串,感觉整得越来越复杂了,不过通过这个例子学会了如何操控队列和简单链表。
[此贴子已经被作者于2016-12-11 11:05编辑过]
一切都在学习、尝试、摸索中