Untitled
unknown
plain_text
2 years ago
2.9 kB
4
Indexable
#include <string> #include <unordered_map> #include <vector> #define MAXL (11) #define SIZE 50000 #define HASH_SIZE 75007 using namespace std; struct Species{ int id; int rank; int child[5]; int prev; //vector<int> next; Species(){ rank = -1; for(int i = 0; i < 5; i++){ child[i] = 0; } prev = -1; //next.resize(0); } } data[SIZE]; unordered_map<string, int> hashTable; int index; //int hashKey(char* str){ // int index = 0; // while(*str != 0){ // index = (index*31 + *str) % HASH_SIZE; // *str++; // } // // return index; //} void init(char mRootSpecies[MAXL]) { index = 0; hashTable = unordered_map<string, int>(); for(int i = 0; i < SIZE; i++){ data[i] = Species(); } data[index].rank = 0; hashTable[ mRootSpecies] = index; } void add(char mSpecies[MAXL], char mParentSpecies[MAXL]) { index++; hashTable[mSpecies] = index; int idP = hashTable[mParentSpecies]; data[index].rank = data[idP].rank + 1; data[index].prev = idP; //hashTable[idP].next.push_back(id); int tmpParent = index; for(int i = 1; i <= 4; i++){ tmpParent = data[tmpParent].prev; if(tmpParent == -1) break; data[tmpParent].child[i]++; } } int findParent(int id1, int id2) { if(id1 == id2) return id1; if(data[id1].prev == data[id2].prev){ return data[id1].prev; } if(data[id1].rank > data[id2].rank){ return findParent(data[id1].prev, id2); } if(data[id1].rank < data[id2].rank){ return findParent(id1, data[id2].prev); } return findParent(data[id1].prev, data[id2].prev); } int getDistance(char mSpecies1[MAXL], char mSpecies2[MAXL]) { int cnt = 0; int id1 = hashTable[mSpecies1]; int id2 = hashTable[mSpecies2]; if(data[id1].rank == 0) return data[id2].rank; if(data[id2].rank == 0) return data[id1].rank; int idP = findParent(id1, id2); cnt = data[id1].rank - data[idP].rank + data[id2].rank - data[idP].rank; return cnt; } int getCount(char mSpecies[MAXL], int mDistance) { int id = hashTable[mSpecies]; int cnt =data[id].child[mDistance]; if(data[id].rank == 0) return cnt; int curId = id; int prevId; int needCnt; for(int i = 1; i <= mDistance; i++){ if(data[curId].rank == 0) break; prevId = data[curId].prev; needCnt = mDistance - i; if(needCnt == 0) cnt++; else if(needCnt == 1){ cnt += data[prevId].child[needCnt] - 1; } else{ cnt += data[prevId].child[needCnt] - data[curId].child[needCnt-1]; } curId = prevId; } return cnt; }
Editor is loading...