蓝胖子教编程 2024-08-09 20:20 采纳率: 0%
浏览 11

[CSP-J 2021] 网络连接求调,细节问题

求调
[CSP-J 2021] 网络连接 - 洛谷
测试点对错情况

#include<bits/stdc++.h>
using namespace std;
int n,cnt;
struct internet
{
    string op,ad;
    int num;//这台机器的编号 
    internet(string _op,string _ad,int _num):op(_op),ad(_ad),num(_num){}
    internet(){}
    friend bool check(internet x)//检查地址是否合法 
    {
        //储存当前数字,地址内有.或:的个数,当前数字的长度(不含前导0) 
        long long num=0,point_cnt=0,num_len=0;
        bool is_front_zero=0;//存储是否有前导零 
        for(int i=0;i<x.ad.length();i++)//遍历地址 
        {
            char tmp=x.ad[i];//存储当前字符 
            if(tmp>='0'&&tmp<='9')//如果是数字
                if(num_len==0&&tmp=='0')//如果有前导零 
                {
                    is_front_zero=1;
                    num_len++;
                }
                else//否则就更新这个数字 
                {
                    num=num*10+(tmp-'0');
                    num_len++;
                }
            else if(tmp=='.')//如果遇到了. 
            {
                point_cnt++;
                if(point_cnt>3)//.最多有3个 
                    return 0;
                if(!(num>=0&&num<=255))//如果数字大小不合法 
                    return 0;
                if(is_front_zero&&num_len>1)//如果有前导零 
                    return 0;
                if(num_len<=0)//如果没有数字 
                    return 0;
                num=0;
                num_len=0;
                is_front_zero=0;
            }
            else if(tmp==':')//如果遇到了:
            {
                point_cnt++;
                if(point_cnt!=4)//:只能是第四个 
                    return 0;
                if(!(num>=0&&num<=255))//如果数字大小不合法
                    return 0;
                if(is_front_zero&&num_len>1)//如果有前导零
                    return 0;
                if(num_len<=0)//如果没有数字 
                    return 0;
                num=0;
                num_len=0;
                is_front_zero=0;
            }
        }
        if(!(num>=0&&num<=65535))//判断最后一个数字 
            return 0;
        if(is_front_zero&&num_len>1)//是否有前导零 
            return 0;
        if(point_cnt==4&&num_len>0)//是否刚好有四个符号且有数字 
            return 1;
    }
}a[10010];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        string op,ad;
        cin>>op>>ad;
        internet m=internet(op,ad,i);
        if(!check(m))//先判断是否合法 
        {
            cout<<"ERR"<<endl;
            continue;
        }
        if(m.op=="Server")//如果是服务机 
        {
            bool flag=0;
            for(int j=1;j<=cnt;j++)
                if(a[j].ad==m.ad)
                {
                    cout<<"FAIL"<<endl;
                    flag=1;
                    break;
                }
            if(!flag)
            {
                a[++cnt]=m;
                cout<<"OK"<<endl;
            }
        }
        else//否则就是客户机 
        {
            bool flag=0;
            for(int j=1;j<=cnt;j++)
                if(a[j].ad==m.ad)
                {
                    cout<<a[j].num<<endl;
                    flag=1;
                    break;
                }
            if(!flag)
                cout<<"FAIL"<<endl;
        }
    }
    return 0;
}
  • 写回答

