提交记录 14736
提交时间 |
评测时间 |
2020-11-03 22:05:37 |
2020-11-03 22:05:39 |
#include "router.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <list>
using namespace std;
/*
RoutingTable Entry 的定义如下:
typedef struct {
uint32_t addr; // 大端序,IPv4 地址
uint32_t len; // 小端序,前缀长度
uint32_t if_index; // 小端序,出端口编号
uint32_t nexthop; // 大端序,下一跳的 IPv4 地址
} RoutingTableEntry;
约定 addr 和 nexthop 以 **大端序** 存储。
这意味着 1.2.3.4 对应 0x04030201 而不是 0x01020304。
保证 addr 仅最低 len 位可能出现非零。
当 nexthop 为零时这是一条直连路由。
你可以在全局变量中把路由表以一定的数据结构格式保存下来。
*/
//binary tree
struct node{
bool isleaf;
unsigned nexthop;
node* child[2];
uint8_t pos;
static unsigned q_ans;
static bool has_found;
node(int pos){
this->pos = pos;
child[0] = child[1] = NULL;
isleaf = false;
}
void insert(int p,RoutingTableEntry*& e){
if(this->pos == e->len){
this->nexthop = e->nexthop;
isleaf = true;
return;
}
if(p > 32){
return;
}
else{
if(e->addr & (0x80000000 >> p)){
if(!child[1]){
child[1] = new node(p+1);
}
child[1]->insert(p+1,e);
}
else{
if(!child[0]){
child[0] = new node(p+1);
}
child[0]->insert(p+1,e);
}
}
}
bool del(int p,RoutingTableEntry*& entry){
return false;
}
void query(int pos,uint32_t addr){
if(this->isleaf){
node::q_ans = this->nexthop;
node::has_found = true;
}
unsigned a = addr & (0x80000000 >> pos);
if(pos > 32){
return;
}
else{
if(a != 0 && child[1]){
child[1]->query(pos+1,addr);
}
else if( a == 0 && child[0]){
child[0]->query(pos+1,addr);
}
}
}
};
unsigned node::q_ans = 0;
bool node::has_found = false;
node* root = new node(0);
/**
* @brief 插入/删除一条路由表表项
* @param insert 如果要插入则为 true ,要删除则为 false
* @param entry 要插入/删除的表项
*
* 插入时如果已经存在一条 addr 和 len 都相同的表项,则替换掉原有的。this
// TODO:
*/
void update(bool insert,RoutingTableEntry entry){
//int addr = ((entry.addr & 0xff) << 24) | ((entry.addr & 0xff00) << 8) | ((entry.addr & 0xff0000) >> 8) | ((entry.addr&0xff000000) >> 24);
//printf("%x\n",addr);
RoutingTableEntry* tt = &entry;
tt->addr = htonl(tt->addr);
if (insert) {
root -> insert(0,tt);
}
else{
root -> del(0,tt);
}
}
/**
* @brief 进行一次路由表的查询,按照最长前缀匹配原则
* @param addr 需要查询的目标地址,大端序
* @param nexthop 如果查询到目标,把表项的 nexthop 写入
* @param if_index 如果查询到目标,把表项的 if_index 写入
* @return 查到则返回 true ,没查到则返回 false
*/
bool prefix_query(uint32_t addr, uint32_t *nexthop) {
// TODO:q_ans
*nexthop = 0;
node::q_ans = 0;
root->query(0,addr);
if(node::q_ans)
{
*nexthop = node::q_ans;
return true;
}
return false;
}
void init(int n, int q, const RoutingTableEntry *a) {
for (int i = 0; i < n; i++) {
update(true, a[i]);
}
}
unsigned query(unsigned addr) {
node::has_found = false;
addr = htonl(addr);
root->query(0,addr);
if (node::has_found)
return node::q_ans;
return 0;
}
Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
Testcase #1 | 12.44 us | 28 KB | Accepted | Score: 25 | 显示更多 |
Testcase #2 | 57.924 ms | 94 MB + 520 KB | Accepted | Score: 25 | 显示更多 |
Testcase #3 | 232.635 ms | 94 MB + 520 KB | Accepted | Score: 25 | 显示更多 |
Testcase #4 | 406.477 ms | 94 MB + 520 KB | Accepted | Score: 25 | 显示更多 |
Judge Duck Online | 评测鸭在线
Server Time: 2024-12-05 10:11:09 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