由一道逻辑推理题衍生的对于实际问题求解的一般思路(续)

来源:互联网 发布:手机透视拍照软件 编辑:程序博客网 时间:2024/05/01 03:24

接上次的关于逻辑推理题的分析,这次我们需要对上次的思路做一个反思,同时整理出更优的方法出来,一方面,帮助我们能够快速地找到解决问题的思路,同时能够提供一个良好解决方案。还记得上次的分析当中,我们采用面向对象的方法做了一次简单的尝试,但是由于思路的不完整性或者说部分的方向偏差导致不得不中断而采用其他的面向过程的解决方案。现在我们已经有了一个可行的方案了,在这个前提下,我们再次尝试一下更加令人容易想到且容易理解的,采用面向对象的方法进行全方位的思考解题。将逻辑问题转变成计算机能够处理的数据,并得出我们所需要的结论。OK,先回顾一下上次关于面向对象的方法进行思考的过程。我们为什么会采取以房子为中心而不是以人为中心进行设计呢?!当时的原因是:由于条件中最难使用计算机语言表达的是关于关系的条件,而这些关系是与房子本身紧密相关的例如:左面、邻居、隔壁等等,这些关系都是与房子直接相关的,我们需要使用房间号来进行判定的。因此我们为了让这个难以表述的条件得到良好的表述,我们采用了以房子为中心的设计方案。但是在这个思考的过程中,却犯了一个错误:那就是没有完全搞清楚定了什么条件要推导或者说要验证什么的问题。结果在写验证过的时候出现了逻辑混乱的现象。现在让我们还原当时的过程,重新整理一下思路:我们一开始想到要用枚举来使得程序的可读性增强且容易我们编程的时候思路的清晰,这点是没有问题的,另外我们采用了面向对象的思考方法,将所有相关的属性作为一个类,并且对于比较“棘手”的判断设计了相应的方法,这点也是没有问题的,那么问题出在哪儿呢?换句话说,这个程序最后烂尾到哪个地方了呢?我们再看看烂尾的代码,明显地,我们可以发现我们的出发点有个地方出了问题,我们需要的是对不同情况的一个穷举,而不是对某个特定的情况进行挨个“组合”。也就是在循环的地方出了问题,导致了代码烂尾了,换句话说就是在对条件的使用上出现了思维混乱的问题,现在我们重新调整一下思路,现在已经知道,假设我们把房子定下来,弄了五个房子对象,这个时候我可以根据要求进行设置,但是不可避免地要碰到一个排列的问题。一方面我们想快速解决问题,另外一方面我们又想规避一下排列的问题,毕竟排列需要涉及到的操作也是相对毕竟繁琐的。这个时候我们单纯地去定房子意义已经不大了,那么我们能否这样来考虑呢,将房子这个类的使用进行一下改变,不一开始进行房子的制定,而是继续沿用之前我们的方法,不过这次不论是从程序的可读性上来说还是判断条件的转换来说相比上次都要方便了许多!部分代码如下所示:

