字符串的包含

如果两个字符串中的字符一样,出现的次数也一样,只是出现的顺序不一样,则可以认为这两个字符串是兄弟字符串。例如,“bad”和“abd”即为兄弟字符串。
在书中提到的一个检验是否包含的算法是位运算算法,可将长字符串用位运算的方法计算出一个“签名”(58位二进制表示,‘A’ASCII值为65,’Z’ASCII值为122,两个字符差值属于[0,58]),在逐一将端字符串中的字符放入查找。方法十分巧妙。
但是对于本问题涉及到每个元素出现的个数问题,无法用上述算法实现,例如“bbc”包含于“abc”,但是二者并非是兄弟字符串。可以将原来的58位二进制“签名”改为用长度为58的数组表示,两个字符串出现对应的字符则在对应编号的位置++或–。

/*
字符串的包含
如果两个字符串的字符一样,出现次数也一样,则认为这两个字符串是兄弟字符串。
例如,“bad”和“abd”即为兄弟字符串。现提供一个字符串,在字典中快速找到他的一个兄弟字符串
*/
#include <iostream>
using namespace std;

void FindBrother(char *s1, char *s2);
bool CharBrother(char* s1, char* s2, int nStart, int nEnd);

int main()
{

    char sInput[] = "abc" ;
    char sFind[] = "abcsdasdfasgagafgafcbagasfbcagSDfaaea";
    FindBrother(sInput,sFind);
    cin.get();
    return 0;
}

void FindBrother(char *s1,char *s2)
{
    /*
    检测兄弟字符串个数
    输入参数:*s1       ---待检测字符串
            *s2       ---待检测字符串
    输出参数:
    */
    int start = 0;
    int num=0;
    while (s2[start + strlen(s1) - 1] != '\0')
    {
        if (CharBrother(s1,s2,start,start+strlen(s1)-1))
        {
            num++;
        }
        start++;

    }
    cout << "The number of CharBrother is " << num << endl;

}

bool CharBrother(char* s1,char* s2,int nStart,int nEnd)
{
    /*
    检测两个字符串是否是兄弟字符串
    输入参数:*s1       ---待检测字符串
            *s2       ---待检测字符串
            nStart    ---起始位置
            nEnd      ---截止位置
    输出参数:false     ---不是兄弟字符串
            true      ---是兄弟字符串
    */
    int hash[58] = {0};              // (int) 'z'-'A' =57
    if (nStart>nEnd)
    {

        return false;
    }
    else
    {
        for (int i = 0; i < nEnd-nStart+1; i++)
        {
            ++hash[s1[i] - 'A'];
            --hash[s2[nStart+i] - 'A'];
        }
        for (int i = 0; i < 2*26; i++)
        {
            if (hash[i]!=0)
            {
                return false;
            }
        }

    }
    return true;
}

运行结果
这里写图片描述

上述方法都借鉴了hash table的思路,能比较巧妙的解决问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值