第二次寒假作业 二更
第二次寒假作业 二更
Part#1 成果
#include<iostream>
#include<math.h>
#include<fstream>
using namespace std;
int i;
struct dataset
{
long long ipin,ipout;
long ptin,ptout;
int ptcl=256;
}dt[10001];
struct ruleset
{
int iip[5],oip[5];
long long ipin,ipout;
int smin,smout;
int ptinlow,ptinup,ptoutlow,ptoutup;
char ptcl[10]={};
int ptclmode,ptcll=256;
}rl[10001];
long long iptrans(int *ip)
{
long long tmp=0,result=0;
int a[4];
a[0]=ip[0];a[1]=ip[1];a[2]=ip[2];a[3]=ip[3];
for(int i=3;i>=0;i--)
{
tmp=0;
for(int j=0;a[i]!=0;j++)
{
tmp+=((a[i]%2)*pow(10,j));
a[i]/=2;
}
for(int j=0;tmp!=0;j++)
{
result+=(tmp%10)*pow(2,j+(i*8));
tmp/=10;
}
}
return result;
}
long findrule(long n)
{
for(long k=0;k<i;k++)
{
if(dt[n].ipin==rl[k].ipin&&dt[n].ipout==rl[k].ipout)
{
if(dt[n].ptin<=rl[k].ptinup&&dt[n].ptin>=rl[k].ptinlow&&dt[n].ptout<=rl[k].ptoutup&&dt[n].ptout>=rl[k].ptoutlow)
{
if(dt[n].ptcl==rl[k].ptcll||rl[k].ptclmode==1)
{
return k;
}
}
}
}
return -1;
}
int main()
{
char tmp;
fstream fin("rule.txt");
for(i=0;!fin.eof();i++)
{
fin>>tmp>> rl[i].iip[3]>>tmp>>rl[i].iip[2]>>tmp>>rl[i].iip[1]>>tmp>>rl[i].iip[0]>>tmp>>rl[i].smin;
fin>> rl[i].oip[3]>>tmp>>rl[i].oip[2]>>tmp>>rl[i].oip[1]>>tmp>>rl[i].oip[0]>>tmp>>rl[i].smout;
fin>>rl[i].ptinlow>>tmp>>rl[i].ptinup>>rl[i].ptoutlow>>tmp>>rl[i].ptoutup;
rl[i].ipin =iptrans(rl[i].iip);
rl[i].ipout =iptrans(rl[i].oip);
if(rl[i].ptcl[2]=='F'&&rl[i].ptcl[3]=='F')
{
rl[i].ptclmode=0;
rl[i].ptcll=(((int)rl[i].ptcl[0])-48)*10+((int)rl[i].ptcl[1])-48;
}
else if(rl[i].ptcl[2]=='0'&&rl[i].ptcl[3]=='0')
{
rl[i].ptclmode=1;
}
}
ifstream dfin("packet.txt");
fstream fout("ans.txt");
for(long j=0;;j++)
{
dfin>>dt[j].ipin>>dt[j].ipout>>dt[j].ptin>>dt[j].ptout>>dt[j].ptcl;
if(dt[j].ptcl==256)
{
break;
}
else
{
fout<<findrule(j)<<endl;
}
}
return 0;
}
我终于成功写出了一个可以正常使用的代码了。
代码量甚至还没有100行嘿嘿~
不过,在9191条数据中,只有8201条数据是对的(多次测试过后,正确数据总是8201)。正确率是89.2%。错误大多是判断函数返回了“-1”(正确答案里面是没有“-1”的!),偶尔出现找到匹配但不是最佳匹配的情况。
在单独测试那些出现错误的数据的时候,程序又能够输出9成正确的答案。说明不是判断的问题而又双叒叕是输入的问题,还没找到原因和解决办法。
Part#2 复盘
上一次出错的地方是fin.get(rl[i].ptcl,10,'\n');
于是我这次将这一句改回了基本的fin
语句:fin>>tmp>>tmp>>rl[i].ptcl[0]>>rl[i].ptcl[1]>>tmp>>tmp>>tmp>>rl[i].ptcl[2]>>rl[i].ptcl[3];
但是问题随之而来:fin.eof()
没有正确运行,打开有9191行的数据集时读入了9192行。
我的解决办法是:既然协议号从0~255,那么为每一条数据的协议号赋初值256,当正常读入时覆盖初值,不正常读入时不覆盖('\0'不会覆盖)。这样就能确定要不要对这条数据进行判断和输出。
另外,我将判断的代码做成了一个单独的函数findrule(j)
以返回第j条数据的最佳匹配。
Part#3 还可以改进的地方
可以只定义数据集的其中一行,每次读入一行的时候覆盖前一行的内容,读完数据即时判断和输出最佳匹配。可以大幅减少内存消耗。
另外,我的判断算法比较暴力,理论时间复杂度也是σ(n^2),看同学的作业了解到还能够利用某些算法降低时间复杂度。容我好好学习一番。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?