输入一行字符,将字符串中最长的单词输出

本文介绍了一种算法思路,通过遍历输入字符串,找到以空格分隔的单词,并找出其中最长的一个。关键在于维护当前最长单词的起始和结束下标,以节省空间。代码示例展示了如何实现这一功能,适合处理带空格的字符串输入。

题目:

输入一行字符,栗如:hello i like code  输出hello;如果一行字符最长的单词有多个,则输出最后保存的最长单词。如输入:okli mnbv 则输出为:mnbv

思路:

单词以空格进行分隔,因此寻找空格出现的位置即为关键,每次从单词的起始到空格出现的位置即为一个单词,此时计算单词的长度,如果比当前最大的还长,就进行更新最长单词的信息,当整个字符串遍历完成,即找到最长的单词。

假如我们输入lmn defgk,我们设每个单词开头字母的下标为a初始化为0(为了解决字符一开始是空格),单词结尾字母下标为b,在循环中第一个空格下标i等于3,则前面单词结尾序号为b=i-1,那么如lmn这个结尾字母下标为2,那么单词长度就为b-a+1;从头开始遍历,每遍历完一个单词(遇到空格)我们需要一个maxlen用来记录这个单词的长度,用来和下一次单词的长度进行比较,如果下一个单词长度大于maxlen,我们需要将maxlen保存的信息更新。此外为了节省空间,不额外定义数组来保存最长的单词,我们定义两个变量用来储存最长单词的首,尾下标,最后输出从原数组中找到这一段下标输出,即为保存的最长单词。

代码示例:

void Std(char crr[])
{
	int a = 0, b; //每一个单词第一个字符的下号为a  最后一个为b
					   //单词长度为b-a+1
	int start = 0, end = 0;   //储存最长单词首尾字符下标
	int maxlen = 0; //来储存最长单词默认为0
	int len = strlen(crr);

	for (int i = 0; i < len + 1; i++) //len+1为了能遍历到最后一个单词 
	{
		if (crr[i] == ' ' || crr[i] == '\0')  //字符串最后面是'\0'
		{
			b = i - 1;

			if ((b - a + 1) > maxlen)
			{
				maxlen = b - a + 1;
				start = a;
				end = b;
			}
			a = i + 1; //开始下一个字符的遍历 i是前面的空格下标 a为新字符第一个下标
		}

	}
	for (int i = start; i <= end; i++)  //从记录的最长单词的开头下标开始到结尾下标输出单词
	{
		printf("%c", crr[i]);
	}
	printf("\n");
}

int main()
{
	char arr[50];
	printf("请输入一行字符:");
	//scanf("%s", arr);   遇到空格结束
    //gets(arr);  不安全,勿用
	fgets(arr, 50, stdin);
	Std(arr);

	return 0;
}

测试用例:

注意******

scanf函数扫描字符串时,若遇到" "会判定扫描结束,因此在输入带空格的字符串时,不要用。

因此很多人在输入带空格的字符串时习惯使用gets()函数。gets可以无限读取字符串,不会判断上限,以回车结束读取。但是gets函数具有危险性,如今大多编译器已经不支持。

gets() 函数的形参只有一个指针。它会从标准输入流中读字符到一块连续的内存地址空间中。这块地址空间的开始位置就是指针 str 指向的位置。当在输入流中遇到文件结束符( EOF )或者换行符(n)时,读取操作结束。当读入换行符(n)时,该字符不会被放入那块连续的地址空间中。在读取结束时, gets() 会自动在内存空间的末尾追加一个 NULL 字符。经过上述这些操作,对于程序员来说,这个函数得到的就是从标准输入进来的,以 NULL 字符结尾的C字符串。如果读入的字符流是一整行的话,行尾的换行符将会被舍去。由于gets()无法知道字符串的大小,必须遇到换行字符或文件尾才会结束输入,这个函数只有一个指针作为参数,该指针指向的内存空间将用于保存读入数据。但是 gets() 函数无法知道它需要使用多大的内存空间。如果在标准输入中读入足够长的,不包含换行符的字符留, gets() 函数肯定会覆盖掉指定的内存区域。

那么如何改进?我推荐大家使用fgets函数,函数原型  char *fgets(char *buf, int bufsize, FILE *stream);

从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。与gets相比使用这个好处是:读取指定大小的数据,避免gets函数从stdin接收字符串而不检查它所复制的缓存的容积导致的缓存溢出问题。

正如我上述代码表示    fgets(arr, 50, stdin); 从键盘最多读取49个字符到arr数组中,第50个是'\0'

stdin从键盘读取数据,stdout将数据输出到屏幕上

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BearPot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值