字串统计

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 //定义子串参数结构体 
 5 struct sub_str
 6 {
 7     char sstr[61]; //子串 
 8     int len; //子串长度 
 9     int times; //子串出现的次数 
10 };
11 
12 int main()
13 {
14     int i,j,k;
15     int l,l_temp; //l:用于记录输入的要统计的子串的最小长度;l_temp:用于记录遍历子串时的临时动态子串长度 
16     char str[61],sstr_temp[61]; //str:用于指向输入的要统计的字符串;sstr_temp:用于指向当前统计的子串 
17     int str_len; //用于记录输入的要统计的字符串的长度 
18     struct sub_str substr[1830]; //substr[1830]:用于记录各个子串的参数,最多有1+2+3+···+60个子串 
19     struct sub_str substr_temp; //substr_temp:用于对substr[1830]中的子串进行排序时交换顺序的临时中间结构体变量 
20     int sstr_num=0; //用于统计存入substr[1830]中的实际子串数量 
21     int max_times; //用于记录子串出现的最大次数 
22     
23     //输入 
24     scanf("%d",&l); //输入统计的子串的最小长度 
25     getchar(); //除去输入时的回车键 
26     gets(str); //输入要统计的字符串 
27     
28     str_len=strlen(str); //得到输入的要统计的字符串的长度 
29 
30     //初始临时动态子串长度为最大长度,遍历要统计的字符串中满足长度的子串 
31     for(l_temp=str_len;l_temp>=l;l_temp--) 
32     {
33         for(i=0;i<str_len-l_temp;i++) //长度为l_temp的子串在长度为str_len的字符串中有str_len-l_temp个
34         {
35             for(j=i,k=0;j<i+l_temp;j++,k++) //得到当前要统计的子串
36                 sstr_temp[k]=str[j];
37 
38             for(k=0;k<sstr_num;k++) //查询 substr[1830] 中是否存在当前要统计的子串 
39                 if(strcmp(sstr_temp,substr[k].sstr)==0) //有,则使该子串的出现次数加1 
40                 {
41                     substr[k].times++;
42                     break;
43                 }
44 
45             if(k==sstr_num) //没有,则在 substr[1830] 中新增该子串,并初始化各个参数 
46             {
47                 strcpy(substr[sstr_num].sstr,sstr_temp);
48                 substr[sstr_num].len=l_temp;
49                 substr[sstr_num].times=1;
50                 sstr_num++; // substr[1830] 中实际的子串数量加1 
51             }
52             
53             memset(sstr_temp,0,sizeof(sstr_temp)); //清 0 sstr_temp[61],继续遍历该长度的子串 
54         }
55     }
56     
57     //采用冒泡排序法对 substr[1830] 中的子串根据出现次数进行排序 
58     for(i=0;i<sstr_num-1;i++) 
59     {
60         for(j=i;j<sstr_num;j++)
61         {
62             if(substr[j].times>substr[i].times)
63             {
64                 for(k=0;k<61;k++)
65                     substr_temp.sstr[k]=substr[i].sstr[k];
66                 substr_temp.len=substr[i].len;
67                 substr_temp.times=substr[i].times;
68 
69                 for(k=0;k<61;k++)
70                     substr[i].sstr[k]=substr[j].sstr[k];
71                 substr[i].len=substr[j].len;
72                 substr[i].times=substr[j].times;
73                 
74                 for(k=0;k<61;k++)
75                     substr[j].sstr[k]=substr_temp.sstr[k];
76                 substr[j].len=substr_temp.len;
77                 substr[j].times=substr_temp.times;
78             }
79         }
80     }
81     
82     //输出 
83     puts(substr[0].sstr);
84     
85     return 0;
86 }

转载于:https://www.cnblogs.com/LeoFeng/p/4340155.html

在 Java 中,统计字符串中最长子串可以根据不同的条件和需求采用不同的方法,以下为几种常见的情况及实现: ### 至少有 K 个重复字符的最长子串 可使用递归分治的方法,统计每个字母出现的次数,排除频次小于 k 的字符,再递归处理剩余子串。 ```java class Solution { public int longestSubstring(String s, int k) { int len = s.length(); if (len == 0 || k > len) { return 0; } if (k < 2) { return len; } return count(s.toCharArray(), k, 0, len - 1); } private static int count(char[] chars, int k, int left, int right) { if (right - left + 1 < k) return 0; int[] times = new int[26]; // 26个字母 for (int i = left; i <= right; ++i) { times[chars[i] - 'a']++; // 统计每个字母出现的次数,字符出现频次小于k,则不可能出现在结果子串中 } // 分别排除,然后挪动两个指针 while (right - left + 1 >= k && times[chars[left] - 'a'] < k) { ++left; } while (right - left + 1 >= k && times[chars[right] - 'a'] < k) { --right; } if (right - left + 1 < k) { // 排除到剩余的字符串小于k,则直接return return 0; } // 得到临时子串,再递归处理 for (int i = left; i <= right; ++i) { // 如果第i个不符合要求,切分成左右两段分别递归求得 if (times[chars[i] - 'a'] < k) { return Math.max(count(chars, k, left, i - 1), count(chars, k, i + 1, right)); } } return right - left + 1; } } ``` 使用示例: ```java public class Main { public static void main(String[] args) { Solution solution = new Solution(); String s = "ababbc"; int k = 2; System.out.println(solution.longestSubstring(s, k)); } } ``` ### 无重复字符的最长子串 可使用滑动窗口的思想,定义两个指针 `start` 和 `end`,利用 `HashSet` 存放符合条件的子串,遍历字符串并动态调整窗口。 ```java import java.util.HashSet; public class LongestSubstringWithoutRepeatingCharacters { public int lengthOfLongestSubstring(String s) { int start = 0; int end = 0; int maxLength = 0; HashSet<Character> set = new HashSet<>(); while (end < s.length()) { if (!set.contains(s.charAt(end))) { set.add(s.charAt(end)); end++; maxLength = Math.max(maxLength, set.size()); } else { set.remove(s.charAt(start)); start++; } } return maxLength; } public static void main(String[] args) { LongestSubstringWithoutRepeatingCharacters solution = new LongestSubstringWithoutRepeatingCharacters(); String s = "abcabcbb"; System.out.println(solution.lengthOfLongestSubstring(s)); } } ``` ### 长度大于等于 L 且出现次数最多的子串 可以枚举所有可能的子串,统计其出现次数,找出符合条件的子串。 ```java import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class SubstringStatistics { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int L = scanner.nextInt(); scanner.nextLine(); String S = scanner.nextLine(); String result = findMaxSubstring(S, L); System.out.println(result); } public static String findMaxSubstring(String S, int L) { Map<String, Integer> substringCount = new HashMap<>(); int n = S.length(); for (int i = 0; i < n; i++) { for (int j = i + L; j <= n; j++) { String sub = S.substring(i, j); substringCount.put(sub, substringCount.getOrDefault(sub, 0) + 1); } } String maxSubstring = ""; int maxCount = 0; for (Map.Entry<String, Integer> entry : substringCount.entrySet()) { String sub = entry.getKey(); int count = entry.getValue(); if (count > maxCount || (count == maxCount && sub.length() > maxSubstring.length()) || (count == maxCount && sub.length() == maxSubstring.length() && S.indexOf(sub) < S.indexOf(maxSubstring))) { maxCount = count; maxSubstring = sub; } } return maxSubstring; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值