4 条题解

  • 2
    @ 2024-12-14 17:46:41

    感谢楼上题解,不过我认为可以不用转为int再放到数组里面,可以直接减去字符a后变为0-25然后再计算频率会更清楚一点,然后就是这个编辑器是markdown格式的,可以加代码块,不加代码块直接发出来会看的很头疼。总结:感谢楼上题解[花]

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int T;
        cin>>T;
        int Q;
        string s;
        for(int i=1; i<=T; i++)
        {
            cin>>s;
    //		s是要匹配的字符串
            cin>>Q;
            string zi;
            int len2 = s.size();
            for(int j=1; j<=Q; j++)
            {
                cin>>zi;
                int len = zi.size();
                int std[27]={0};
                for(int k=0; k<len; k++)
                {
                    std[zi[k] - 'a']++;
                }
                int ans=0;
                for(int k=0; k<len2 - len + 1; k++)
                {
                    int jd[27]={0};
                    string judge=s.substr(k,len);
                    for(int h=0; h<len; h++)
                    {
                        jd[judge[h] - 'a']++;
                    }
                    int flag = 1;
                    for (int h = 0; h <= 26; h ++)
                    {
                        if (jd[h] != std[h])
                        {
                            flag = 0;
                        }
                    }
                    if (flag == 1) ans++;
                }
                cout<<ans<<endl;
            }
        }
        return 0;
    }
    
    • 1
      @ 2025-10-11 10:57:15

      解题思路

      1. 先对字符串进行预处理,获取每中长度的串

      2. 由于abc,cba..这种属于同一种串,那么分开处理将会十分浪费时间,使用sort进行排序,可将同一类型的串变成同一个串。随后进行计数即可

      3. 子串进行匹配前,也使用sort进行排序,便可以从map中查询到对应串的出现次数

      完整代码如下:

      #include <iostream>
      #include <map>
      #include <vector>
      #include <cstring>
      #include <algorithm>
      using namespace std;
      
      int main() 
      {
          int T;
          cin >> T;
          for (int i = 0; i < T; i++) 
      	{
              string main_sec;
              cin >> main_sec;
              int n = main_sec.size();
              int Q;
              cin >> Q;
              
              // 预处理:预先计算所有可能长度的字符频率
              // 使用一个映射,键为长度,值为另一个映射(键为排序后的子串,值为出现次数)
              map<int, map<string, int>> precomputed;
              
              // 只处理长度1到10的子串(根据题目提示,子串长度<=10)
              for (int len = 1; len <= 10; len++) 
      		{
                  for (int start = 0; start <= n - len; start++) 
      			{
                      string substr = main_sec.substr(start, len);
                      // 对子串排序,作为频率的标识
                      sort(substr.begin(), substr.end());
                      precomputed[len][substr]++;
                  }
              }
              
              for (int j = 0; j < Q; j++) 
      		{
                  string str;
                  cin >> str;
                  int len = str.size();
                  
                  // 如果长度超过10或主串长度,直接返回0
                  if (len > 10 || len > n) 
      			{
                      cout << 0 << endl;
                      continue;
                  }
                  
                  // 对查询子串排序,作为频率标识
                  sort(str.begin(), str.end());
      			
                  // 直接从预处理结果中获取计数
                  if (precomputed.find(len) != precomputed.end() && 
                      precomputed[len].find(str) != precomputed[len].end()) 
      			{
                      cout << precomputed[len][str] << endl;
                  } 
      			else 
      			{
                      cout << 0 << endl;
                  }
              }
          }
          return 0;
      }
      
      • 0
        @ 2025-9-28 11:14:55

        我之前没有学过字符串的相关知识,我是一边做题一边看书学出来。所以我觉得我的题解应该可以给像我一样的新手看,给予参考或者启发。 我的思路是,被匹配的字符串的每个字符都去匹配要匹配的字符串的字符,如果匹配到了,就标记被占用。核心思路是这个,然后配上辅助减少计算时间的方法就行了。应该会有更快的算法,但我想了很久想不出来。 下面的代码要用到的没教过的函数(目前)是strlen() (这个函数是我从课本扒出来的,需要<string.h>头文件),这个函数是求字符串长度的。然后其它的都是些课上讲的东西组合起来和我发现的一些小点。

        #include <stdio.h>
        #include <string.h>
        
        int get_times(char main_str[], char sub_str[]) {
        	int main_length = strlen(main_str);
        	int sub_length = strlen(sub_str);
        	int times = 0;
        	// 遍历主串
        	int start = 0;
        	int end = 0;
        	for (int i = 0; i < main_length; i ++) {
        		int match_array[15] = {0};
        		end = i;
        		
        		if ((end - start) == sub_length) {
        			start += 1;
        		}
        		
        		int match_times = 0;
        		for (int j = start; j <= end; j ++) {
        			for (int k = 0; k < sub_length; k ++) {
        				if (main_str[j] == sub_str[k] && match_array[k] == 0) {
        					match_array[k] = 1;
        					match_times += 1;
        					break;
        				}
        			}
        		}
        		
        		if (match_times == sub_length) {
        			times += 1;
        		}
        	}
        	
        	return times;
        }
        
        
        int main(void) {
        	int t;
        	int qs = 0;
        	scanf("%d", &t);
        	
        	int times_array[20005] = {0};
        	int counter = -1;
        	for (int i = 0; i < t; i ++) {
        		char main_str[1005] = {0};
        		scanf("%s", main_str);
        		
        		int q;
        		scanf("%d", &q);
        		qs += q;
        		
        		for (int j = 0; j < q; j ++) {
        			counter += 1;
        			char sub_str[15] = {0};
        			scanf("%s", sub_str);
        			times_array[counter] = get_times(main_str, sub_str);
        		}
        	}
        	
        	
        	for (int i = 0; i < qs; i ++) {
        		printf("%d\n", times_array[i]);
        	}
        	
        	return 0;
        }
        
        • 0
          @ 2024-11-9 12:46:46

          #include<bits/stdc++.h> using namespace std;

          int main() { int T;

          cin>>T;
          
          int Q;
          
          string s;
          
          for(int i=1; i<=T; i++)
          {
          	cin>>s;
          	
          	cin>>Q;
          	
          	string zi;
          	
          	
          	
          	for(int j=1; j<=Q; j++)
          	{
          		cin>>zi;
          		
          		int std[1024]={0}; //子串的标准 
          		
          		for(int k=0; k<zi.size(); k++)
          		{
          			std[(int)zi[k]]++;
          		}
          		
          		int ans=0; //一个Q对应一个ans 
          		
          		for(int k=0; k<s.size()-zi.size()+1; k++)
          		{
          			int jd[1024]={0};
          			
          			string judge=s.substr(k,zi.size());
          

          // cout<<"查找的子串是:"<<judge<<endl; // cout<<"子串的长度是:"<<zi.size()<<endl;

          			for(int h=0; h<zi.size(); h++)
          			{
          				jd[(int)judge[h]]++;
          			}
          			
          			int flag=1;
          			
          			for(int h=0; h<zi.size(); h++)
          			{
          

          // cout<<zi[h]<<':'<<"std:"<<std[(int)zi[h]]<<" VS "<<"jd:"<<jd[(int)zi[h]]<<endl;

          				if(std[(int)zi[h]]!=jd[(int)zi[h]])
          					flag=0;
          

          // cout<<"flag:"<<flag<<endl; }

          			if(flag==1)
          				ans++;
          		} 
          		
          		cout<<ans<<endl;
          		
          	}
          }
          
          return 0;
          

          }

          感觉我写的太丑陋了 抛砖引玉一下吧

          • 1

          信息

          ID
          196
          时间
          4000ms
          内存
          256MiB
          难度
          9
          标签
          递交数
          827
          已通过
          91
          上传者