编程珠玑-第15章

本文探讨了字符串处理中的两种算法:寻找最长重复子串和生成随机文本。通过具体实例展示了算法的应用,包括在《史记》中查找最长重复子串,并基于文本生成具有一定连贯性的随机文本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章讨论了一些字符串处理的算法

1,最长重复子串

   使用了后缀字符串的技巧

#define  MAX_TEXT_LEN 2000000
#define  FORWARD_LEN 2

int getMaxCmp(const wchar_t* p1,const wchar_t* p2)
{
    int n=0;
    while(p1[n]==p2[n])n++;
    return n;
}
wstring maxCmpText( const char* file )
{
    wchar_t* text=new wchar_t[MAX_TEXT_LEN];
    wchar_t** textp=new wchar_t*[MAX_TEXT_LEN];
    for (int i=0;i<MAX_TEXT_LEN;i++)
    {
        textp[i]=text+i;
    }
    //
    memset(text,0,MAX_TEXT_LEN*sizeof(wchar_t));
    setlocale(LC_ALL,"chs");
    FILE* f=fopen(file,"r");

    wchar_t *curPos=text;
    int len=0;
    while(fgetws(curPos,1000,f))
    {
        len+=wcslen(curPos);
        curPos=text+len;
    }
    //wprintf(L"%s",text);
    printf("长度:%d\n",len);
    std::sort(textp,textp+len,[](wchar_t* p1,wchar_t* p2){
        return wcscmp(p1,p2)<0;
    });
    int nMaxCmp=0;
    wchar_t* pMax=text;
    for (int i=0;i<len-1;i++)
    {
        int tmp=getMaxCmp(textp[i],textp[i+1]);
        if (tmp>nMaxCmp)
        {
            pMax=textp[i];
            nMaxCmp=tmp;
        }
    }
    wprintf(L"%d\n",nMaxCmp);
    wstring st(pMax,pMax+nMaxCmp);
    wprintf(L"%s\n",st.c_str());
    return L"";
}

让我们来检查一下史记中的最长子串是什么?结果如下:

果不其然,由于史记里面的<孝武本纪>基本上是摘抄<封禅书>的内容,因此最长重复子串就在<封禅书>里面

但是为什么只有171个字符呢?应该更大才对,我看了一下史记,在开始处分别是"祀其名山川"和"礼其名山川",结尾处是"则祠泰一"和"则祠太一",为什么是这样呢?既然是摘抄的,应该是一样的啊

话说回来,我很想看看原本的<孝武本纪>,看看司马迁是如何描写汉武帝的,太史公肯定有其独到的观点

2,随机文本

 书上使用单词为单位生成随机文本,我生成汉字,直接以每个字输出,算法要简单一些

 这里的重点是二分搜索和随机字符的算法,使用了前几章的习题里面的技巧:二分搜索如何搜索满足条件的第一个元素?如何在不知道元素总数的情况下随机选择一个?

   

#define  MAX_TEXT_LEN 2000000
#define  FORWARD_LEN 2

int getMaxCmp(const wchar_t* p1,const wchar_t* p2)
{
    int n=0;
    while(p1[n]==p2[n])n++;
    return n;
}
int wordCmp(const wchar_t* p1,const wchar_t* p2)
{
    for (int i=0;i<FORWARD_LEN-1;i++)
    {
        if(p1[i]!=p2[i])return p1[i]-p2[i];
    }
    return 0;
}
wstring randomText( const char* file )
{
    srand(clock());
    wchar_t* text=new wchar_t[MAX_TEXT_LEN];
    wchar_t** textp=new wchar_t*[MAX_TEXT_LEN];
    for (int i=0;i<MAX_TEXT_LEN;i++)
    {
        textp[i]=text+i;
    }
    //
    memset(text,0,MAX_TEXT_LEN*sizeof(wchar_t));
    setlocale(LC_ALL,"chs");
    FILE* f=fopen(file,"r");

    wchar_t *curPos=text;
    int len=0;
    while(fgetws(curPos,1000,f))
    {
        len+=wcslen(curPos);
        curPos=text+len;
    }
    printf("长度:%d\n",len);
    std::sort(textp,textp+len,[](wchar_t* p1,wchar_t* p2){
        return wcscmp(p1,p2)<0;
    });
    int nMaxCmp=0;
    wchar_t* pMax=text;
    for (int i=0;i<len-FOWWARD+1;i++)
    {
        int tmp=getMaxCmp(textp[i],textp[i+1]);
        if (tmp>nMaxCmp)
        {
            pMax=textp[i];
            nMaxCmp=tmp;
        }
    }
    wprintf(L"%d\n",nMaxCmp);
    wstring st(pMax,pMax+nMaxCmp);
    int maxLength=2000;
    wchar_t* randStr=new wchar_t[maxLength+1];
    randStr[maxLength]=L'\0';
    randStr[0]=L'';
    randStr[1]=L'';
     
    for(int i=0;i<maxLength-FORWARD_LEN+1;i++)
    {
        int l=0;
        int r=len-1;
        int re=-1;//搜索结果i
        while(1)
        {
            if(l==r)
            {
                if(wordCmp(randStr+i,textp[l])==0)re=l;
                break;
            }             
            int m=(l+r)/2;
            if(wordCmp(randStr+i,textp[m])<=0)r=m;
            else l=m+1;
        }
        wchar_t tmp=L' ';
        int j=1;
        while(re!=-1&&re<len&&wordCmp(textp[re],randStr+i)==0)
        {
            if(rand()%j==0&&textp[re][FORWARD_LEN-1]!=L' '&&textp[re][FORWARD_LEN-1]!=L'\n')tmp=textp[re][FORWARD_LEN-1];
            re++;
            j++;
        }
        if(tmp==L'\0')tmp=L' ';
        randStr[i+FORWARD_LEN-1]=tmp;         
    }
    wprintf(L"%s\n",randStr);
    return L"";
}

