华为机试——字符串过滤

题目描述

* 题目:对输入的字符串检查是否存在非法字符,输出合法字符串(去重)和非法字符串(不去重)
*     对合法字符串循环左移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宏定义开关,仅用于调试。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值