纯纯模拟题,但是我写了好久,太难过了。
留下AC代码纪念一下这个疯狂星期四:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N1 201 // 字符串长度最长为200
#define N2 11 // 分隔符最长为10
#define COUNT 20 // 分隔后字符串数量最多为20
int split(char origin[], char sep[],char (*result)[N1])//原字符串origin,分隔符sep,以及存放结果的二维输入result
{
int index=0;
int fore=0;//记录两个sep之间的那个被分割的字符串的第一个字符的下标
int judge=0;//用judge来标记sep是否匹配成功
int count=0;//用来记录分隔的子字符串的个数
char tmp[10010];
//临时数组tmp,用于记录被分割的字符串=>作为中间人将被分割的字符串传给result数组
int idxtmp=0;//临时数组tmp的下标
for(int i=0;i<(int )strlen(origin);i++)//遍历原数组origin
{
memset(tmp,0,sizeof(tmp));//每次循环都初始化tmp(略显繁琐)
while(origin[i]==sep[index]&&i<(int )strlen(origin))
//匹配分割字符串sep 注意i不能越界
{
i++;
index++;
if(index==(int )strlen(sep))//匹配成功!
{
judge=1;//用judge来标记是否匹配成功,以便于接下来的判断(小伏笔)
for(int j=fore;j<i-index;j++)
{
tmp[idxtmp]=origin[j];
//将上一个sep与新发现的sep之间的字符串复制给tmp数组
idxtmp++;
}
strcpy(result[count],tmp);
count++;
break;//退出循环
}
}
if(judge==1&&index==(int )strlen(sep)) index=0,fore=i,judge=0,idxtmp=0;//翻译成人话:if成功匹配,所有条件更新,踏上发现新的sep的道路
//fore=i 记录的是现在这个sep与下一个sep之间的字符串(新一个被截断的字符串)的初始下标 呼应第26~30行的代码
else if(judge==0&&index>0) i--,index=0,judge=0,idxtmp=0;
//这行代码我是用来判断这种情况:origin字符串中有部分与sep匹配,但不是全部
//eg:sep为hello origin为hellhello
else index=0,judge=0,idxtmp=0;
if(i==(int )strlen(origin)-1)//如果最后一个sep后面还有字符串,直接输出即可。
{
idxtmp=0;
memset(tmp,0,sizeof(tmp));
for(int j=fore;j<(int )strlen(origin);j++)
{
tmp[idxtmp]=origin[j];
idxtmp++;
}
strcpy(result[count],tmp);
count++;
return count;
}
}
}
int main(void)
{
char origin[N1];
char sep[N2];
char result[COUNT][N1];
gets(origin);
gets(sep);
int n_result = split(origin,sep,result);
int i;
for(i=0;i<n_result;i++)
{
printf("%s\n",result[i]);
}
return 0;
}
能力有限,算法肯定不是最优解,希望大家多多指教!!!
追加一个更加简洁的思路:第一次循环对每一个sep进行标记,第二次循环输出被分割的字符串时遇到标记就跳过。(感谢某位大佬!!!)
int split(char origin[], char sep[],char (*result)[N1])
{
int cnt=0;//用来记录分隔符出现的次数(标记二维数组的维度)
int len1=strlen(origin);
int len2=strlen(sep);
int i=0;
for(;i<len1;)
{
if(strstr(origin,sep)==NULL) break;
i=strstr(origin,sep)-origin;//查找分隔符的位置并用i标记
origin[i]='*';//把分隔符的首元素赋值为‘*’=>下面循环每次碰到‘*’就跳
}
for(int j=0,k=0;j<len1;j++)
{
if(origin[j]=='*')
{
memset(result[cnt+1],0,sizeof(result[cnt]));
j+=len2-1;k=0;cnt++;
continue;
}
else result[cnt][k++]=origin[j];
}
return cnt+1;
}