题目不多说了,见如下连接:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1002
我的思想是二叉排序树,不过如果是正儿八经的软件这样作肯定是违背规则的(除非十分注意效率问题)。因为电话号码是7位数,所以我想用long类型来作,毕竟要比strcmp(char *, char *)有较高的效率,当然这也带来了几个问题:
1.电话号码从char*转成long,这个思想比较简单,就是比较麻烦,按照规则作就好了
2.电话号码的输出。这个比较麻烦,反正我是进了这个圈套了。比如说电话号码“001-1000”,如果是long的话,最后输出就是“11000”,少了前两个0,这个一定要注意
题目本身要注意几个问题:
1.电话输出的时候中间要个‘-’,我第一次就是这个成了WA
2.没有匹配时候要输出“No duplicates.”。PS:我最后就是因为这个WA了好几次,主要是没看清题目,少了个点...
下面是代码:
#include <iostream>
#include <cstring>
using namespace std;
const int STR_MAX = 50;
const int STACK_MAX = 100000;
class CPhone
{
public:
CPhone(char *);
//private:为了效率全部设成public
long phoneNumber;
int count;
};
class BSNode
{
public:
BSNode(CPhone *phone, BSNode *lc, BSNode *rc):data(phone), lchild(lc), rchild(rc) {};
CPhone *data;
BSNode *lchild, *rchild;
};
CPhone::CPhone(char *strPhoneNumber)
{
this->phoneNumber = atol(strPhoneNumber);
this->count = 1;
}
bool testPhoneNumber(char *strPhoneNumber)
{
int slen = strlen(strPhoneNumber);
int i,j;
for (i = 0, j = 0; j < slen; j++, i++)
{
switch(strPhoneNumber[j])
{
case 'A':
case 'B':
case 'C':
strPhoneNumber[i] = '2';break;
case 'D':
case 'E':
case 'F':
strPhoneNumber[i] = '3';break;
case 'G':
case 'H':
case 'I':
strPhoneNumber[i] = '4';break;
case 'J':
case 'K':
case 'L':
strPhoneNumber[i] = '5';break;
case 'M':
case 'N':
case 'O':
strPhoneNumber[i] = '6';break;
case 'P':
case 'R':
case 'S':
strPhoneNumber[i] = '7';break;
case 'T':
case 'U':
case 'V':
strPhoneNumber[i] = '8';break;
case 'W':
case 'X':
case 'Y':
strPhoneNumber[i] = '9';break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
strPhoneNumber[i] = strPhoneNumber[j];break;
case '-':
i--;break;
default:
return false;
}
}
strPhoneNumber[i] = 0;
if (strlen(strPhoneNumber) != 7)
{
return false;
}
return true;
}
BSNode* InsertBST(BSNode *root, CPhone *data)
{
if (root == NULL)
{
root = new BSNode(data, NULL, NULL);
return root;
}
BSNode *tree = root;
BSNode *father;
int lorr = 0;
while (root != NULL)
{
if (data->phoneNumber < root->data->phoneNumber)
{
father = root;
root = root->lchild;
lorr = 1;
}
else if (data->phoneNumber > root->data->phoneNumber)
{
father = root;
root = root->rchild;
lorr = 2;
}
else
{
root->data->count++;
return tree;
}
}
root = new BSNode(data, NULL, NULL);
if (lorr == 1)
{
father->lchild = root;
}
else if (lorr == 2)
{
father->rchild = root;
}
return tree;
}
void standOutput(CPhone *phone) // 讨厌的题目,还要在电话上补上一横
{
long pn = phone->phoneNumber;
char temp[9];
temp[8] = 0;
int i, j = 7;
for (i = 0; i < 4; i++, j--)
{
temp[j] = pn%10 + '0';
pn /= 10;
}
temp[j--] = '-';
for (i = 0; i < 3; i++, j--)
{
temp[j] = pn%10 + '0';
pn /= 10;
}
cout << temp << ' ' << phone->count << endl;
}
void InorderOutput(BSNode *root)
{
BSNode *s[STACK_MAX];
int top = -1;
bool duplicate = false;
while (root != NULL || top != -1)
{
while (root != NULL)
{
s[++top] = root;
root = root->lchild;
}
if (top != -1)
{
root = s[top--];
if (root->data->count > 1)
{
standOutput(root->data);
duplicate = true;
}
root = root->rchild;
}
}
if (duplicate == false)
{
cout << "No duplicates." << endl;
}
}
struct stack
{
BSNode *ptr;
int flag;
};
void DeleteTree(BSNode *root)
{
int top = -1;
stack s[STACK_MAX];
while(root != NULL || top != -1)
{
while (root != NULL)
{
top++;
s[top].ptr = root;
s[top].flag = 1;
root = root->lchild;
}
while (top != -1 && s[top].flag == 2)
{
root = s[top--].ptr;
delete root->data;
delete root;
root = NULL;
}
if (top != -1)
{
s[top].flag = 2;
root = s[top].ptr->rchild;
}
}
}
int main()
{
int total;
cin >> total;
char strTemp[STR_MAX];
CPhone *phone = NULL;
BSNode *tree = NULL;
for (int i = 0; i < total;i++)
{
cin >> strTemp;
if (testPhoneNumber(strTemp))
{
phone = new CPhone(strTemp);
tree = InsertBST(tree, phone);
}
}
InorderOutput(tree);
DeleteTree(tree);
return 0;
}
代码也要注意个问题:
几乎所有的数据结构的书上写的都是伪代,而且特别像正儿八经的代码。对于InsertBST(BSNode *, CPhone *data),如果在书上都是void型的返回值。这里如果是void时,main函数的tree永远也不会变,仍然是NULL,这个是由于C++的值传递特性决定的。所以要注意一下