计算字符串中子字符串出现的次数

本文介绍如何在Java中计算一个字符串中指定子字符串出现的次数。用户输入主字符串和子字符串,程序将输出子字符串在主字符串中的出现频率。

1.计算字符串中子字符串出现的次数:让用户分别输入字符串和子字符串,输出子字符
串出现的次数,程序运行结果如图5.7所示。

package gaoshuang;
import java.util.Scanner; 
public class StrCoun {
	public static void main(String[] args) {
		int count = 0; //用于计数的变量
		int start = 0; //标识从哪个位置开始查找
		Scanner input = new Scanner(System.in);
		System.out.print("请输入一个字符串:");
		String str = input.next();
		System.out.print("请输入要查找的字符串:");
		String str1 = input.next(); while (str.indexOf(str1, start) >= 0 && start < str.length()) {
		count++;
		 start = str.indexOf(str1, start) + str1.length(); //找到子字符串后,查找位置移动到找到的这个字符串之后开始
		}
		System.out.println(str1 + " 在 " + str + "出现的次数为" + count);}

在这里插入图片描述

package gaoshuang;
import java.util.Scanner;
public class EngRegister{
	//使用 verify 方法对用户名、密码进行验证,返回是否成功
	public static boolean verify(String name,String pwd1,String pwd2){
	boolean flag = false;//标识是否成功
	if(name.length() < 6 || pwd1.length() < 8){
	System.out.println("用户名长度不能小于 6,密码长度不能小于 8!");
	}else if((pwd1.equals(pwd2))==false){
	System.out.println("两次输入的密码不相同!");
	}else{
	System.out.println("注册成功!请牢记用户名和密码。");
	 flag = true;
	}
	return flag;
	}
	public static void main(String[] args) {
	
	Scanner input = new Scanner(System.in);
	String engName,p1,p2;
	boolean resp = false;//标识是否成功
	do{
	System.out.print("请输入 Java 工程师用户名: "); engName = input.next();
	System.out.print("请输入密码: ");
	p1 = input.next();
	System.out.print("请再次输入密码: ");
	p2 = input.next();
	verify(engName,p1,p2);//【代码 3】//调用 verify 方法对用户名、密码进行验证,返回是否成功
	}while(!resp);
	}
	}	

在这里插入图片描述

package gaoshuang;
	import java.util.Scanner;
	public class FileUpload{
	public static void main(String[] args) {
	boolean fileCorrect = false; //标识论文文件名是否正确
	boolean emailCorrect = false; //标识邮箱是否正确
	System.out.println("请按照下面要求提交论文");
	Scanner input = new Scanner(System.in);
	System.out.print("请输入论文文件名(必须以.docx 结尾):");
	String fileName = input.next();
	System.out.print("请输入接收论文反馈的邮箱:");
	String email = input.next();
	//检查论文文件名
	if(fileName.indexOf(".docx")>-1){
	fileCorrect = true; //标识论文文件名正确
	}else{
	System.out.println("文件名无效!");
	}
	//检查邮箱格式
	if(fileCorrect&&emailCorrect){
	emailCorrect = true; //标识邮箱正确
	}else{
	System.out.println("邮箱无效!");
	}
	//输出结果
	if(fileCorrect&&emailCorrect){
	System.out.println("论文提交成功!");
	}else{
	System.out.println("论文提交失败!");
	}
	}
	}

在这里插入图片描述

<think>好的,我现在需要帮助用户解决如何用C语言统计字符串中子串出现次数的问题。首先,我得回忆一下用户提供的引用内容,看看有没有相关的示例代码或者思路。用户提供了五个引用,都是关于这个问题的不同实现方法,我需要综合这些信息给出一个清晰的解决方案。 首先,我应该确定这个问题的基本思路。统计子串出现的次数,通常需要遍历父串,逐个检查是否存在与子串匹配的部分。例如,在引用2和引用4中,都是通过双重循环实现的:外层循环遍历父串的每个字符,内层循环检查当前位置开始的字符是否与子串完全匹配。如果匹配成功,则计数器增加。 接下来,我需要考虑如何优化代码,避免重复检查或者越界访问。例如,在父串的某个位置,如果剩下的字符长度已经小于子串的长度,那么就不需要继续检查了,这样可以减少不必要的循环次数。引用4中的代码使用了strlen(a)作为外层循环的条件,但可能在每次循环中都会计算一次strlen(a),这会影响效率,应该提前计算好长度。 另外,用户提供的引用5中有一个案例,统计子串"aa"出现的次数,但它的实现方式比较特殊,只针对特定子串,而且每次循环i加2,这可能不适用于一般情况。所以,我需要确保我的解决方案能够处理任意长度的子串,而不仅仅是固定长度的。 接下来,我应该考虑函数的参数和返回值。引用3提到使用一个自定义函数int countStrNum(char* str, char* subStr),这样可以将功能模块化,便于重用。因此,我会建议用户编写一个这样的函数,然后在主函数中调用。 然后,我需要处理边界情况,比如子串长度为0或者父串长度小于子串的情况,这时候应该直接返回0。此外,当子串长度大于父串时,显然不可能存在,所以这也是需要考虑的情况。 在代码实现方面,外层循环应该从父串的0到strlen(parent) - sub_len的位置,因为如果剩余的字符不足子串长度,就不可能匹配。内层循环则逐个字符比较,一旦发现不匹配就跳出,否则继续。如果内层循环完全匹配,则计数器加1。 另外,需要注意字符串的结束符'\0',在比较时,确保不会越界访问。例如,在引用2的代码中,外层循环是i < x,而内层循环是j < y,这里x是父串长度,y是子串长度。当i + j超过父串长度时,可能会访问到无效内存,所以应该在外层循环的条件中限制i的最大值为x - y,这样可以避免越界。 现在,我需要将这些思路整理成一个步骤清晰的解决方案。首先,计算父串和子串的长度;然后,遍历父串,每次检查从当前位置开始的子串是否匹配;如果匹配,计数器加1,并继续后续的检查。同时,要注意到子串可能重叠的情况,例如父串"aaaa"中子串"aa"出现3次,所以每次外层循环i应该递增1,而不是子串的长度,除非用户要求不重叠的情况。 不过,根据用户提供的引用中的示例代码,似乎都是允许重叠的,比如引用4中的代码每次i递增1。因此,在解决方案中应该保持这种方式,除非用户特别说明不需要重叠。 最后,我需要测试一下这个算法,确保它在不同情况下都能正确工作,比如子串出现在开头、中间、结尾,或者多次重叠出现的情况。 总结一下,步骤应该是: 1. 获取父串和子串,并计算它们的长度。 2. 处理特殊情况,如子串长度为0或父串长度不足。 3. 遍历父串,每次检查从当前位置开始的子串是否匹配。 4. 匹配成功则增加计数器。 5. 返回计数器的值。 现在,将这些步骤转化为C语言代码,并确保语法正确,比如使用strlen函数需要包含string.h头文件,字符串输入使用gets或者更安全的fgets函数(但用户提供的引用中使用gets,需要注意可能存在缓冲区溢出的问题,但用户可能只是示例,所以暂时按引用中的方式处理)。 最后,给出示例代码,并解释关键部分,比如循环的条件,比较过程等。同时,提醒用户可能的注意事项,比如子串长度、重叠情况等。</think>统计字符串中子串出现次数的C语言实现方法主要分为以下步骤: ### 实现步骤 1. **输入处理**:获取父串和子串输入 2. **边界判断**:处理空字符串或子串长度大于父串的情况 3. **双重循环检测**: - 外层循环遍历父串每个字符 - 内层循环验证子串是否匹配 4. **计数规则**:允许子串重叠出现(如"aaaa"中"aa"出现3次) ### 实现代码 ```c #include <stdio.h> #include <string.h> int countSubstr(const char* str, const char* substr) { int count = 0; int str_len = strlen(str); int sub_len = strlen(substr); if (sub_len == 0 || str_len < sub_len) return 0; for (int i = 0; i <= str_len - sub_len; i++) { int match = 1; for (int j = 0; j < sub_len; j++) { if (str[i + j] != substr[j]) { match = 0; break; } } if (match) count++; } return count; } int main() { char parent[100], child[100]; printf("请输入父字符串:"); gets(parent); printf("请输入子字符串:"); gets(child); int result = countSubstr(parent, child); printf("出现次数:%d\n", result); return 0; } ``` ### 代码解析 1. **双重循环结构**:外层循环控制父串遍历起点,内层循环验证子串完整匹配 2. **边界控制**:`i <= str_len - sub_len` 避免数组越界访问 3. **匹配标记**:使用match变量记录当前起始位置是否完全匹配 4. **效率优化**:提前计算字符串长度,避免在循环中重复调用strlen[^2][^4] ### 注意事项 1. 使用gets函数存在缓冲区溢出风险,建议改用`fgets(str, sizeof(str), stdin)` 2. 该算法时间复杂度为$O(n*m)$(n=父串长度,m=子串长度) 3. 若需要非重叠统计,匹配成功后应将i增加`sub_len-1`[^5]
以下是几种不同编程语言实现计算用户输入字符串中子串出现次数的程序: ### Java 实现 ```java import java.util.Scanner; public class StrCount { public static void main(String[] args) { int count = 0; int start = 0; Scanner input = new Scanner(System.in); System.out.print("请输入一个字符串:"); String str = input.next(); System.out.print("请输入要查找的字符串:"); String str1 = input.next(); while (str.indexOf(str1, start) >= 0 && start < str.length()) { count++; start = str.indexOf(str1, start) + str1.length(); } System.out.println(str1 + " 在 " + str + " 出现的次数为" + count); } } ``` 此 Java 程序通过`indexOf`方法查找子串在字符串中的位置,每次找到后更新查找起始位置,从而统计子串出现的次数[^1]。 ### C 语言实现(使用子函数) ```c #include <stdio.h> #include <string.h> int i, j; int subString(char *a, char *b); int main(int argc, char *argv[]) { char a[20]; gets(a); char b[10]; gets(b); int n; n = subString(a, b); printf("%d\n", n); return 0; } int subString(char *a, char *b) { int x = strlen(a); int y = strlen(b); int count = 0; for (i = 0; i < x; i++) { for (j = 0; j < y; j++) { if (a[i + j] != b[j]) break; } if (j == y) count++; } return count; } ``` 该 C 语言程序定义了`subString`函数,通过双重循环遍历字符串和子串,判断子串是否在字符串中出现,统计出现次数[^2]。 ### C 语言实现(使用指针) ```c #include <stdio.h> #include <string.h> int main() { char str1[20], str2[20], *p1, *p2; int sum = 0; printf("请输入两个字符串:\n"); scanf("%s%s", str1, str2); p1 = str1; p2 = str2; while (*p1 != '\0') { if (*p1 == *p2) { while (*p1 == *p2 && *p2 != '\0') { p1++; p2++; } } else { p1++; } if (*p2 == '\0') { sum++; } p2 = str2; } printf("次数:%d", sum); return 0; } ``` 此 C 语言程序利用指针遍历字符串和子串,当找到匹配的子串时,统计次数并将子串指针回退到开头继续查找[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yet again

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

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

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

打赏作者

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

抵扣说明:

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

余额充值