代码写得好丑,没有数据不知道怎么调...
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
// P7911
// 模拟TCP/IP协议
struct Computer
{
string name; // 种类
string address; // 地址
int id; // 编号
bool state_name; // 状态,true为服务机,false为客户机
bool state_address; // 状态,true为有效,false为无效
};
string tt[5]; // 暂存分割的地址串
vector<string> mp; // 服务机地址表
int n;
void computer_name(Computer &computer) // true为服务机,false为客户机
{
if (computer.name == "Server")
computer.state_name = true;
else
computer.state_name = false;
}
bool hasAddressZero(const string &port_address) // 地址前导零
{
if (port_address.empty())
return false;
if (port_address.size() > 1 && port_address[0] == '0')
return false;
try
{
unsigned long long number = stoul(port_address);
return 0 <= number && number <= 255;
}
catch (exception &e)
{
return false; // 如果转换失败,表示数字不合法
}
}
bool hasPortZero(const string &port) // 端口前导零
{
if (port.empty() || port.size() > 5)
return false;
if (port[0] == '0' && port.size() > 1)
return false;
try
{
unsigned long long p = stoul(port);
return p >= 0 && p <= 65535;
}
catch (exception &e)
{
return false; // 如果转换失败,则端口无效
}
}
void fengedizhichuan(Computer &computer) // 分割地址并检查格式
{
fill(tt, tt + 5, "");
int tag = 0;
int len = computer.address.size();
// 查找 ':' 的位置,确保它在地址部分之后
size_t colon_pos = computer.address.find(':');
if (colon_pos == string::npos || colon_pos == len - 1) // 没有 ':' 或 ':' 在末尾
{
computer.state_address = false;
return;
}
// 分割IP部分和端口部分
string ip = computer.address.substr(0, colon_pos);
string port = computer.address.substr(colon_pos + 1);
// 进行分割,按 '.' 进行
stringstream ss(ip);
string token;
while (getline(ss, token, '.'))
{
if (tag < 4) // 限制只能有 4 个 IP 部分
tt[tag++] = token;
}
// 如果IP部分不是4部分,或者地址部分有无效部分,返回错误
if (tag != 4 || !hasAddressZero(tt[0]) || !hasAddressZero(tt[1]) || !hasAddressZero(tt[2]) || !hasAddressZero(tt[3]) || !hasPortZero(port))
{
computer.state_address = false;
}
else
{
computer.state_address = true;
}
}
bool isAddress_Service(Computer &computer) // 判断服务机地址串正确性
{
fengedizhichuan(computer);
return computer.state_address;
}
bool isAddress_Client(Computer &computer) // 判断客户机地址串正确性
{
fengedizhichuan(computer);
return computer.state_address;
}
bool isAddressUsed(const Computer &computer) // 查找地址表
{
return find(mp.begin(), mp.end(), computer.address) != mp.end();
}
int main()
{
IOS;
cin >> n;
Computer computer[1005];
for (int i = 0; i < n; i++)
{
cin >> computer[i].name >> computer[i].address;
computer[i].id = i + 1;
computer_name(computer[i]);
}
for (int i = 0; i < n; i++)
{
if (computer[i].state_name == true) // 服务机
{
if (isAddress_Service(computer[i])) // 地址有效
{
if (isAddressUsed(computer[i])) // 地址已经被使用过
{
cout << "FAIL" << endl; // 地址已被占用
}
else // 地址有效且未被占用
{
mp.push_back(computer[i].address); // 记录地址
cout << "OK" << endl; // 成功建立连接
}
}
else // 地址无效
{
cout << "ERR" << endl;
}
}
else if (computer[i].state_name == false) // 客户机
{
if (isAddress_Client(computer[i])) // 地址有效
{
if (isAddressUsed(computer[i])) // 地址对应的服务机存在
{
for (int j = 0; j < n; j++) // 输出连接的服务机 ID
{
if (computer[j].address == computer[i].address && computer[j].state_name == true)
{
cout << computer[j].id << endl;
break;
}
}
}
else // 地址有效,但没有对应的服务机
{
cout << "FAIL" << endl;
}
}
else // 地址无效
{
cout << "ERR" << endl;
}
}
}
return 0;
}
// 判断computer是客户机还是服务机
/// 服务机
//// 地址串正确 && 建立连接--OK
//// 地址串正确 && 未建立连接(先前有相同地址串的服务机)--FALL
//// 地址串错误--ERR
/// 客户机
//// 地址串正确 && 建立连接--输出连接到的服务机编号
//// 地址串正确 && 未建立连接(先前有相同地址串的服务机)--FALL
//// 地址串错误--ERR
// 判断地址串正确性
/// 不含前导零
/// 0 <= a,b,c,d <= 255 0 <= e <= 65535
// 地址串不可重复使用,需要标记,
//
//