第二次寒假作业 二更

第二次寒假作业 二更

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),看同学的作业了解到还能够利用某些算法降低时间复杂度。容我好好学习一番。

posted @ 2022-01-31 10:14  Knigh7_de_Ficusé  阅读(36)  评论(0编辑  收藏  举报