使用C语言,编写函数,实现对给定的字符串(包含英文字母、数字、符号)的处理,经处理的字符串按照字母、数字、符号的顺序排放,顺序不变。
思路1:先统计字母、数字、符号的个数,假设分别为a,b,c,字符串总长度是d,那么字母下标分布应该是:[0, a-1],数字下标分布应该是:[a, a+ b- 1],符号下标分布应该是:[a+ b, d - 1]。定义一个临时空间,拷贝原字符串到这个临时空间,然后遍历临时空间,按照下标分布赋值到源字符串对应位置。这个方法较容易理解和实现。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int reorder_str1(char* pStr)
{
//统计字母、数字、符号的个数
int nLetterCnt = 0;
int nDigitCnt = 0;
int nStrLen = strlen(pStr);
for (int i = 0; i < nStrLen; ++i) {
if ((pStr[i] >= 'a' && pStr[i] <= 'z') || (pStr[i] >= 'A' && pStr[i] <= 'Z')) {
++nLetterCnt;
}
else if (pStr[i] >= '0' && pStr[i] <= '9') {
++nDigitCnt;
}
}
char* pTmpStr = (char *)malloc(nStrLen);
if (pTmpStr == NULL) {
return -1;
}
strcpy(pTmpStr, pStr);
//字母下标取值:[0, nLetterCnt -1]
//数字下标取值:[nLetterCnt, nLetterCnt + nDigitCnt - 1]
//符号下标取值:[nLetterCnt + nDigitCnt, nStrLen - 1]
int nLetterIndex = 0;
int nDigitIndex = nLetterCnt;
int nOtherIndex = nLetterCnt + nDigitCnt;
for (int i = 0; i < nStrLen; ++i) {
if ((pTmpStr[i] >= 'a' && pTmpStr[i] <= 'z') || (pTmpStr[i] >= 'A' && pTmpStr[i] <= 'Z')) {
pStr[nLetterIndex++] = pTmpStr[i];
}
else if (pTmpStr[i] >= '0' && pTmpStr[i] <= '9') {
pStr[nDigitIndex++] = pTmpStr[i];
}
else {
pStr[nOtherIndex++] = pTmpStr[i];
}
}
free(pTmpStr);
return 0;
}
int main()
{
//A,2.d?3!e4r87we79 --> Aderwe2348779,.?!
char szBuf[32] = { 0 };
strcpy(szBuf, "A,2.d?3!e4r87we79");
printf("Before szBuf=[%s]\n", szBuf);
reorder_str1(szBuf);
printf("After szBuf=[%s]\n", szBuf);
return 0;
}
在VS2019上运行free(pTmpStr)会报错,具体原因没有深究。调整程序在CentOS7.8编译运行,因为for (int i = 0; i < nStrLen; ++i)的原因,再CentOS7.8下面得加上-std=c99编译,编译命令如下gcc -std=c99 -o test test.c,程序运行结果如下: