總時間限制:1000ms 記憶體限制: 131072kb
描述 現在已經對一些文件求出了倒排索引,對於一些詞得出了這些詞在哪些文件中出現的列表。
要求對於倒排索引實現一些簡單的查詢,即查詢某些詞同時出現,或者有些詞出現有些詞不出現的文件有哪些。
輸入 第一行包含乙個數n,1 <= n <= 100,表示倒排索引表的數目。
接下來n行,每行第乙個數ci,表示這個詞出現在了多少個文件中。接下來跟著ci個數,表示出現在的文件編號,編號不一定有序。1 <= ci <= 1000,文件編號為32位整數。
接下來一行包含乙個數m,1 <= m <= 100,表示查詢的數目。
接下來m行每行n個數,每個數表示這個詞要不要出現,1表示出現,-1表示不出現,0表示無所謂。資料保證每行至少出現乙個1。
輸出 共m行,每行對應乙個查詢。輸出查詢到的文件編號,按照編號公升序輸出。
如果查不到任何文件,輸出」not found」。
樣例輸入
3
3 1 2 3
1 21 3
31 1 1
1 -1 0
1 -1 -1
樣例輸出
not found
1 31
思路 1
對應每個單詞 維護乙個文章set集合
n = int(input())
info = dict((i,set()) for i in range(n))
for wordid, articles in info.items():
articles.update(input().split()[1:])
m = int(input())
for _ in range(m):
ans = none
for wordid, v in enumerate(input().split()):
if v == '1':
ans = ans.intersection(info[wordid]) if ans is
not none else info[wordid]
elif v == '-1'
and ans:
ans = [articleindex for articleindex in ans if articleindex not
in info[wordid]]
ifnot ans:
print("not found")
else:
ans = list(ans)
ans.sort()
print(" ".join(ans))
演算法
查 包含 第i 個單詞 和 第j 個單詞的集合
a = ai&aj
查 包含 第i個單詞 但 不包含第j 個單詞的集合
a = ai&(~aj)
解決問題:
10000個bit 和 文章編號articleid 對應關係;
用int map[10000]來儲存 map[i]=articleid ;
點陣圖的儲存;
char bit[n][10000/8]; // 第i個word的點陣圖 用10000/8個位元組表示 即bit[i];
位圖操作;
1、第i個單詞 出現在文件map[k]=articleid中, 對應位=1
*((int *)(bit[i])+k/intbl) |= 1<<(k%intbl); // eg k=32 32bit個一組 記憶體分布 00…00 00..01 00..00
2、&操作 以4個位元組=1個int型為基本單位進行求&;
for(k=0; k<10000/32; k++)
((int *)(bit[i])+k) & ((int *)(bit[j])+k)
**如下 記憶體 1632kb 時間 51ms
#include
#include
#define bytel (sizeof(byte))
#define intl (sizeof(int))
#define intbl (intl*bytel)
#define n 100
#define an (intbl*1000) // 文章數量 intbl的倍數 方便後續處理
char bit[n][an/bytel];
intmap[an]; // 儲存文章編號-索引對映; 把文章編號對映為0-an的索引編號
int ansord[an]; // 有序答案
/** 列印 位址p 長度為length*8 的記憶體中的 bit值
*/int pp(char *p, int length)
printf(" ");
}printf("\n");
}// 把文章編存放到map中 保證map的長度》=文章數
int getid(int n)
map[i] = n;
return i; //返回對應的索引
}int test4193()
// pp(bit+i, an/bytel);
i++;
}// 判斷
scanf("%d", &m);
while(m--)
// 不包含; 取反後 求並集
else
if(k==-1) for(j=0; jint *)ans+j) &= ~ *((int *)(bit+i)+j); // ans &= ~ bit[i]}}
// 統計答案
u=-1;
// pp((char*)ans, sizeof(ans)); //顯示記憶體bit值
for(i=0, p=(int *)ans; ifor(j=0;j//對每一位遍歷
ansord[k+1]=v;
u++;}}
}// 列印答案
if(u==-1)
else
}}
倒排索引 和 倒排表
為什麼我們要說倒排索引呢?因為倒排索引是目前 搜尋引擎公司最對搜尋引擎最常用的儲存方式.也是搜尋引擎的核心內容 在搜尋引擎實際的引用之中,有時需要按照關鍵字的某些值查詢記錄,所以我們是按照關鍵字建立索引,這個索引我們就稱之為 倒排索引,而帶有倒排索引的檔案我們又稱作 倒排索引檔案也可以叫它為 倒排檔...
倒排索引 Inverted Index
倒排索引 英語 inverted index 也常被稱為反向索引 置入檔案或反向檔案,是一種索引方法,被用來儲存在全文搜尋下某個單詞在乙個文件或者一組文件中的儲存位置的對映。它是文件檢索系統中最常用的資料結構。有兩種不同的反向索引形式 以英文為例,下面是要被索引的文字 我們就能得到下面的反向檔案索引...
1 倒排索引
總時間限制 1000ms 記憶體限制 131072kb 描述 給定一些文件,要求求出某些單詞的倒排表。對於乙個單詞,它的倒排表的內容為出現這個單詞的文件編號。輸入第一行包含乙個數n,1 n 1000,表示文件數。接下來n行,每行第乙個數c i,表示第i個文件的單詞數。接下來跟著c i個用空格隔開的單...