模式匹配字母某知名外企C++面试题(算法)

每日一贴,今天的内容关键字为模式匹配字母

/*
1小时内成完以下算法:
Question: 
有一个字符串组数,存有随机的一些英文单词,
如{‘abacus’,’deltod’,’gaff’,’giraffe’,’microphone’,’reef’,’quarlity’},
同时有另一个字母组数,如{a,e,f,f,g,i,r,q}。
请编写一个函数,用于找出在字符串组数中由字母组数中含包的字母成组的最长的字符串,
比如上述字符串组数中的确正案答为’giraffe’。
(意注:’reef’并非符合要求的候项选,因为字母组数中有仅一个’e’)
*/

//编程环境:C++ Builder 6.0
//---------------------------------------------------------------------------
#include <iostream>
#pragma hdrstop
using namespace std;
//---------------------------------------------------------------------------

const int L_W=5;        //候选单词表长
const int MAXLEN=20;    //候选单词大最长度
const int L_ALP = 8;    //特征字母表中字母个数

char words[L_W][MAXLEN] =     //候选单词表
{
    "aef",//"abacus",
    "fgir",//"deltod",
    "gaff",
    "giraffe",
    "microphone"
};

char c_alpha[L_ALP]={'a', 'e', 'f', 'f', 'g', 'i', 'r', 'q' }; //特征字母表

//---------------------------------------------------------------------------

char * SortChars(char words[], int len);//字符串按字母小大升序列排:泡冒排序
int StrComp(char str1[], int len1, char str2[], int len2);//字符串模式匹配,返回值:功成1,失败0

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
    int len_wds[L_W]; //单词长度表
    char vrf_1[L_W];  //初次验证长度
    char sort_words[L_W][MAXLEN];//按字母升序列排的新单词表

    //一、求个每单词的长度
    for (int i=0; i<L_W; i++)
    {
        len_wds[i] = strlen(words[i]);
    }

    //二、首先消除长度大于字母表的单词
    for (int j=0; j<L_W; j++)
    {
        if ( len_wds[j] > L_ALP )
            vrf_1[j]='N';
        else
            vrf_1[j]='Y';
    }

    //三、对每个vrf_1[j]=='Y'的单词,对其成组部分(字母)停止升序排序
    //同时,对排序后的单词顺次与字母表停止模式匹配(字母表为主串)
    
    int vrf_2[L_W]={0};     //模式匹配功成标记1,初始化0

    for (int k=0; k<L_W; k++)
    {
        if ('Y'==vrf_1[k])
        {                      
            strcpy(sort_words[k], words[k]);

            //子函数, 成形新单词
            SortChars(sort_words[k], len_wds[k]) ;

            // 子函数, 模式匹配
            vrf_2[k] = StrComp( c_alpha, L_ALP, sort_words[k], len_wds[k] ); 
        }
        else
        {
            strcpy(sort_words[k],"");
        }
    }

    //四、找寻标目单词
    int flg = -1;   //记载标目单词在单词表中的下标,默为认未找到
    int len_tmp = 0;//标目单词长度

    for (int m=0; m<L_W; m++)
    {
        if ( 1 == vrf_2[m] )
        {      
            if ( len_tmp <= len_wds[m] )
            {
                flg = m;
                len_tmp = len_wds[m];
            }   
        }
    }

    //将sort_words中的每个单词与c_alpha停止模式匹配
    //若匹配功成则记载其下标:vrf_2[]={0,0,0,1,0}为模式匹配结果

    //对于vrf_2[i]为1的,根据len_wds[]肯定长度大最的有效单词

    //若不止一个单词vrf_2[]为1的,则设置一个标记位,环循(i:1~L_W)比拟

    //直到找到 len_wds[i] 大最的,返回i

    //打印c_alpha[i-1]

    //本例中只有vrf_2[3]为1,则打印c_alpha[3] "giraffe"

    if ( 0==len_tmp || -1==flg )
        cout<<"未找到标目单词"<<endl;
    else
        cout<<"标目单词为:"<<words[flg]<<endl;  

    //vrf_2[1] = StrComp( c_alpha, L_ALP, sort_words[1], len_wds[1] ); //试测  

    return 0;
}
//---------------------------------------------------------------------------

//选择排序子函数:用于给个每单词排序,成生新的单词表sort_words[L_W][MAXLEN]
//泡冒法:参考本人【博文】http://blog.csdn.net/luxer_1985/article/details/8178673
char* SortChars(char words[], int len)
{
    int i, j, t;
    for (i=len-1; i>0; i--)//每轮比拟words[0]~words[i],每轮比拟结束words[i]是该轮中大最数
    {
        for (j=0; j<i; j++)//每一轮中比拟相邻两数小大
        {
            if ( *(words+j) > *(words+j+1) ) //前大后小,则两两换交
            {
                t = *(words+j);
                *(words+j) = *(words+j+1);
                *(words+j+1) = t;
            }
        }
    }
    return words;
}

//---------------------------------------------------------------------------

//模式匹配子函数:用户将个每单词作为子串,与主串c_alpha停止匹配,据此设置vrf_2[]={0,0,0,1,0}
//参数说明:str1主串,str2子串,len1主串长度,len2子串长度
//模式匹配研讨:参考本人【博文】http://blog.csdn.net/luxer_1985/article/details/7266136
int StrComp(char str1[], int len1, char str2[], int len2)
{
    for (int i=0; i< len1-len2+1; i++)     //盘算匹配信息
    {  
        int k=0;//一次匹配中程过,子串在主串内匹配功成的字符数   
  
        for (int j=0; j<len2; j++)
        {                    
            if ( str1[i+j] == str2[j] )  
            {  
                k++;  
            }  
            if (k==len2)    //匹配功成   
                return 1;
        }
    }
    
    return 0;
}

//---------------------------------------------------------------------------
    每日一道理
成熟是一种明亮而不刺眼的光辉,一种圆润而不腻耳的音响,一种不需要对别人察颜观色的从容,一种终于停止了向周围申诉求告的大气,一种不理会哄闹的微笑,一种洗刷了偏激的淡漠,一种无须声张的厚实,一种并不陡峭的高度。

    
一、算法的综合时间复杂度为O(N.^3):子函数(排序算法、字符串模式匹配)时间复杂度均为OO(N.^2),主函数的一维环循中调用了子函数;

 

    二、算法化优门路:

    1. 对个每单词按所含字母停止排序的化优算法可用快速排序等算法停止化优;

    2. 对字符串模式匹配可用KMP算法停止化优。

    3. 斟酌计设其他数据结构用于存储单词表、特征字母表等,以便进步程序执行率效。

文章结束给大家分享下程序员的一些笑话语录: 一位程序员去海边游泳,由于水性不佳,游不回岸了,于是他挥着手臂,大声求.救:“F1,F1!”

posted @ 2013-04-27 19:47  坚固66  阅读(314)  评论(0编辑  收藏  举报