• 11-散列3 QQ帐户的申请与登陆 (25 分)


    实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是:据说现在的QQ号码已经有10位数了。

    输入格式:

    输入首先给出一个正整数N(10^5​​),随后给出N行指令。每行指令的格式为:“命令符(空格)QQ号码(空格)密码”。其中命令符为“N”(代表New)时表示要新申请一个QQ号,后面是新帐户的号码和密码;命令符为“L”(代表Login)时表示是老帐户登陆,后面是登陆信息。QQ号码为一个不超过10位、但大于1000(据说QQ老总的号码是1001)的整数。密码为不小于6位、不超过16位、且不包含空格的字符串。

    输出格式:

    针对每条指令,给出相应的信息:

    1)若新申请帐户成功,则输出“New: OK”;
    2)若新申请的号码已经存在,则输出“ERROR: Exist”;
    3)若老帐户登陆成功,则输出“Login: OK”;
    4)若老帐户QQ号码不存在,则输出“ERROR: Not Exist”;
    5)若老帐户密码错误,则输出“ERROR: Wrong PW”。

    输入样例:

    5
    L 1234567890 myQQ@qq.com
    N 1234567890 myQQ@qq.com
    N 1234567890 myQQ@qq.com
    L 1234567890 myQQ@qq
    L 1234567890 myQQ@qq.com
    

    输出样例:

    ERROR: Not Exist
    New: OK
    ERROR: Exist
    ERROR: Wrong PW
    Login: OK

    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    
    map<string, string> mp;
    void Login(string account, string passwd); 
    void Create(string account, string passwd); 
    
    int main()
    {
        int n;
        char c;
        string account, passwd;
        
        cin >> n;
        for (int i = 0 ; i < n; i++)
        {
            getchar();
            cin >> c >> account >> passwd;
            switch (c)
            {
                case 'L':
                    Login(account, passwd);
                    break;
                case 'N':
                    Create(account, passwd);
                    break;
            }
        }
        
        return 0;
    }
    
    void Login(string account, string passwd)
    {
        if (mp.find(account) != mp.end())
        {
            if (passwd == mp[account])
            {
                cout << "Login: OK" << endl;
            }
            else
            {
                cout << "ERROR: Wrong PW" << endl;
            }
        }
        else
        {
            cout << "ERROR: Not Exist" << endl;
        }
    }
    
    void Create(string account, string passwd)
    {
        if (mp.find(account) != mp.end())
        {
            cout << "ERROR: Exist" << endl;
        }
        else
        {
            mp[account] = passwd;
            cout << "New: OK" << endl;
        }
    }

    map如果在栈中定义,地址作为函数参数传到函数中,函数中用map型指针接收的思路,还没有通过。

    用创建链表的方式代替map功能

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    const int maxn = 100010;
    
    typedef struct ListNode* Position;
    typedef struct Table* HashTable;
    
    struct ListNode
    {
        char account[15];
        char password[20];
        Position next;
    };
    
    struct Table
    {
        Position List;
        int TableSize;
    };
    
    HashTable createTable(int size);
    int NextPrime(int size);
    void Insert(HashTable H, char *account, char *password);
    Position Find(HashTable H, char *key);
    int Find_account(HashTable H, char *account);
    int check_password(Position P, char *password);
    void DestoryTable(HashTable H);
    
    int main()
    {
        int n;
        scanf("%d", &n);
        HashTable H = createTable(n * 2);
        
        char c;
        char account[15];
        char password[20];
        for (int i = 0; i < n; i++)
        {
            getchar();
            scanf("%c %s %s", &c, account, password);
            switch(c)
            {
                case 'N':
                    if (-1 == Find_account(H, account))
                    {
                        Insert(H, account, password);
                        printf("New: OK
    ");
                    }
                    else
                    {
                        printf("ERROR: Exist
    ");
                    }
                    break;
                case 'L':
                    if (1 == Find_account(H, account))
                    {
                        if (1 == check_password(Find(H, account), password))
                        {
                            printf("Login: OK
    ");
                        }
                        else
                        {
                            printf("ERROR: Wrong PW
    ");
                        }
                    }
                    else
                    {
                        printf("ERROR: Not Exist
    ");
                    }
                    break;
            }
        }
        //DestoryTable(H);
        return 0;
    }
    
    HashTable createTable(int size)
    {
        //在堆区申请一个Table大小的内存,转化成该结构体指针类型返回 
        HashTable H = (HashTable)malloc(sizeof (struct Table));
        H->TableSize = NextPrime(size);
        H->List = (Position)malloc(sizeof(struct ListNode) * H->TableSize);
        for (int i = 0 ; i < H->TableSize; i++)
        {
            H->List[i].next = NULL;
        }
        return H;
    }
    
    int NextPrime(int size)
    {
        for (int tmpSize = size; ; tmpSize++)
        {
            int i = 2;
            for ( ; i * i <= tmpSize; i++)
            {
                if (tmpSize % i == 0)
                {
                    break;
                }
            }
            
            if (i * i > tmpSize)
            {
                return tmpSize;
            }
        }
    }
    
    void Insert(HashTable H, char *account, char *password)
    {
        int h = atoi(account+3) % H->TableSize;
        
        /*Position P = H->List[h].next; 
        while(P && strcmp(P->account, account))
        {
            P = P->next;
        }*/
        Position P = Find(H, account);    
        if (P == NULL)    //头插法 
        {
            Position tmp = (Position)malloc(sizeof (struct ListNode));
            strcpy(tmp->account, account);
            strcpy(tmp->password, password);
            tmp->next = H->List[h].next;
            H->List[h].next = tmp;
        }
    }
    
    Position Find(HashTable H, char *key)
    {
        int h = atoi(key+3) % H->TableSize; 
        Position P = H->List[h].next;
        while( P != NULL && strcmp(P->account, key))
        {
            //节点存在,并且节点的账户不是传进来的key 
            P = P->next;
        }
        return P;
    }
    
    int Find_account(HashTable H, char *account)
    {
        Position P = Find(H, account);
        if (P)
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
    
    int check_password(Position P, char *password)
    {
        if (0 == strcmp(P->password, password))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    void DestoryTable(HashTable H)
    {
        for (int i = 0; i < H->TableSize; i++)
        {
            Position P = H->List[i].next;
            while (P)
            {
                Position tmp = P->next;
                free(P);
                P = tmp;
            }
        }
        free(H->List);
        free(H);
    }
  • 相关阅读:
    shell脚本修改文件
    腾讯企业邮箱获取客户端专用密码(授权码)
    java内存dump文件导出与查看
    为什么MySQL数据库索引选择使用B+树?
    nginx 平滑重启的实现方法
    nginx重启 平滑重启
    Nginx常用的平滑重启
    nginx reload和reopen
    转载【小程序】: 微信小程序开发---应用与页面的生命周期
    【微信小程序】用户首次进入小程序拒绝授权,如何再次调用授权页面,获取用户信息userInfo
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11963566.html
Copyright © 2020-2023  润新知