由于有太多空格和换行,我把很多空格和换行干掉了,生成的文本:

始五年,淮阴侯,左右既行阴事。而李夫人田荣如此始汤方;使安曰“我”少季札书相楚、
蔡之间行四年,夹持其後宫中,又 当见臣之。 燕、卫子曰:“赵王欲发兵尽也。秦来,
五色。反,而句戟百越王。舜。”臣,奸神可得全乎南阳,乃为太阿房君臣,功。数破灭之
宗庙,岂非真草美之意方仙神或朝,秦始。韩宣公十七年徙者务在人安邑,秦灭赵又可以为
长美女极人。风居下相攻。 灵王其次曰“道备燕饮,所置吏为沛,而能督亢竖子欣喜
。先据地?”市,带复予金作,而何如廷也。项王遂以为於兹兹益矣,是相国有作奸乃与宋
元年,颇用文德,杭,此时极亡之少傅其言也,以天五年,遂西伯阳人。”诸吕礼之,遇之
後去学者少与其子不享诸臣征巴蜀,海内其察礻必祸及八·伍子章章,无书 太守。陈,还
报劳者不胜 於边邑,问所以收下。”公子曰:“秦,高之,莫敢举有济北地。故国者年
伐吴东王信武王基者夫,破镜;离为王耳目不朝。简子将兵十年卒。 

把FORWARD_LEN改成3,保留换行符:

始皇自以为九卿尽会立,是必大矣,不疑。荀息。斡流而下报赵王以诸侯,食顷,齐桓,将
不能守也。
韩厥,厥称太子,子文王生曰:
平原君求救,其将欲移兵而去。弃女子长为陶天下服。
王者之无尽索之时,季文子奔莒,则蛮夷所侵暴乱,畏诛,死者不求何获!我真王嗣,
冠固何当?”曰:“为此药者乃‘刘’也。
汤征诸侯,昭公卒,子庄王曰:“始上数在困急之中。
太史公遭李陵既壮,杀
厉公於朝廷。
清明风居西北外国。

把FORWARD_LEN改成4:

始皇帝。其语在吕后语中。于丞相去,王乃反诛我。嗟乎,利诚乱之始也!夫秦王有连。其
居於秦,
莫如从亲以孤秦。大王命季历,明天人分际,通古今之义,则两失
之矣,
其势必不
来。至长安。
武帝立,以微眇之身,国治兵︹,可以备胡。数月而降,杀之。使弃疾为陈公,不随项
羽,故立为殷王,都朝歌。诸侯兵罢归,乃阴聚徒党及谋反者。
大馀三十二年,周致伯於秦孝公、楚悼王、越王,与城阳、琅邪负海之国
也。此
两人深相结,请案兵无攻。愿大王资馀兵,击楚,其意不厌。今秦之欲伐楚,败而亡王舟。
光惧,袭楚至邓。楚兵惧,自秦归。而楚太子商臣弑其父成王代立。帝廑崩,立沃
甲兄祖辛之子祖丁,是为缪侯,续绛侯後。十二年,彗星见

已经有点史记样子了,把FORWARD_LEN改成10的时候,由于没有这么长的重复子串,直接输出实际原文了,汗

 

 

 

   

转载于:https://www.cnblogs.com/mightofcode/archive/2012/11/26/2788403.html

内容概要:本文详细介绍了扫描单分子定位显微镜(scanSMLM)技术及其在三维超分辨体积成像中的应用。scanSMLM通过电调透镜(ETL)实现快速轴向扫描,结合4f检测系统将不同焦平面的荧光信号聚焦到固定成像面,从而实现快速、大视场的三维超分辨成像。文不仅涵盖了系统硬件的设计与实现,还提供了详细的软件代码实现,包括ETL控制、3D样本模拟、体积扫描、单分子定位、3D重建和分子聚类分析等功能。此外,文还比较了循环扫描与常规扫描模式,展示了前者在光漂白效应上的优势,并通过荧光珠校准、肌动蛋白丝、线粒体网络和流感A病毒血凝素(HA)蛋白聚类的三维成像实验,验证了系统的性能和应用潜力。最后,文深入探讨了HA蛋白聚类与病毒感染的关系,模拟了24小时内HA聚类的动态变化,提供了从分子到细胞尺度的多尺度分析能力。 适合人群:具备生物学、物理学或工程学背景,对超分辨显微成像技术感兴趣的科研人员,尤其是从事细胞生物学、病毒学或光学成像研究的科学家和技术人员。 使用场景及目标:①理解和掌握scanSMLM技术的工作原理及其在三维超分辨成像中的应用;②学习如何通过Python代码实现完整的scanSMLM系统,包括硬件控制、图像采集、3D重建和数据分析;③应用于单分子水平研究细胞内结构和动态过程,如病毒入侵机制、蛋白质聚类等。 其他说明:本文提供的代码不仅实现了scanSMLM系统的完整工作流程,还涵盖了多种超分辨成像技术的模拟和比较,如STED、GSDIM等。此外,文还强调了系统在硬件改动小、成像速度快等方面的优势,为研究人员提供了从理论到实践的全面指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值