PKU 1002 487-3279 问题的解决

来源:互联网 发布:网络鸡肋什么意思 编辑:程序博客网 时间:2024/05/16 01:07

题目不多说了,见如下连接:

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++的值传递特性决定的。所以要注意一下

原创粉丝点击