子串计算

题目描述:

给出一个01字符串(长度不超过100),求其每一个子串出现的次数。

输入:

输入包含多行,每行一个字符串。

输出:

对每个字符串,输出它所有出现次数在1次以上的子串和这个子串出现的次数,输出按字典序排序。

样例输入:
10101
样例输出:
0 2
01 2
1 3
10 2
101 2
来源:
2010年北京大学计算机研究生机试真题


#include<iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <assert.h>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
 
bool isSubStr( const char * lhs, const char * rhs)
{
     if ( strlen (lhs)> strlen (rhs))
         return false ;
     for ( int i=0; i< strlen (lhs); i++)
         if (lhs[i] != rhs[i])
             return false ;
     return true ;
}
 
bool cmp( char *pa, char *pb)
{
     return strcmp (pa,pb)<0;
}
string subStr( const char *src, int num)
{
     assert ( strlen (src)>=num);
     string str;
     str.resize(num);
     for ( int i=0; i<num; i++)
         str[i]=src[i];
     return str;
}
void ComputeSubStrInfo( const char * src)
{
     int size = strlen (src);
     char ** pStr = new char *[size];
     for ( int i=0; i<size; i++)
         pStr[i]= const_cast < char *>(src+i);
 
     sort(pStr,pStr+size,cmp);
     map<string, int > subStrMap;
     for ( int i=0; i<size-1; i++)
     {
         map<string, int >::iterator it;
         int len=1;
         while ( strlen (pStr[i])>=len && strlen (pStr[i+1])>=len && subStr(pStr[i],len) == subStr(pStr[i+1],len))
         {
             it = subStrMap.find(subStr(pStr[i],len));
             if (it!=subStrMap.end())
                 it->second++;
             else
                 subStrMap.insert(make_pair(subStr(pStr[i],len),2));
 
             //subStrMap[subStr([i],len)]+=1;
             len++;
         }
 
     }
     for (map<string, int >::iterator it = subStrMap.begin(); it!=subStrMap.end(); it++)
         cout<<it->first<< " " <<it->second<<endl;
}
 
 
int main()
{
     //freopen("in.txt","r",stdin);
     string str;
     while (cin>>str)
     {
         ComputeSubStrInfo(str.c_str());
         //cout<<endl;
     }
     return 0;
}
/**************************************************************
     Problem: 1149
     User: xjbscut
     Language: C++
     Result: Accepted
     Time:20 ms
     Memory:1520 kb
****************************************************************/

使用前缀方法很不方便,实现起来苦难许多
还不如直接的方法
#include <cstdio>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
struct Sc {
 
     string s;
 
     int cnt;
 
     Sc(){};
 
     Sc(string ss , int icnt):s(ss),cnt(icnt){};
 
};
 
int cmp ( const Sc& a, const Sc& b){
 
     return a.s<b.s;
 
}
 
// 在字符串s中找字符串sub,结果存入v
 
void find (string s, string sub,vector<Sc>&v){
 
     int cur=0,cnt = 0;
 
     while (1){
 
         int next = s.find(sub,cur);
 
         if (next !=string::npos){
 
             cnt++ ;
 
             cur= next+1;
 
         }
 
         else break ;
 
     }
 
     if (cnt>1) v.push_back(Sc(sub,cnt));
 
}
 
int main ()
{
     //freopen("in.txt","r",stdin);
     string s;
     while (cin >> s)
     {
 
         vector<Sc>strs;
 
         int len = s.length();
 
         int i,j,k;
 
         for (i=0;i<len;i++)
         {
 
             for (j=1;j<=len-i;j++)
             {
 
                 string cur = s.substr(i,j);  // 注意substr的参数:开始位置和长度。
 
                 find(s,cur,strs);
 
             }
 
         }
 
         sort(strs.begin(),strs.end(),cmp);
 
 
         for (k=0;k<strs.size();k+=strs[k].cnt)
         {
 
             cout<< strs[k].s << " " << strs[k].cnt << endl;
 
         }
 
     }
 
     return 0;
}
/**************************************************************
     Problem: 1149
     User: xjbscut
     Language: C++
     Result: Accepted
     Time:20 ms
     Memory:1516 kb
****************************************************************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值