主机名由多级域名组成,自右向左,依次是顶级域名、二级域名、三级域名…..以此类推
例,主机名:google.com.hk
hk是顶级域名
com是二级域名
google是三级域名
现在我们需要实现一个主机名的排序功能
排序规则
1)主机名按照域名等级排序,即先按照顶级域名排序,顶级域名相同的再按照二级域名排序,顶级和二级域名均相同的再按照三级域名排序,以此类推,直到整个主机名排序完毕
2)如果短主机名是由长主机名从顶级域名开始的连续一个或多个域名组成,短主机名排在长主机名前面。例:google.com 排在gmail.google.com 之前
3)每一级域名按照字典顺序排序,字典顺序定义见下页
输入确保符合以下规则(无需检查)
1)主机名以字符串形式给出,非空串
2)主机名中仅包含小写英文字母和分隔符’.’
3)主机名中没有连续的’.’,不以’.’开始,也不以’.’结束
3)主机名不存在重复
字典顺序定义
1、两个单词(字母按照自左向右顺序)先以第一个字母作为排序的基准,如果第一个字母相同,就用第二个字母为基准,如果第二个字母相同就以第三个字母为基准。依此类推,如果到某个字母不相同,字母顺序在前的那个单词顺序在前。
例:abc 排在 abf 之前
2、如果短单词是长单词从首字母开始连续的一部分,短单词顺序在前。
例:abc 排在 abcd 之前
// 添加主机名
int add_host_name(const char* host_name);
// 获取主机名
int get_host_name(int serial_number, int host_name_max_length, char* host_name);
// 清空所有主机名
void clear(void);
#include <string.h>
#include <stdlib.h>
#include <vector>
using namespace std;
std::vector<string> g_vecHostName;
void mySort(std::vector<string>& vector) //对域名排序
{
if (!vector.empty())
{
size_t length = vector.size();
string tmpStr = vector[0];
for (unsigned int i = 0; i < length; i++)
{
for(unsigned int j = 0; j < length-i-1; j++)
{
if( vector[j].compare(vector[j+1]) > 0)
{
tmpStr = vector[j];
vector[j] = vector[j+1];
vector[j+1] = tmpStr;
}
}
}
}
}
string myReverseString(const string& srcString,char ch)
{
unsigned int countDism = 0;
string strDest = "";
string tmpStr = srcString;
for (size_t i = 0; i < tmpStr.length(); ++i)
{
if (ch == tmpStr[i])
{
countDism ++;
}
}
for (size_t i = 0; i < countDism+1; ++i)
{
size_t nPos = -1;
nPos = tmpStr.find_last_of(".");
if (nPos != std::string::npos)
{
std::string tmpStrSegment = tmpStr.substr(nPos+1);
strDest.append(tmpStrSegment);
strDest.append(".");
tmpStr = tmpStr.substr(0,nPos);
}
else
{
strDest.append(tmpStr);
}
}
return strDest;
}
/*****************************************************************************
Description : 添加主机名
Input Param : host_name 主机名字符串,非空串
Output Param : 无
Return Value : 成功返回0,失败返回-1
*****************************************************************************/
int add_host_name(const char* host_name)
{
if (NULL == host_name || 0 == strlen(host_name))
{
return -1;
}
else
{
const char *pValue = host_name;
size_t length = strlen(pValue);
if (('.' == pValue[0]) || ('.' == pValue[length-1]))
{
return -1;
}
while('\0' != *pValue)
{
char ch = *pValue;
if (((ch < 'a') || (ch > 'z')) && ('.' != ch))
{
return -1;
}
else if(( '.' == *pValue) && ( '.' == *(pValue+1)))
{
return -1;
}
pValue++;
}
char *pToken;
std::vector<string> tmpVec;
char *pHostName = new char[length+1];
strncpy(pHostName,host_name,length);
pHostName[length] = '\0';
char *pDelim = ".";
pToken = strtok(pHostName, pDelim);
while (NULL != pToken)
{
tmpVec.push_back(pToken);
pToken = strtok( NULL, pDelim); // Get next token:
}
delete []pHostName;
pHostName = NULL;
string strHostName("");
std::vector<string>::reverse_iterator rIter;
for (rIter = tmpVec.rbegin(); rIter != tmpVec.rend(); ++rIter)
{
strHostName.append(*rIter);
strHostName.append(".");
}
strHostName = strHostName.substr(0,strHostName.length()-1);
if (g_vecHostName.empty())
{
g_vecHostName.push_back(strHostName); //首次插入数据
}
else
{
std::vector<string>::iterator pIter = g_vecHostName.begin();
for (; pIter != g_vecHostName.end(); ++pIter)
{
if (strHostName.compare(*pIter) != 0)
{
continue;
}
else
{
return -1;
}
}
if (pIter == g_vecHostName.end())
{
g_vecHostName.push_back(strHostName); //没有重复域,插入vector
}
}
mySort(g_vecHostName);
return 0;
}
}
/*****************************************************************************
Description : 获取主机名
Input Param : serial_number 排序后的序列号,从1开始
host_name_max_length host_name的最大长度,包括'\0'
Output Param : host_name 主机名字符串,必须包括’\0’,内存由调用者分配和释放
Return Value : 成功返回0,失败返回-1(如:serial_number超出范围、最大长度不够)
*****************************************************************************/
int get_host_name(int serial_number, int host_name_max_length, char* host_name)
{
size_t index = serial_number;
if (index > g_vecHostName.size() || serial_number < 1)
{
return -1;
}
if ((size_t)host_name_max_length <= g_vecHostName[index-1].length())
{
return -1;
}
string strHostName = "";
strHostName = myReverseString(g_vecHostName[index-1],'.');
size_t nLength = strHostName.length();
strncpy(host_name,strHostName.c_str(),nLength);
host_name[nLength] = '\0';
return 0;
}
/*****************************************************************************
Description : 清空所有主机名
Input Param : 无
Output Param : 无
Return Value : 无
*****************************************************************************/
void clear(void)
{
g_vecHostName.clear();
}