华为机考试题学习1——字符串最后一个单词的长度

题目描述:

描述

        对于给定的若干个单词组成的句子,每个单词均由大小写字母混合构成,单词间使用单个空格分隔。输出最后一个单词的长度。

输入描述:

        在一行上输入若干个字符串,每个字符串代表一个单词,组成给定的句子。
        除此之外,保证每个单词非空,由大小写字母混合构成,且总字符长度不超过 10^{3}

输出描述:

        在一行上输出一个整数,代表最后一个单词的长度。

示例

示例
输入输出描述
HelloNowcoder13最后一个单词是 ‘HelloNowcoder’,长度为 13
A B C D1最后一个字符为‘D’,则输出为1

特别注意:

社区讨论中,大家提出了输入字符串尾端为空格的情况,确实需要额外讨论。

        如:‘I am a student’        句子中。结尾没有空格,可以进行简单算法计算。

        如:‘I am acturally not human  ’        句子中,结尾出现了两个空格,则可能需要额外讨论。

分析与解题思路:

①简单版(考虑结尾空格):

        用循环接收字符,在开始时开始计数,检测到空格的时候重新计数,计数为非空格输入量,最后计数的值就是最后一个单词的长度。

//最简单的方法就是,根本就不需要存储字符串,直接单个字符循环输入并计数
//直接计算长度就可以了,也不需要动态的复杂的数据结构
#include <stdio.h>

int main()
{
	char ch;
	int n = 0;
	int flag = 0;

	while(1)
	{
		ch = getchar();		//每一个字符单独输入 
		
		if(ch == '\n')		//检测回车,输入结束,跳出循环 
		{
			break;
		}
		else if(ch != ' ')	//检测到不是空格,则开始计数 
	 	{
			if(flag == 0)
			{
				n = 0;
				flag = 1;
			}
			n++;
		}
		else				//检测到空格,则不计数,并把标志置零 
		{
			flag = 0;
		}
	}
	printf("%d\n", n);		//最后得到最后一个单词所含字符数为:n 
	return 0;
}

输入'I am a student' ,输出为7

输入‘ I am a student  ’(结尾带空格),输出为也7

②数组版(倒序查询,考虑结尾空格)

        该函数中,无论最后有咩有空格输入,数组最后一位存的都是‘\n’这个字符,所以计算末尾位置的时候需要跳过。

         而当只有一个单词或字母输入的时候,行18的while会将j减到负值,出现word[-1]的错误情况,为了避免,在下一行规定 j 的值不能小于0。

#include <stdio.h>
#define MAX 1000			// 最大长度 

int main()
{
	int i,j,n;				//	n用来计数 
	char word[MAX];
	
	i = j = n = 0;
	while((word[i]=getchar()) != '\n')
		i++ ;
	
	while( word[i] == ' '|| word[i]=='\n')	
		i-- ;				// 找到字符串非空格的末尾,回车也跳 

	j = i ;	
	
	while( word[j] != ' ')	// 找到末尾单词的字头的前一个空格 	
	{
		if  (j==0) 			//当输入只有一个单词时候,特别讨论 
		{	
			j--;			
			break;
		}
		j-- ;
		
	}				
	n = i-j ;
	printf("%d\n",n);	 
}

③字符串版(倒序查询,考虑结尾空格)

        和数组版类似,只不过输入输出改为字符串的形式。

#include <stdio.h>
#define MAX 1000			// 最大长度 

int main()
{
	int i,j,n;			//	n用来计数 
	i=j=n=0;
	char word[MAX];
	
	gets(word); 
	for(;word[i]!='\0';i++);		//找到字符串的末尾 
	
	while( word[i] == ' '|| word[i]=='\0')	
		i-- ;				// 找到字符串非空格的末尾,回车也跳 

	j = i ;	
	
	while( word[j] != ' ')	// 找到末尾单词的字头的前一个空格 	
	{
		if  (j==0) 			//当输入只有一个单词时候,特别讨论 
		{	
			j--;			
			break;
		}
		j-- ;	
	}				
	n = i-j ;
	printf("%d\n",n);	 
}

