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