主机名排序

题目:对主机名按字典顺序进行排序。

          支持接口:

           1)、int add_host_name(const char* hostname);  //添加主机

           2)、int get_host_name(int serial, int maxSize, char* pOut) //获取排序后的第serial个主机(起始为1),若maxSize 小于此域名的长度(包括'\0'),则返回-1,pOut空间由调用者申请和释放

规则:1、从顶级域名开始比较

             2、存在前缀时,长着较大,例如    :  huawei.com 排在  huawei2.com之前

             3、子域名排在前面,例如:  sse.huawei.com 排在 huawei.com之前


题目描述很简单,思路也不难,为难的事选择何种算法。算法选择:

1、借助C++ STL中的set可以简单快速的完成。分析如下:

     set是ordered的unique序列,那么我们需要对主机名进行重构造,按域名级别进行倒序,例如:www.huawei.com  重构为   com.huawei.www

     把重构后的域名加入到set中,即可得到排序后的主机名

2、使用链表操作,分析如下:

    核心算法是对单链表进行排序,重点在于链表之间的指针变换,其次要完成比较函数的定义。此算法适合对指针了解清晰的同学。Jeick采用了此法。参考代码如下



Author: Jeick Jia (贾钰)  

E-mail: Jyu.jia@huawei.com

Timer: 2013-10-23


//Host.h 头文件

//主机名及相关操作的函数声明

#ifndef HOST_H_
#define HOST_H_

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

typedef struct _CHost
{
    const char* hostName;
    _CHost* pNext;
}Host;
//排序链表
Host* SortList(Host* mylist);


int add_into(Host** host,const char* host_name);
int add_host_name(const char* host_name);
int get_host_name(int serial,int maxSize,char* pOut);
//销毁主机链
void Clear(Host** host);
//比较函数
int CompareHost(const char* _front,const char* _back);

void Print();
int getSize();


#endif // HOST_H_

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//Host.cpp

//Host的实现文件

#include "Host.h"

const int OK = 0;
const int ERR = -1;

Host* pHost = NULL;

int currentSize = 0;

/** \brief 向表中添加新主机
* \return
*/
int add_into(Host** host,const char* host_name)
{
if (NULL == host_name)
return ERR;
Host* newHost = new Host;
if (NULL == newHost)
return ERR;

newHost->hostName = host_name;
newHost->pNext = NULL;

newHost->pNext = *host;

*host = newHost;
return OK;
}

Host* SortList(Host* mylist)
{
Host* first = (Host*)NULL;
Host* tail = (Host*)NULL;
Host* maxPtr = (Host*)NULL;
Host* current = (Host*)NULL;
Host* pre = (Host*)NULL;

while (NULL != mylist)
{
//选择最大项
for (current = maxPtr = mylist;NULL != current->pNext;current = current->pNext)
if (0 < CompareHost(maxPtr->hostName,current->pNext->hostName))
{
maxPtr = current->pNext;
pre = current;
}
//组件已排序链
if (NULL == first)
{
first = tail = maxPtr;
}
else
{
tail->pNext = maxPtr;
tail = tail->pNext;
}
//在原链中去除maxPtr
if (maxPtr == mylist)
mylist = mylist->pNext;
else
{
pre->pNext = maxPtr->pNext;
}
}
if (NULL != first)
tail->pNext = NULL;
return first;
}

/** \brief 添加主机名
* \param 插入已排序的链中
* \return
*/
int add_host_name(const char* host_name)
{
if (NULL == host_name)
return ERR;
if (ERR == add_into(&pHost,host_name))
return ERR;
currentSize ++;
pHost = SortList(pHost);
return OK;
}

/** \brief 获取排序后的第serial个主机名
* \param maxSize pOut最大长度包括 '\0'
* \param
* \return
*/
int get_host_name(int serial,int maxSize,char* pOut)
{
if (serial < 1 || serial > currentSize || maxSize < 1 || NULL == pOut)
{
return ERR;
}
int step = 0,len;
int ret = ERR;
Host* work = pHost;
while (NULL != work)
{
step++;
if (step == serial) /**找出第serial位主机名*/
{
len = strlen(work->hostName);
if (maxSize <= len) /**maxSize小于主机名长度*/
{
break;
}
else
{
strncpy(pOut,work->hostName,len);
*(pOut+len) = '\0';
ret = OK;
break;
}
}
work = work->pNext;
}
return ret;

}


/** \brief 清理主机名链表
* \param
* \param
* \return
*/
void Clear(Host** host)
{
if (NULL == *host)
{
return;
}
Clear(&((*host)->pNext));
delete *host;
*host = NULL;

return;
}

/** \brief 比较两个主机的大小,根据规则
* \return
*/
int CompareHost(const char* _front,const char* _back)
{
string Front = _front;
string Back = _back;

string FrontSub,BackSub;
size_t front_pos,back_pos;
int result = 0,lenF,lenB;

while ( 0 != Front.length() && 0 != Back.length())
{
front_pos = Front.find_last_of(".");
back_pos = Back.find_last_of(".");

FrontSub = Front.substr(front_pos+1);
BackSub = Back.substr(back_pos+1);

Front = Front.substr(0,front_pos);
Back = Back.substr(0,back_pos);

result = FrontSub.compare(BackSub);


if (0 == result && (string::npos == front_pos && string::npos == back_pos))
{
break;
}
if (0 == result)
{
continue;
}

return result;
}
if (0 == result)
{
result = (strlen(_front) > strlen(_back))?-1:1;
}
return result;
}

void Print()
{
Host* work = pHost;
while (NULL != work)
{
cout<<work->hostName<<endl;
work = work->pNext;
}
}
int getSize()
{
return currentSize;
}

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//UnitTest.h 头文件

//测试文件

#ifndef UNITTEST_H_
#define UNITTEST_H_

void TestCase01();
void TestCase02();
void TestCase03();
void TestCase04();
#endif // UNITTEST_H_

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//UnitTest.cpp

//测试函数


#include "UnitTest.h"
#include "Host.h"

extern Host* pHost;

void TestCase01()
{
    puts("TestCase01");
    add_host_name("www.huawei.com");
    add_host_name("sse2.huawei.com");
    add_host_name("sse.huawei.com");
    char pOut[32] = {0};

    get_host_name(1,32,pOut);

    if (0 != strcmp(pOut,"sse.huawei.com"))
    {
        cout<<"Expect: sse.huawei.com"<<endl;
        cout<<"Actully: "<<pOut<<endl;
    }
    else
    {
        puts("pass");
    }

   Clear(&pHost);
}
void TestCase02()
{
    puts("TestCase02");
    char*host[5] = {"www.huawei.com",
                "sse.huawei.com",
                "www.java.org",
                "huawei.com",
                "mail.google.com.hk"};
    char* expert[5] = {"huawei.com",
                        "sse.huawei.com",
                        "www.huawei.com",
                        "mail.google.com.hk",
                        "www.java.org"};
    char pt[32] = {0};
    int flag = 0;
    for(int i=0;i<5;i++)
    {
        add_host_name(*(host+i));
    }
    for (int i=0;i<5;i++)
    {
        get_host_name(i+1,32,pt);
        if (0 != strcmp(pt,*(expert+i)))
        {
            cout<<"Expert:"<<*(expert+i)<<endl;
            cout<<"Actully:"<<pt<<endl;
            flag = 1;
            break;
        }
    }
    if (!flag)
        puts("pass");
    Clear(&pHost);
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//main.cpp

//主测函数main


#include "UnitTest.h"

using namespace std;

int main()
{
    TestCase01();
    TestCase02();
    return 0;
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

上述代码测试结果:






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值