<think>好的,我需要帮助用户理解华为考中计算字符串最后一个单词长度的算法。首先,用户的问题是关于这个题目使用了哪种算法,我需要结合提供的引用内容来回答。 先看一下用户提供的引用,共有五个引用。引用1到5都是关于华为试的题目,特别是HJ1,也就是计算字符串最后一个单词长度。例如,引用3中提到了C++的代码,引用4是Python的代码,引用5讨论了输入函数的使用。这些引用中的代码和描述应该能帮助我分析所用的算法。 首先,题目要求是输入一个字符串,由多个单词组成,以空格分隔,要求输出最后一个单词长度。注意字符串末尾没有空格。例如输入"hello nowcoder",输出8,因为最后一个单词是"nowcoder"。 接下来,我需要确定这个问题使用的算法。一般来说,处理这种字符串问题,常用的方法有两种:一种是分割字符串,直接取最后一个元素计算长度;另一种是从字符串末尾反向遍历,统计字符直到遇到空格或开头为止。这两种方法在时和空复杂度上可能有所不同。 查看引用中的代码示例,例如引用3的C++代码,它从字符串的末尾开始向前遍历,直到遇到第一个空格为止,统计非空格字符的数量。这说明他们使用的是反向遍历的方法,而不是分割字符串。引用4中的Python代码可能更简洁,可能用的是split方法,但用户提供的引用4中的代码片段不完整,不过根据常见的Python实现,可能使用了类似的方法。例如,用户提到的函数get_last_string_len可能内部用了split,但需要具体看代码。不过引用3的C++代码明显是反向遍历,所以这可能更接近华为考的解法。 另外,引用5提到了使用scanf函数来读取输入,可能考虑到输入中有多个空格的情况,但具体到这个问题,无论输入中有多少空格,最后一个单词都是最后一个非空格字符序列。因此,反向遍历是更高效的方法,因为它不需要处理整个字符串,只需要从后往前找到第一个空格的位置即可,这在最坏情况下时复杂度是O(n),但避免了分割整个字符串带来的O(n)空复杂度。 总结一下,华为考可能主要考察反向遍历的算法,因为它更高效,尤其是在处理大字符串时,不需要额外的存储空。而像Python这样的语言可能因为split的简洁性而采用不同的方法,但核心思路是一样的。因此,可以回答用户该算法是反向遍历,统计最后一个单词长度。 接下来,我需要确保回答符合用户的要求,即结构清晰,分步骤解释,引用相关引用。同时,要生成相关问题,并正确标注引用来源。 可能的问题点:需要确认是否所有引用的代码都采用相同的方法。例如,引用3的C++代码是反向遍历,引用4的Python代码如果是split的话则是另一种方法,但根据问题中的引用,华为试可能有多种解法,但主要考察的是算法效率,因此反向遍历可能更被推荐。不过,用户的问题是关于华为使用了哪种算法,所以需要根据提供的引用内容来判断。 查看引用中的代码,引用3的C++代码是明确的反向遍历,而引用4的Python代码可能用split,但根据用户给出的引用4中的代码,可能没有给出具体实现,所以可能split也是一种方法。不过,根据引用3的例子,华为的官方题解可能更倾向于反向遍历,因为这样更高效,尤其是考虑到字符串可能很长的情况下。 因此,在回答中应该说明两种可能的思路,但指出华为考中可能更倾向于使用反向遍历的方法,并引用相应的例子,如引用3中的C++代码。 最后,生成相关问题,例如分割字符串的方法与反向遍历的优缺点,如何处理特殊情况,或者不同编程语言中的实现差异等。</think>### 字符串最后一个单词长度的算法解析 华为考题目要求计算字符串最后一个单词长度,其核心算法可归纳为以下两种实现思路: #### 方法1:反向遍历(推荐) **算法步骤**: 1. **从字符串末尾开始向前遍历**,忽略末尾可能的连续空格(若题目允许末尾有空格,需先处理) 2. **统计连续非空格字符的数量**,直到遇到第一个空格或遍历到字符串开头 3. **输出统计结果** **代码示例(C++)**: ```cpp #include <iostream> #include <string> using namespace std; int main() { string str; getline(cin, str); int count = 0; for (int i = str.length() - 1; i >= 0; i--) { if (str[i] != ' ') count++; else if (count > 0) break; // 遇到空格且已统计到字符时终止 } cout << count << endl; return 0; } ``` **优势**: - **时复杂度为$O(n)$**,仅需一次遍历 - **空复杂度为$O(1)$**,无需额外存储[^3] --- #### 方法2:分割字符串(适用于短字符串) **算法步骤**: 1. **按空格分割字符串**为单词列表 2. **取列表最后一个元素**并计算其长度 **代码示例(Python)**: ```python s = input().strip() words = s.split() print(len(words[-1]) if words else 0) ``` **注意**: - 需处理输入全为空格的特殊情况[^4] - **时复杂度为$O(n)$**,但分割操作需要额外空存储所有单词[^4] --- ### 华为考的实际应用 根据引用中的C++实现,华为考**更倾向于反向遍历方法**。这种算法直接操作字符串,避免内存浪费,尤其适合处理长字符串(题目限制字符串长度<5000)[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值