题目:对主机名按字典顺序进行排序。
支持接口:
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;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
上述代码测试结果: