華爲機試——字符串過濾

題目描述

* 題目:對輸入的字符串檢查是否存在非法字符,輸出合法字符串(去重)和非法字符串(不去重)
*     對合法字符串循環左移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宏定義開關,僅用於調試。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章