题目描述
* 题目:对输入的字符串检查是否存在非法字符,输出合法字符串(去重)和非法字符串(不去重)
* 对合法字符串循环左移10次,再进行排序输出。(举例:比如字符串“abc”,循环左移一次的结果为“bca”)
*
* 输入描述:
* (1) 字符串中的字符集合为’0’ - ‘9’,‘a’ - ‘z’,‘A’ - ‘Z’,其余为非法字符(空字符串作为定界符),有非法字符的字符串被视为非法输入
* (2) 作为输入的字符串个数不超过100,每个字符串长度不超过64
* (3) 作为输入的连续空字符串(空格/制表符/回车/换行符)作为一个空格处理(作为定界符,字符串起始字符不为空)
* (4) 输入每行只有一个字符串
* (5) 输入以空行结束
*
* 输出描述:
* (1) 输出合法字符串并去重
* (2) 输出所有非法字符串
* (3) 对结果(1)的去重合法字符串循环左移10次
* (4) 对结果(3)合法字符串排序,按ASCII表字符从小到大顺序排序
代码实现
/************************************************************************************
* 题目:对输入的字符串检查是否存在非法字符,输出合法字符串(去重)和非法字符串(不去重)
* 对合法字符串循环左移10次,再进行排序输出。(举例:比如字符串“abc”,循环左移一次的结果为“bca”)
*
* 输入描述:
* (1) 字符串中的字符集合为’0’ - ‘9’,‘a’ - ‘z’,‘A’ - ‘Z’,其余为非法字符(空字符串作为定界符),有非法字符的字符串被视为非法输入
* (2) 作为输入的字符串个数不超过100,每个字符串长度不超过64
* (3) 作为输入的连续空字符串(空格/制表符/回车/换行符)作为一个空格处理(作为定界符,字符串起始字符不为空)
* (4) 输入每行只有一个字符串
* (5) 输入以空行结束
*
* 输出描述:
* (1) 输出合法字符串并去重
* (2) 输出所有非法字符串
* (3) 对结果(1)的去重合法字符串循环左移10次
* (4) 对结果(3)合法字符串排序,按ASCII表字符从小到大顺序排序
***************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
/* 字符串的长度和数量 */
#define STR_SIZE 64
#define STR_NUM 100
/* 检查字符串是否有不合法字符,根据题目定义合法性 */
#define STR_ILLEGAL 0
#define STR_LEGAL 1
/* 定义左移的位数 */
#define LEFT_LEN 10
#define DEBUG
typedef struct data_base
{
char str[STR_SIZE];
int legal_flag;
}STR_T;
/* 检查是否合法 */
int check_legal(STR_T* src)
{
if(NULL == src)
{
#ifdef DEBUG
printf("[Error]:Input is NULL!Func:%s Line:%d.\n\r",__FUNCTION__,__LINE__);
#endif
return -1;
}
char* check_point = src->str;
while(*check_point) /* 遍历字符串 */
{
if( (*check_point <= '9' && *check_point >= '0') ||\
(*check_point <= 'z' && *check_point >= 'a') ||\
(*check_point <= 'Z' && *check_point >= 'A') ) /* 合法字符:'0'-'9','a'-'z','A'-'Z' */
{
src->legal_flag = STR_LEGAL;
check_point++;
}
else
{
src->legal_flag = STR_ILLEGAL; /* 否则字符串不合法 */
return 0;
}
}
return 0;
}
/* 字符串去重 */
int dedup_str(STR_T* src)
{
if(NULL == src)
{
#ifdef DEBUG
printf("[Error]:Input is NULL!Func:%s Line:%d.\n\r",__FUNCTION__,__LINE__);
#endif
return -1;
}
char* check_point = src->str;
char current_point[2];
char pass_buf[64]; /* 已遍历过的字符串,从前面开始 */
while(*check_point) /* 遍历字符串 */
{
memset(current_point,0,sizeof(current_point));
memset(pass_buf,0,sizeof(pass_buf));
memcpy(pass_buf,src->str,sizeof(char)*(check_point-src->str));
current_point[0] = *check_point;
if(NULL != strstr(pass_buf,current_point)) /* 在已遍历过得字符串中查找是否有重复的 */
{
memmove(check_point,check_point+1,strlen(check_point)); /* 移动存储空间覆盖,该操作意味着从前往后查重,后面重复的会被覆盖 */
}
else/* 没有重复 */
check_point++;
}
return 0;
}
/* 左右移动字符 */
int str_left_right(STR_T* src,int len)
{
if(NULL == src)
{
#ifdef DEBUG
printf("[Error]:Input is NULL!Func:%s Line:%d.\n\r",__FUNCTION__,__LINE__);
#endif
return -1;
}
char* move_point = src->str + (len-1)%strlen(src->str); /* 将指针移动到移动的临界点 */
char tmp_buf[64];
memset(tmp_buf,0,sizeof(tmp_buf));
memcpy(tmp_buf,move_point,strlen(move_point)); /* 从临界点后面移动长度为strlen的字符串到前面 */
memcpy(tmp_buf+strlen(tmp_buf),src->str,sizeof(char)*(move_point-src->str)); /* 将前半截字符串拷贝到新的字符串中 */
memcpy(src->str,tmp_buf,strlen(tmp_buf)); /* 将新字符串拷贝回去 */
return 0;
}
int str_sort(STR_T* src)
{
if(NULL == src)
{
#ifdef DEBUG
printf("[Error]:Input is NULL!Func:%s Line:%d.\n\r",__FUNCTION__,__LINE__);
#endif
return -1;
}
int i,j;
char tmp;
/* 冒泡排序 */
for(i=0;i<strlen(src->str);i++)
{
for(j=i;j<strlen(src->str);j++)
{
if(src->str[i] > src->str[j])
{
tmp = src->str[i];
src->str[i] = src->str[j];
src->str[j] = tmp;
}
}
}
return 0;
}
void main()
{
STR_T input[STR_NUM];
int in_point = 0;
int i,res=0;
memset(input,0,sizeof(STR_T)*STR_NUM);
#ifdef DEBUG
printf(">>>>>>>>>>>> Start Test <<<<<<<<<<<<<<<<\n\r");
#endif
while(1)
{
#ifdef DEBUG
printf("[提示]:请输入%d个字符串:\n\r",in_point+1);
#endif
/*scanf("%s",&input[in_point].str);*/
gets(input[in_point].str); /* gets可检测空字符串并输入 */
if(0 == strlen(input[in_point].str))
{
#ifdef DEBUG
printf("[提示]:输入空字符串,退出录入,进入解析.\n\r");
#endif
break;
}
else
{
#ifdef DEBUG
printf("[提示]:当前输入字符串:%s\n\r",input[in_point].str);
#endif
if(0 != check_legal(&input[in_point])) /* 检查字符串里是否有不合法的字符,标记到legal_flag,0为不合法,1为合法 */
{
#ifdef DEBUG
printf("[Error]:check str func return no zero!\n\r");
#endif
}
in_point ++;
}
}
/* 对合法字符串去重 */
for(i=0;i<in_point;i++)
{
if(STR_LEGAL == input[i].legal_flag)
{
res = dedup_str(&input[i]);
#ifdef DEBUG
if(0 == res)
printf("[提示]:第%d合法字符串去重结果:%s\n",i,input[i].str);
else
printf("[提示]:第%d合法字符串去重失败!!\n",i);
#endif
}
}
#ifdef DEBUG
printf(">>>>>>>>>>>>>> 输出合法去重字符串 <<<<<<<<<<<<<<<<\n");
#endif
/* 输出去重合法字符串 */
for(i=0;i<in_point;i++)
{
if(STR_LEGAL == input[i].legal_flag)
{
#ifdef DEBUG
printf("[提示]:第%d去重合法字符串:%s\n",i,input[i].str);
#else
printf("%s\n",input[i].str);
#endif
}
}
#ifdef DEBUG
printf(">>>>>>>>>>>>>> 输出不合法字符串 <<<<<<<<<<<<<<<<\n");
#endif
/* 输出不合法字符串 */
for(i=0;i<in_point;i++)
{
if(STR_ILLEGAL == input[i].legal_flag)
{
#ifdef DEBUG
printf("[提示]:第%d不合法字符串:%s\n",i,input[i].str);
#else
printf("%s\n",input[i].str);
#endif
}
}
/* 合法字符串的字符左右移动 */
for(i=0;i<in_point;i++)
{
if(STR_LEGAL == input[i].legal_flag)
{
res = str_left_right(&input[i],LEFT_LEN);
#ifdef DEBUG
if(0 == res)
printf("[提示]:左移动%d位后的合法去重字符串:%s\n",LEFT_LEN,input[i].str);
else
printf("[提示]:第%d合法字符串移动失败!!\n",i);
#endif
}
}
/* 合法字符串排序 */
for(i=0;i<in_point;i++)
{
if(STR_LEGAL == input[i].legal_flag)
{
res = str_sort(&input[i]);
#ifdef DEBUG
if(0 == res)
printf("[提示]:第%d合法字符串排序后结果:%s\n",i,input[i].str);
else
printf("[提示]:第%d合法字符串排序失败!!\n",i);
#endif
}
}
}
测试描述
注意事项
依据需求裁剪,注意关闭DEBUG宏定义开关,仅用于调试。