1条回答 默认 最新

  • 清水白石008 2024-08-11 18:24
    关注
    🕒下午好,题主!目前:🟢[在线]
    📢参考GPT-4o mini 模型、由清水白石008整理提供!
    📣今日金句:人必須相信自己,這是成功的秘訣。
    

    在你提供的代码中,主要实现了一个简单的网络连接管理系统,支持对服务器和客户端的地址合法性检查以及连接状态的管理。以下是对代码的详细分析和一些可能的改进建议。

    代码分析

    1. 数据结构

      • internet 结构体用于存储网络设备的信息,包括操作类型(op)、地址(ad)和编号(num)。
      • check 函数用于验证地址的合法性,支持 IPv4 和 IPv6 地址的基本格式检查。
    2. 地址合法性检查

      • 对于 IPv4 地址,检查点的数量、每个数字的范围(0-255)以及前导零的情况。
      • 对于 IPv6 地址,检查冒号的数量和最后一个数字的范围(0-65535)。
    3. 主函数逻辑

      • 读取输入的操作和地址。
      • 调用 check 函数验证地址是否合法。
      • 如果是服务器操作,检查地址是否已存在,若不存在则添加并返回 "OK",否则返回 "FAIL"。
      • 如果是客户端操作,检查地址是否存在于已注册的服务器中,若存在则返回服务器编号,否则返回 "FAIL"。

    可能的问题和改进建议

    1. 地址合法性检查

      • 目前的 check 函数只返回了合法性检查的结果,但没有处理 IPv6 地址的具体格式。需要进一步完善对 IPv6 地址的检查逻辑。
      • 对于 IPv4 地址,最后一个数字的检查应该在 point_cnt 为 4 的情况下进行。
    2. 内存管理

      • 代码中使用了固定大小的数组 a[10010],在实际应用中可能会导致内存浪费或溢出。可以考虑使用动态数组(如 std::vector)来管理服务器列表。
    3. 代码可读性

      • 可以将 check 函数中的逻辑拆分成多个小函数,以提高可读性和可维护性。
    4. 错误处理

      • 在输入时,如果输入格式不正确,可能会导致程序崩溃。可以添加更多的错误处理逻辑来确保程序的健壮性。
    5. 输出格式

      • 输出的格式可以根据具体需求进行调整,例如在输出 "ERR"、"FAIL" 和 "OK" 时,可以考虑添加更多的上下文信息。

    改进后的代码示例

    以下是对原代码的一些改进示例:

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Internet {
        string op, ad;
        int num; // 这台机器的编号
        Internet(string _op, string _ad, int _num) : op(_op), ad(_ad), num(_num) {}
        Internet() {}
    };
    
    bool check(const string& ad) {
        // 检查地址是否合法
        // 这里可以添加对 IPv6 的检查逻辑
        long long num = 0, point_cnt = 0, num_len = 0;
        bool is_front_zero = false;
    
        for (char tmp : ad) {
            if (isdigit(tmp)) {
                if (num_len == 0 && tmp == '0') {
                    is_front_zero = true;
                    num_len++;
                } else {
                    num = num * 10 + (tmp - '0');
                    num_len++;
                }
            } else if (tmp == '.') {
                point_cnt++;
                if (point_cnt > 3 || !(num >= 0 && num <= 255) || (is_front_zero && num_len > 1) || num_len <= 0) {
                    return false;
                }
                num = 0;
                num_len = 0;
                is_front_zero = false;
            }
        }
        return point_cnt == 3 && num >= 0 && num <= 255;
    }
    
    int main() {
        int n, cnt = 0;
        vector<Internet> a(10010); // 使用动态数组
        cin >> n;
    
        for (int i = 1; i <= n; i++) {
            string op, ad;
            cin >> op >> ad;
            Internet m(op, ad, i);
    
            if (!check(m.ad)) {
                cout << "ERR" << endl;
                continue;
            }
    
            if (m.op == "Server") {
                bool flag = false;
                for (int j = 1; j <= cnt; j++) {
                    if (a[j].ad == m.ad) {
                        cout << "FAIL" << endl;
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    a[++cnt] = m;
                    cout << "OK" << endl;
                }
            } else { // 客户机
                bool flag = false;
                for (int j = 1; j <= cnt; j++) {
                    if (a[j].ad == m.ad) {
                        cout << a[j].num << endl;
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    cout << "FAIL" << endl;
                }
            }
        }
        return 0;
    }
    

    总结

    以上是对你提供的代码的分析和改进建议。希望这些信息能帮助你更好地理解代码的逻辑和实现。如果你有其他问题或需要进一步的帮助,请随时提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 8月9日