22程设I-周14-课后1

 纯纯模拟题,但是我写了好久,太难过了。

留下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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值