//门牌号:   1           2           3           4           5//国籍:     挪威        德国        英国        瑞典        丹麦//颜色:     黄          蓝          红          绿          白//饮料:     啤酒        水          牛奶        咖啡        茶//香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall//宠物:     Fish        Horse       Cat         Dog         Birdenum HOUSECOLOR     //房子颜色{    Yellow  =  1,    Blue,    Red,    Green,    White};enum BEVERAGE       //饮料{    Beer    =  1,    Water,    Milk,    Coffee,    Tea};enum NATIONALITY    //国籍{    Norway  =   1,    Germany,    British,    Sweden,    Denmark};enum CIGARETTE      //香烟(品牌){    Dunhill =  1,    Prince,    Blends,    BlueMaster,    PallMall};enum PET            //宠物{    Fish    =  1,    Horse,    Cat,    Dog,    Bird};class House{public:    House( const int iHouseNum,           NATIONALITY eNation,            HOUSECOLOR eColor,           BEVERAGE eDrink,           CIGARETTE eCigar,            PET ePet )            : m_iHouseNum( iHouseNum ),              m_eColor( eColor ),              m_eCigar( eCigar ),              m_eDrink( eDrink ),              m_eNation( eNation ),              m_ePet( ePet )    {    }    ~House(){}public:    //Relationship    bool IsOnLeftSide( const House &objHouse )    {        return 1 == (m_iHouseNum - objHouse.m_iHouseNum);    }    bool IsOnRightSide( const House &objHouse )    {        return -1 == (m_iHouseNum - objHouse.m_iHouseNum);    }    bool IsNeighbour( const House &objHouse )    {        return 1 == abs(m_iHouseNum - objHouse.m_iHouseNum );    }public:    //Setter and Getter    //void SetCigar( const CIGARETTE eCigar ) { m_eCigar = eCigar; }    //void SetHouseColor( const HOUSECOLOR eColor ) { m_eColor = eColor; }    //void SetBeverage( const BEVERAGE eDrink ) { m_eDrink = eDrink; }    //void SetNationality(const NATIONALITY eNation ) { m_eNation = eNation; }    //void SetPet( const PET ePet ) { m_ePet = ePet; }    const CIGARETTE GetCigar( void ) const { return m_eCigar; }    const HOUSECOLOR GetHouseColor( void ) const { return m_eColor; }    const BEVERAGE GetBeverage( void ) const { return m_eDrink; }    const NATIONALITY GetNationality( void ) const { return m_eNation; }    const PET GetPet( void ) const { return m_ePet; }    const int GetHouseNum( void ) const { return m_iHouseNum; }private:    CIGARETTE       m_eCigar;    HOUSECOLOR      m_eColor;    BEVERAGE        m_eDrink;    NATIONALITY     m_eNation;    PET             m_ePet;    int             m_iHouseNum;};//门牌号:   1           2           3           4           5//映射号:  1           2           3           4           5//国籍:     挪威        德国        英国        瑞典        丹麦//颜色:     黄          蓝          红          绿          白//饮料:     啤酒        水          牛奶        咖啡        茶//香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall//宠物:     Fish        Horse       Cat         Dog         Birdchar *pstrsNationality[5] = { "挪威", "德国", "英国", "瑞典", "丹麦" };char *pstrsHouseColor[5]  = { "黄", "蓝", "红", "绿", "白" };char *pstrsBeverage[5]    = { "啤酒", "水", "牛奶", "咖啡", "茶" };char *pstrsCigarette[5]   = { "Dunhill", "Prince", "Blends", "BlueMaster", "PallMall" };char *pstrsPet[5]         = { "Fish", "Horse", "Cat", "Dog", "Bird" };int main( int argc, char *argv[] ){    size_t tNum_1 = 0;    size_t tNum_2 = 0;    size_t tNum_3 = 0;    size_t tNum_4 = 0;    size_t tNum_5 = 0;    std::vector<House*> rgpHouses;    clock_t tStart = clock();    for (int iNum=1; iNum<6; ++iNum )                               //门牌号    {        for (UCHAR eNation=1; eNation<6; ++eNation)                 //国籍        {            for (UCHAR eColor=1; eColor<6; ++eColor)                //颜色            {                for (UCHAR eDrink=1; eDrink<6; ++eDrink)            //饮料                {                    for (UCHAR eCigar=1; eCigar<6; ++eCigar)        //香烟                    {                        for (UCHAR ePet=1; ePet<6; ++ePet)          //宠物                        {                            //根据断言条件进行过滤                            //断言条件:                            //8、挪威人住第一间房(否)                            if ( 1==iNum && Norway != eNation )                                continue;                            //11、第二间房间是蓝色的(否)                            if ( 2==iNum && Blue != eColor )                                continue;                            //7、住在中间房子的人喝牛奶(否)                            if ( 3==iNum && Milk != eDrink )                                continue;                            //1、英国人住红色房子(否)                            if ( British == eNation && Red != eColor )                                continue;                            //2、瑞典人养狗(否)                            if ( Sweden == eNation && Dog != ePet )                                continue;                            //3、丹麦人喝茶(否)                            if ( Denmark == eNation && Tea != eDrink )                                continue;                            //4、绿色房子主人喝咖啡(否)                            if ( Red == eColor && Coffee != eDrink )                                continue;                            //5、抽Pall Mall香烟的人养鸟(否)                            if ( PallMall == eCigar && Bird != ePet )                                continue;                            //6、黄色房子主人抽Dunhill香烟(否)                            if ( Yellow == eColor && Dunhill != eCigar )                                continue;                            //9、抽Blue Master的人喝啤酒(否)                            if ( Beer == eDrink && BlueMaster != eCigar )                                continue;                            //10、德国人抽Prince香烟(否)                            if ( Germany == eNation && Prince != eCigar )                                continue;                            House *pObjHouse = new House(iNum,(NATIONALITY)eNation,                                (HOUSECOLOR)eColor,(BEVERAGE)eDrink,                                (CIGARETTE)eCigar,(PET)ePet);                            rgpHouses.push_back( pObjHouse );                            if ( 1 == iNum ) ++tNum_1;                            if ( 2 == iNum ) ++tNum_2;                            if ( 3 == iNum ) ++tNum_3;                            if ( 4 == iNum ) ++tNum_4;                            if ( 5 == iNum ) ++tNum_5;
这样的可读性明显要看了很多,同时在对关系条件的判断上虽然思路与之前也是一样的,但是由于采用对象的表述方法,因此将判断的方法写入类中,使得程序的逻辑结构更加清晰,程序不容易出错。虽然算法复杂度没有改变,且由于使用new的原因甚至速度有所下降但是,换来的却是思路与结构更为清晰的代码,从这点来说还是值得的。当然若想不受new操作的拖累,完全可以按照此思路去改写前一次的程序,用枚举变量去表述,同样可以获得良好的可读性。可读性的问题解决了,接下来,我们从全排的角度去解决此类问题,来设计一下看看是否再算法复杂度上能够比之前的方法要小些,得到代码如下:
//门牌号:   1           2           3           4           5//国籍:     挪威        德国        英国        瑞典        丹麦//颜色:     黄          蓝          红          绿          白//饮料:     啤酒        水          牛奶        咖啡        茶//香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall//宠物:     Fish        Horse       Cat         Dog         Birdenum HOUSECOLOR     //房子颜色{    XColor  =  0,    Yellow  =  1,    Blue,    Red,    Green,    White};enum BEVERAGE       //饮料{    XDrink  =  0,    Beer    =  1,    Water,    Milk,    Coffee,    Tea};enum NATIONALITY    //国籍{    XNation  =  0,    Norway  =   1,    Germany,    British,    Sweden,    Denmark};enum CIGARETTE      //香烟(品牌){    XCigar  =  0,    Dunhill =  1,    Prince,    Blends,    BlueMaster,    PallMall};enum PET            //宠物{    XPet    =  0,    Fish    =  1,    Horse,    Cat,    Dog,    Bird};class House{public:    House( const int iHouseNum,           NATIONALITY eNation = XNation,            HOUSECOLOR eColor = XColor,           BEVERAGE eDrink = XDrink,           CIGARETTE eCigar = XCigar,            PET ePet = XPet )            : m_iHouseNum( iHouseNum ),              m_eColor( eColor ),              m_eCigar( eCigar ),              m_eDrink( eDrink ),              m_eNation( eNation ),              m_ePet( ePet )    {    }    ~House(){}public:    //Relationship    //bool IsOnLeftSide( const House &objHouse )    //{    //    return 1 == (m_iHouseNum - objHouse.m_iHouseNum);    //}    //bool IsOnRightSide( const House &objHouse )    //{    //    return -1 == (m_iHouseNum - objHouse.m_iHouseNum);    //}    //bool IsNeighbour( const House &objHouse )    //{    //    return 1 == abs(m_iHouseNum - objHouse.m_iHouseNum );    //}public:    //Setter and Getter    void SetCigar( const CIGARETTE eCigar ) { m_eCigar = eCigar; }    void SetHouseColor( const HOUSECOLOR eColor ) { m_eColor = eColor; }    void SetBeverage( const BEVERAGE eDrink ) { m_eDrink = eDrink; }    void SetNationality(const NATIONALITY eNation ) { m_eNation = eNation; }    void SetPet( const PET ePet ) { m_ePet = ePet; }    const CIGARETTE GetCigar( void ) const { return m_eCigar; }    const HOUSECOLOR GetHouseColor( void ) const { return m_eColor; }    const BEVERAGE GetBeverage( void ) const { return m_eDrink; }    const NATIONALITY GetNationality( void ) const { return m_eNation; }    const PET GetPet( void ) const { return m_ePet; }    const int GetHouseNum( void ) const { return m_iHouseNum; }private:    CIGARETTE       m_eCigar;    HOUSECOLOR      m_eColor;    BEVERAGE        m_eDrink;    NATIONALITY     m_eNation;    PET             m_ePet;    int             m_iHouseNum;};//门牌号:   1           2           3           4           5//映射号:  1           2           3           4           5//国籍:     挪威        德国        英国        瑞典        丹麦//颜色:     黄          蓝          红          绿          白//饮料:     啤酒        水          牛奶        咖啡        茶//香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall//宠物:     Fish        Horse       Cat         Dog         Birdchar *pstrsNationality[5] = { "挪威", "德国", "英国", "瑞典", "丹麦" };char *pstrsHouseColor[5]  = { "黄", "蓝", "红", "绿", "白" };char *pstrsBeverage[5]    = { "啤酒", "水", "牛奶", "咖啡", "茶" };char *pstrsCigarette[5]   = { "Dunhill", "Prince", "Blends", "BlueMaster", "PallMall" };char *pstrsPet[5]         = { "Fish", "Horse", "Cat", "Dog", "Bird" };int main( int argc, char *argv[] ){    //国籍:     挪威        德国        英国        瑞典        丹麦    std::vector<NATIONALITY> rgpNations;    rgpNations.push_back( Norway );    rgpNations.push_back( Germany );    rgpNations.push_back( British );    rgpNations.push_back( Sweden );    rgpNations.push_back( Denmark );    std::sort( rgpNations.begin(), rgpNations.end() );    std::vector<HOUSECOLOR>  rgpColors;    //颜色:     黄          蓝          红          绿          白    rgpColors.push_back( Yellow );    rgpColors.push_back( Blue );    rgpColors.push_back( Red );    rgpColors.push_back( Green );    rgpColors.push_back( White );    std::sort( rgpColors.begin(), rgpColors.end() );    //饮料:     啤酒        水          牛奶        咖啡        茶    std::vector<BEVERAGE>    rgpDrinks;    rgpDrinks.push_back( Beer );    rgpDrinks.push_back( Water );    rgpDrinks.push_back( Milk );    rgpDrinks.push_back( Coffee );    rgpDrinks.push_back( Tea );    std::sort( rgpDrinks.begin(), rgpDrinks.end() );    //香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall    std::vector<CIGARETTE>   rgpCigars;    rgpCigars.push_back( Dunhill );    rgpCigars.push_back( Prince );    rgpCigars.push_back( Blends );    rgpCigars.push_back( BlueMaster );    rgpCigars.push_back( PallMall );    std::sort( rgpCigars.begin(), rgpCigars.end() );    //宠物:     Fish        Horse       Cat         Dog         Bird    std::vector<PET>         rgpPets;    rgpPets.push_back( Fish );    rgpPets.push_back( Horse );    rgpPets.push_back( Cat );    rgpPets.push_back( Dog );    rgpPets.push_back( Bird );    std::sort( rgpPets.begin(), rgpPets.end() );    clock_t tStart = clock();    House obj_1(1), obj_2(2), obj_3(3), obj_4(4), obj_5(5);    UINT uCounter = 0;    do                              //国籍    {        do                          //颜色        {            do                      //饮料            {                do                  //香烟                {                    do              //宠物                    {                        //国籍                        obj_1.SetNationality( rgpNations[0] );                        obj_2.SetNationality( rgpNations[1] );                        obj_3.SetNationality( rgpNations[2] );                        obj_4.SetNationality( rgpNations[3] );                        obj_5.SetNationality( rgpNations[4] );                        //颜色                        obj_1.SetHouseColor( rgpColors[0] );                        obj_2.SetHouseColor( rgpColors[1] );                        obj_3.SetHouseColor( rgpColors[2] );                        obj_4.SetHouseColor( rgpColors[3] );                        obj_5.SetHouseColor( rgpColors[4] );                        //饮料                        obj_1.SetBeverage( rgpDrinks[0] );                        obj_2.SetBeverage( rgpDrinks[1] );                        obj_3.SetBeverage( rgpDrinks[2] );                        obj_4.SetBeverage( rgpDrinks[3] );                        obj_5.SetBeverage( rgpDrinks[4] );                        //香烟                        obj_1.SetCigar( rgpCigars[0] );                        obj_2.SetCigar( rgpCigars[1] );                        obj_3.SetCigar( rgpCigars[2] );                        obj_4.SetCigar( rgpCigars[3] );                        obj_5.SetCigar( rgpCigars[4] );                        //宠物                        obj_1.SetPet( rgpPets[0] );                        obj_2.SetPet( rgpPets[1] );                        obj_3.SetPet( rgpPets[2] );                        obj_4.SetPet( rgpPets[3] );                        obj_5.SetPet( rgpPets[4] );                        std::cout << "uCounter:" << ++uCounter <<" Fin:24883200000" << std::endl;                        //根据断言条件进行过滤                        //断言条件:                        //8、挪威人住第一间房(否)                        if ( Norway != obj_1.GetNationality() )                            continue;                        //11、第二间房间是蓝色的(否)                        if ( Blue != obj_2.GetHouseColor() )                            continue;                        //7、住在中间房子的人喝牛奶(否)                        if ( Milk != obj_3.GetBeverage() )                            continue;                        //1、英国人住红色房子(否)                        if ((British == obj_2.GetNationality() && Red != obj_2.GetHouseColor()) ||                            (British == obj_3.GetNationality() && Red != obj_3.GetHouseColor()) ||                            (British == obj_4.GetNationality() && Red != obj_4.GetHouseColor()) ||                            (British == obj_5.GetNationality() && Red != obj_5.GetHouseColor()) )                            continue;                        //2、瑞典人养狗(否)                                                    if ((Sweden == obj_2.GetNationality() && Dog != obj_2.GetPet()) ||                            (Sweden == obj_3.GetNationality() && Dog != obj_3.GetPet()) ||                            (Sweden == obj_4.GetNationality() && Dog != obj_4.GetPet()) ||                            (Sweden == obj_5.GetNationality() && Dog != obj_5.GetPet()) )                            continue;                        //3、丹麦人喝茶(否)                        if ((Denmark == obj_2.GetNationality() && Tea != obj_2.GetBeverage()) ||                            (Denmark == obj_3.GetNationality() && Tea != obj_3.GetBeverage()) ||                            (Denmark == obj_4.GetNationality() && Tea != obj_4.GetBeverage()) ||                            (Denmark == obj_5.GetNationality() && Tea != obj_5.GetBeverage()) )                            continue;                        //10、德国人抽Prince香烟(否)                        if ((Germany == obj_2.GetNationality() && Prince != obj_2.GetCigar()) ||                            (Germany == obj_3.GetNationality() && Prince != obj_3.GetCigar()) ||                            (Germany == obj_4.GetNationality() && Prince != obj_4.GetCigar()) ||                            (Germany == obj_5.GetNationality() && Prince != obj_5.GetCigar()) )                            continue;                        //4、绿色房子主人喝咖啡(否)                        if ((Green == obj_1.GetHouseColor() && Coffee != obj_1.GetBeverage()) ||                            (Green == obj_2.GetHouseColor() && Coffee != obj_2.GetBeverage()) ||                            (Green == obj_3.GetHouseColor() && Coffee != obj_3.GetBeverage()) ||                            (Green == obj_4.GetHouseColor() && Coffee != obj_4.GetBeverage()) ||                            (Green == obj_5.GetHouseColor() && Coffee != obj_5.GetBeverage()) )                            continue;                        //5、抽Pall Mall香烟的人养鸟(否)                        if ((PallMall == obj_1.GetCigar() && Bird != obj_1.GetPet()) ||                            (PallMall == obj_2.GetCigar() && Bird != obj_2.GetPet()) ||                            (PallMall == obj_3.GetCigar() && Bird != obj_3.GetPet()) ||                            (PallMall == obj_4.GetCigar() && Bird != obj_4.GetPet()) ||                            (PallMall == obj_5.GetCigar() && Bird != obj_5.GetPet()) )                            continue;                        //6、黄色房子主人抽Dunhill香烟(否)                        if ((Dunhill == obj_1.GetCigar() && Yellow != obj_1.GetHouseColor()) ||                            (Dunhill == obj_2.GetCigar() && Yellow != obj_2.GetHouseColor()) ||                            (Dunhill == obj_3.GetCigar() && Yellow != obj_3.GetHouseColor()) ||                            (Dunhill == obj_4.GetCigar() && Yellow != obj_4.GetHouseColor()) ||                            (Dunhill == obj_5.GetCigar() && Yellow != obj_5.GetHouseColor()) )                            continue;                        //9、抽Blue Master的人喝啤酒(否)                        if ((BlueMaster == obj_1.GetCigar() && Beer != obj_1.GetBeverage()) ||                            (BlueMaster == obj_2.GetCigar() && Beer != obj_2.GetBeverage()) ||                            (BlueMaster == obj_3.GetCigar() && Beer != obj_3.GetBeverage()) ||                            (BlueMaster == obj_4.GetCigar() && Beer != obj_4.GetBeverage()) ||                            (BlueMaster == obj_5.GetCigar() && Beer != obj_5.GetBeverage()) )                            continue;                        //关系条件判断过滤                        //1、绿色房子在白色房子左面。(否)                        if ( (Green == obj_1.GetHouseColor() && White != obj_2.GetHouseColor()) ||                             (Green == obj_2.GetHouseColor() && White != obj_3.GetHouseColor()) ||                             (Green == obj_3.GetHouseColor() && White != obj_4.GetHouseColor()) ||                             (Green == obj_4.GetHouseColor() && White != obj_5.GetHouseColor()) )                             continue;                        //2、抽Blends香烟的人住在养猫的人隔壁。(否)                        if ( (Blends == obj_1.GetCigar() && Cat != obj_2.GetPet()) ||                             (Blends == obj_2.GetCigar() && Cat != obj_1.GetPet() && Cat != obj_3.GetPet())||                             (Blends == obj_3.GetCigar() && Cat != obj_2.GetPet() && Cat != obj_4.GetPet())||                             (Blends == obj_4.GetCigar() && Cat != obj_3.GetPet() && Cat != obj_5.GetPet())||                             (Blends == obj_5.GetCigar() && Cat != obj_4.GetPet()))                             continue;                        //4、抽Blends香烟的人有一个喝水的邻居。(否)                        if ( (Blends == obj_1.GetCigar() && Water != obj_2.GetBeverage()) ||                             (Blends == obj_2.GetCigar() && Water != obj_1.GetBeverage() && Water != obj_3.GetBeverage())||                             (Blends == obj_3.GetCigar() && Water != obj_2.GetBeverage() && Water != obj_4.GetBeverage())||                             (Blends == obj_4.GetCigar() && Water != obj_3.GetBeverage() && Water != obj_5.GetBeverage())||                            ( Blends == obj_5.GetCigar() && Water != obj_4.GetBeverage()))                            continue;                        //3、养马的人住抽Dunhill香烟的人隔壁。(否)                        if ( (Horse == obj_1.GetPet() && Dunhill != obj_2.GetCigar()) ||                             (Horse == obj_2.GetPet() && Dunhill != obj_1.GetCigar() && Dunhill != obj_3.GetCigar())||                             (Horse == obj_3.GetPet() && Dunhill != obj_2.GetCigar() && Dunhill != obj_4.GetCigar())||                             (Horse == obj_4.GetPet() && Dunhill != obj_3.GetCigar() && Dunhill != obj_5.GetCigar())||                             (Horse == obj_5.GetPet() && Dunhill != obj_4.GetCigar()))                            continue;                        clock_t tFinish = clock();                        std::cout <<"Time Cost is"<<tFinish-tStart<<"ms"<<std::endl;                        std::cout <<"1 "                         <<" "<< pstrsNationality[obj_1.GetNationality()]                        <<" "<< pstrsHouseColor[obj_1.GetHouseColor()]                        <<" "<< pstrsBeverage[obj_1.GetBeverage()]                        <<" "<< pstrsCigarette[obj_1.GetCigar()]                        <<" "<< pstrsPet[obj_1.GetPet()]                        <<std::endl;                        std::cout <<"2 "                         <<" "<< pstrsNationality[obj_2.GetNationality()]                        <<" "<< pstrsHouseColor[obj_2.GetHouseColor()]                        <<" "<< pstrsBeverage[obj_2.GetBeverage()]                        <<" "<< pstrsCigarette[obj_2.GetCigar()]                        <<" "<< pstrsPet[obj_2.GetPet()]                        <<std::endl;                        std::cout <<"3 "                             <<" "<< pstrsNationality[obj_3.GetNationality()]                        <<" "<< pstrsHouseColor[obj_3.GetHouseColor()]                        <<" "<< pstrsBeverage[obj_3.GetBeverage()]                        <<" "<< pstrsCigarette[obj_3.GetCigar()]                        <<" "<< pstrsPet[obj_3.GetPet()]                        <<std::endl;                        std::cout <<"4 "                         <<" "<< pstrsNationality[obj_4.GetNationality()]                        <<" "<< pstrsHouseColor[obj_4.GetHouseColor()]                        <<" "<< pstrsBeverage[obj_4.GetBeverage()]                        <<" "<< pstrsCigarette[obj_4.GetCigar()]                        <<" "<< pstrsPet[obj_4.GetPet()]                        <<std::endl;                        std::cout <<"5 "                         <<" "<< pstrsNationality[obj_5.GetNationality()]                        <<" "<< pstrsHouseColor[obj_5.GetHouseColor()]                        <<" "<< pstrsBeverage[obj_5.GetBeverage()]                        <<" "<< pstrsCigarette[obj_5.GetCigar()]                        <<" "<< pstrsPet[obj_5.GetPet()]                        <<std::endl;                    } while( next_permutation(rgpPets.begin(), rgpPets.end()) );                } while( next_permutation(rgpCigars.begin(), rgpCigars.end()) );            } while( next_permutation(rgpDrinks.begin(), rgpDrinks.end()) );        } while( next_permutation(rgpColors.begin(), rgpColors.end()) );    } while( next_permutation(rgpNations.begin(), rgpNations.end()) );     return 0;}
代码的可读性可谓是非常高了,但是其算法复杂度却是相当之高,粗略估计一下大概至少需要执行个把小时才能有结果,因此不具备“切实”的可行性(PS:为一个简单的题目等个把小时不实际!),看看如何优化一下子?!通过对实现进行观察我们可以发现,有些判断还有条件可以提前,这样可以大大降低不必要的循环次数,另外对于例如:挪威人住第一间房这样的条件可以将挪威人在房间上的排列剔除掉。经过优化的代码大大提高了效率,代码如下:
//门牌号:   1           2           3           4           5//映射号:  1           2           3           4           5//国籍:     挪威        德国        英国        瑞典        丹麦//颜色:     黄          蓝          红          绿          白//饮料:     啤酒        水          牛奶        咖啡        茶//香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall//宠物:     Fish        Horse       Cat         Dog         Birdchar *pstrsNationality[5] = { "挪威", "德国", "英国", "瑞典", "丹麦" };char *pstrsHouseColor[5]  = { "黄", "蓝", "红", "绿", "白" };char *pstrsBeverage[5]    = { "啤酒", "水", "牛奶", "咖啡", "茶" };char *pstrsCigarette[5]   = { "Dunhill", "Prince", "Blends", "BlueMaster", "PallMall" };char *pstrsPet[5]         = { "Fish", "Horse", "Cat", "Dog", "Bird" };int main( int argc, char *argv[] ){    //国籍:     挪威        德国        英国        瑞典        丹麦    std::vector<NATIONALITY> rgpNations;    //rgpNations.push_back( Norway );    rgpNations.push_back( Germany );    rgpNations.push_back( British );    rgpNations.push_back( Sweden );    rgpNations.push_back( Denmark );    std::sort( rgpNations.begin(), rgpNations.end() );    std::vector<HOUSECOLOR>  rgpColors;    //颜色:     黄          蓝          红          绿          白    rgpColors.push_back( Yellow );    //rgpColors.push_back( Blue );    rgpColors.push_back( Red );    rgpColors.push_back( Green );    rgpColors.push_back( White );    std::sort( rgpColors.begin(), rgpColors.end() );    //饮料:     啤酒        水          牛奶        咖啡        茶    std::vector<BEVERAGE>    rgpDrinks;    rgpDrinks.push_back( Beer );    rgpDrinks.push_back( Water );    //rgpDrinks.push_back( Milk );    rgpDrinks.push_back( Coffee );    rgpDrinks.push_back( Tea );    std::sort( rgpDrinks.begin(), rgpDrinks.end() );    //香烟牌子: Dunhill     Prince      Blends      BlueMaster  PallMall    std::vector<CIGARETTE>   rgpCigars;    rgpCigars.push_back( Dunhill );    rgpCigars.push_back( Prince );    rgpCigars.push_back( Blends );    rgpCigars.push_back( BlueMaster );    rgpCigars.push_back( PallMall );    std::sort( rgpCigars.begin(), rgpCigars.end() );    //宠物:     Fish        Horse       Cat         Dog         Bird    std::vector<PET>         rgpPets;    rgpPets.push_back( Fish );    rgpPets.push_back( Horse );    rgpPets.push_back( Cat );    rgpPets.push_back( Dog );    rgpPets.push_back( Bird );    std::sort( rgpPets.begin(), rgpPets.end() );    clock_t tStart = clock();    House obj_1(1), obj_2(2), obj_3(3), obj_4(4), obj_5(5);    UINT uCounter = 0;    obj_1.SetNationality( Norway );    obj_2.SetHouseColor( Blue );    obj_3.SetBeverage( Milk );    do                              //国籍    {        //国籍        obj_2.SetNationality( rgpNations[0] );        obj_3.SetNationality( rgpNations[1] );        obj_4.SetNationality( rgpNations[2] );        obj_5.SetNationality( rgpNations[3] );        do                          //颜色        {            //颜色            obj_1.SetHouseColor( rgpColors[0] );            obj_3.SetHouseColor( rgpColors[1] );            obj_4.SetHouseColor( rgpColors[2] );            obj_5.SetHouseColor( rgpColors[3] );            //1、英国人住红色房子(否)            if ((British == obj_2.GetNationality() && Red != obj_2.GetHouseColor()) ||                (British == obj_3.GetNationality() && Red != obj_3.GetHouseColor()) ||                (British == obj_4.GetNationality() && Red != obj_4.GetHouseColor()) ||                (British == obj_5.GetNationality() && Red != obj_5.GetHouseColor()) )                continue;            //1、绿色房子在白色房子左面。(否)            if ( (Green == obj_1.GetHouseColor() && White != obj_2.GetHouseColor()) ||                (Green == obj_2.GetHouseColor() && White != obj_3.GetHouseColor()) ||                (Green == obj_3.GetHouseColor() && White != obj_4.GetHouseColor()) ||                (Green == obj_4.GetHouseColor() && White != obj_5.GetHouseColor()) ||                Green == obj_5.GetHouseColor() )                continue;            do                      //饮料            {                //饮料                obj_1.SetBeverage( rgpDrinks[0] );                obj_2.SetBeverage( rgpDrinks[1] );                obj_4.SetBeverage( rgpDrinks[2] );                obj_5.SetBeverage( rgpDrinks[3] );                //3、丹麦人喝茶(否)                if ((Denmark == obj_2.GetNationality() && Tea != obj_2.GetBeverage()) ||                    (Denmark == obj_3.GetNationality() && Tea != obj_3.GetBeverage()) ||                    (Denmark == obj_4.GetNationality() && Tea != obj_4.GetBeverage()) ||                    (Denmark == obj_5.GetNationality() && Tea != obj_5.GetBeverage()) )                    continue;                //4、绿色房子主人喝咖啡(否)                if ((Green == obj_1.GetHouseColor() && Coffee != obj_1.GetBeverage()) ||                    (Green == obj_2.GetHouseColor() && Coffee != obj_2.GetBeverage()) ||                    (Green == obj_3.GetHouseColor() && Coffee != obj_3.GetBeverage()) ||                    (Green == obj_4.GetHouseColor() && Coffee != obj_4.GetBeverage()) ||                    (Green == obj_5.GetHouseColor() && Coffee != obj_5.GetBeverage()) )                    continue;                do                  //香烟                {                    //香烟                    obj_1.SetCigar( rgpCigars[0] );                    obj_2.SetCigar( rgpCigars[1] );                    obj_3.SetCigar( rgpCigars[2] );                    obj_4.SetCigar( rgpCigars[3] );                    obj_5.SetCigar( rgpCigars[4] );                    //10、德国人抽Prince香烟(否)                    if ((Germany == obj_2.GetNationality() && Prince != obj_2.GetCigar()) ||                        (Germany == obj_3.GetNationality() && Prince != obj_3.GetCigar()) ||                        (Germany == obj_4.GetNationality() && Prince != obj_4.GetCigar()) ||                        (Germany == obj_5.GetNationality() && Prince != obj_5.GetCigar()) )                        continue;                    //6、黄色房子主人抽Dunhill香烟(否)                    if ((Dunhill == obj_1.GetCigar() && Yellow != obj_1.GetHouseColor()) ||                        (Dunhill == obj_2.GetCigar() && Yellow != obj_2.GetHouseColor()) ||                        (Dunhill == obj_3.GetCigar() && Yellow != obj_3.GetHouseColor()) ||                        (Dunhill == obj_4.GetCigar() && Yellow != obj_4.GetHouseColor()) ||                        (Dunhill == obj_5.GetCigar() && Yellow != obj_5.GetHouseColor()) )                        continue;                    //9、抽Blue Master的人喝啤酒(否)                    if ((BlueMaster == obj_1.GetCigar() && Beer != obj_1.GetBeverage()) ||                        (BlueMaster == obj_2.GetCigar() && Beer != obj_2.GetBeverage()) ||                        (BlueMaster == obj_3.GetCigar() && Beer != obj_3.GetBeverage()) ||                        (BlueMaster == obj_4.GetCigar() && Beer != obj_4.GetBeverage()) ||                        (BlueMaster == obj_5.GetCigar() && Beer != obj_5.GetBeverage()) )                        continue;                    //4、抽Blends香烟的人有一个喝水的邻居。(否)                    if ( (Blends == obj_1.GetCigar() && Water != obj_2.GetBeverage()) ||                        (Blends == obj_2.GetCigar() && Water != obj_1.GetBeverage() && Water != obj_3.GetBeverage())||                        (Blends == obj_3.GetCigar() && Water != obj_2.GetBeverage() && Water != obj_4.GetBeverage())||                        (Blends == obj_4.GetCigar() && Water != obj_3.GetBeverage() && Water != obj_5.GetBeverage())||                        ( Blends == obj_5.GetCigar() && Water != obj_4.GetBeverage()))                        continue;                    do              //宠物                    {                        //宠物                        obj_1.SetPet( rgpPets[0] );                        obj_2.SetPet( rgpPets[1] );                        obj_3.SetPet( rgpPets[2] );                        obj_4.SetPet( rgpPets[3] );                        obj_5.SetPet( rgpPets[4] );                        //2、瑞典人养狗(否)                        if ((Sweden == obj_2.GetNationality() && Dog != obj_2.GetPet()) ||                            (Sweden == obj_3.GetNationality() && Dog != obj_3.GetPet()) ||                            (Sweden == obj_4.GetNationality() && Dog != obj_4.GetPet()) ||                            (Sweden == obj_5.GetNationality() && Dog != obj_5.GetPet()) )                            continue;                        //5、抽Pall Mall香烟的人养鸟(否)                        if ((PallMall == obj_1.GetCigar() && Bird != obj_1.GetPet()) ||                            (PallMall == obj_2.GetCigar() && Bird != obj_2.GetPet()) ||                            (PallMall == obj_3.GetCigar() && Bird != obj_3.GetPet()) ||                            (PallMall == obj_4.GetCigar() && Bird != obj_4.GetPet()) ||                            (PallMall == obj_5.GetCigar() && Bird != obj_5.GetPet()) )                            continue;                        //关系条件判断过滤                        //2、抽Blends香烟的人住在养猫的人隔壁。(否)                        if ( (Blends == obj_1.GetCigar() && Cat != obj_2.GetPet()) ||                             (Blends == obj_2.GetCigar() && Cat != obj_1.GetPet() && Cat != obj_3.GetPet())||                             (Blends == obj_3.GetCigar() && Cat != obj_2.GetPet() && Cat != obj_4.GetPet())||                             (Blends == obj_4.GetCigar() && Cat != obj_3.GetPet() && Cat != obj_5.GetPet())||                             (Blends == obj_5.GetCigar() && Cat != obj_4.GetPet()))                             continue;                        //3、养马的人住抽Dunhill香烟的人隔壁。(否)                        if ( (Horse == obj_1.GetPet() && Dunhill != obj_2.GetCigar()) ||                             (Horse == obj_2.GetPet() && Dunhill != obj_1.GetCigar() && Dunhill != obj_3.GetCigar())||                             (Horse == obj_3.GetPet() && Dunhill != obj_2.GetCigar() && Dunhill != obj_4.GetCigar())||                             (Horse == obj_4.GetPet() && Dunhill != obj_3.GetCigar() && Dunhill != obj_5.GetCigar())||                             (Horse == obj_5.GetPet() && Dunhill != obj_4.GetCigar()))                            continue;                        clock_t tFinish = clock();                        std::cout <<"Time Cost is"<<tFinish-tStart<<"ms"<<std::endl;                        std::cout <<"1 "                         <<" "<< pstrsNationality[obj_1.GetNationality()-1]                        <<" "<< pstrsHouseColor[obj_1.GetHouseColor()-1]                        <<" "<< pstrsBeverage[obj_1.GetBeverage()-1]                        <<" "<< pstrsCigarette[obj_1.GetCigar()-1]                        <<" "<< pstrsPet[obj_1.GetPet()-1]                        <<std::endl;                        std::cout <<"2 "                         <<" "<< pstrsNationality[obj_2.GetNationality()-1]                        <<" "<< pstrsHouseColor[obj_2.GetHouseColor()-1]                        <<" "<< pstrsBeverage[obj_2.GetBeverage()-1]                        <<" "<< pstrsCigarette[obj_2.GetCigar()-1]                        <<" "<< pstrsPet[obj_2.GetPet()-1]                        <<std::endl;                        std::cout <<"3 "                             <<" "<< pstrsNationality[obj_3.GetNationality()-1]                        <<" "<< pstrsHouseColor[obj_3.GetHouseColor()-1]                        <<" "<< pstrsBeverage[obj_3.GetBeverage()-1]                        <<" "<< pstrsCigarette[obj_3.GetCigar()-1]                        <<" "<< pstrsPet[obj_3.GetPet()-1]                        <<std::endl;                        std::cout <<"4 "                         <<" "<< pstrsNationality[obj_4.GetNationality()-1]                        <<" "<< pstrsHouseColor[obj_4.GetHouseColor()-1]                        <<" "<< pstrsBeverage[obj_4.GetBeverage()-1]                        <<" "<< pstrsCigarette[obj_4.GetCigar()-1]                        <<" "<< pstrsPet[obj_4.GetPet()-1]                        <<std::endl;                        std::cout <<"5 "                         <<" "<< pstrsNationality[obj_5.GetNationality()-1]                        <<" "<< pstrsHouseColor[obj_5.GetHouseColor()-1]                        <<" "<< pstrsBeverage[obj_5.GetBeverage()-1]                        <<" "<< pstrsCigarette[obj_5.GetCigar()-1]                        <<" "<< pstrsPet[obj_5.GetPet()-1]                        <<std::endl;                    } while( next_permutation(rgpPets.begin(), rgpPets.end()) );                } while( next_permutation(rgpCigars.begin(), rgpCigars.end()) );            } while( next_permutation(rgpDrinks.begin(), rgpDrinks.end()) );        } while( next_permutation(rgpColors.begin(), rgpColors.end()) );    } while( next_permutation(rgpNations.begin(), rgpNations.end()) );     return 0;}

经过优化后的代码,能够很好地得出运行结果。同样的道理,对于我们之前采用的不用全排列的方法也可以综合使用判断提前的优化手段,使得计算效率大大提升,省去不必要的循环。如此一来,不仅有了解决方案、而且代码的可读性大大增强,同时对于结构的细微调整达到了良好的优化目的。