寻找包含给定字符集合的最小子串

#include <iostream>
#include <string>
using namespace std;

string min_str(string str1,string str2)
{
    if(str1.size() == str2.size() )
    {
        return min(str1,str2);
    }
    return str1.size() > str2.size() ? str2:str1;
}

bool is_subset(bool str1[26],bool str2[26])
{
    for(int i = 0; i < 26; ++i)
    {
        if(str2[i] && !str1[i])
        {
            return false;
        }
    }
    return true;
}

string Find_str(string S, string D) // 字符串S,字符集合D
{
    string ret;
    int Sset[26], Dset[26]; // int数组模拟集合,还有引用计数
    int Ds; // 字符集合D在字符串S中出现的不同个数
    fill(Dset,Dset+26,0);
    fill(Sset,Sset+26,0);
    Ds = 0;
    for (int i = 0; i < D.length(); i ++)
        Dset[D[i]-'a'] = 1; // 字符集合D初始化
    int l = 0;
    for (int r = 0; r < S.length(); r ++)
    {
        if (Dset[S[r]-'a'] == 1 && Sset[S[r]-'a'] == 0)
            Ds ++; // S中出现新的D集合中字符
        Sset[S[r]-'a'] ++;
        for (; l <= r; l ++)
        {
            if (Dset[S[l]-'a'] == 1 && Sset[S[l]-'a'] == 1)
            {
                if (Ds == D.length())   // D集合中字符全部出现
                {
                    ret = ret.empty() ? S.substr(l, r-l+1) : min_str(ret, S.substr(l, r-l+1));
                    Sset[S[l++]-'a'] --; // left右移
                    Ds --;
                }
                break;
            }
            Sset[S[l]-'a'] --;
        }
    }
    return ret;
}

int main()
{
    string str1,str2;
    str1 = "ssssssadf";
    str2 = "af";
    cout<<Find_str(str1,str2)<<endl;
    return 0;
}

上面是优化后的,下面列出未优化的。

#include <iostream>
#include <string>
using namespace std;

string min_str(string str1,string str2){
    if(str1.size() == str2.size() ){
        return min(str1,str2);
    }
    return str1.size() > str2.size() ? str2:str1;
}

bool is_subset(bool str1[26],bool str2[26]){
    for(int i = 0; i < 26; ++i){
        if(str2[i] && !str1[i]){
            return false;
        }
    }
    return true;
}

string Find_str(string S,string T){
    bool str1[26];
    bool str2[26];
    string ans;
    cout<<ans.size()<<endl;
    fill(str2,str2+26,0);
    for(int i = 0 ; i < T.size(); ++i){
        str2[T[i] - 'a'] = true;
    }
    for(int len = T.size() ; len <= S.size(); len++){
        for(int i = 0; i <= S.size() - len; i++){
            fill(str1,str1+26,0);
            for(int k = i; k < i+len;k++){
                str1[S[k] - 'a'] = true;
            }
            if(is_subset(str1,str2)){
               ans = (ans.empty()? S.substr(i,len):min_str(ans,S.substr(i,len)));
            }
        }
    }
    return ans;
}

int main(){
    string str1,str2;
    str1 = "ssssssadf";
    str2 = "sf";
    cout<<Find_str(str1,str2)<<endl;
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值