構(gòu)建動(dòng)物識(shí)別系統(tǒng)系統(tǒng)分為兩部分,第一部分是初始化綜合數(shù)據(jù)庫(kù),分為兩類,一類是間接數(shù)據(jù)庫(kù),即不指向最終動(dòng)物的信息。另一類是直接數(shù)據(jù)庫(kù),即指向最終動(dòng)物的信息。使用的是二維列表加上一個(gè)一維列表存儲(chǔ)key與value。第二部分為添加數(shù)據(jù)庫(kù)和識(shí)別動(dòng)物,查詢的時(shí)候添加,可以有效的擴(kuò)增數(shù)據(jù)庫(kù),使功能更靈活與完善。在識(shí)別動(dòng)物的時(shí)候,先在間接數(shù)據(jù)庫(kù)中完善信息,在直接數(shù)據(jù)庫(kù)中查找對(duì)應(yīng)的動(dòng)物,記錄信息時(shí),使用字典記錄某個(gè)特征是否出現(xiàn),這樣查詢的復(fù)雜度就為O(1)。(這一段為老師所給提示) 思路:1、我選擇構(gòu)建直接、間接數(shù)據(jù)庫(kù)的方式為將條件存入列表中,列表中的元素都有對(duì)應(yīng)的下標(biāo),將下標(biāo)作為字典的值、結(jié)果作為字典的鍵構(gòu)成數(shù)據(jù)庫(kù),這樣條件和結(jié)果就能構(gòu)成呢個(gè)一一對(duì)應(yīng)的關(guān)系。因此程序中的數(shù)據(jù)庫(kù)是包括列表、字典兩部分的。 eg: 間接庫(kù)列表:奶 哺乳動(dòng)物+蹄 羽毛 間接庫(kù)字典:哺乳動(dòng)物->0 蹄類動(dòng)物->1 鳥(niǎo)->2 2、識(shí)別動(dòng)物的時(shí)候,先在間接庫(kù)中進(jìn)行推理,再在直接庫(kù)中推理。 Indirdict=dict()#間接庫(kù)字典,用于從數(shù)字尋找對(duì)應(yīng)結(jié)果
Dirdict=dict()#直接庫(kù)字典,用于從數(shù)字尋找對(duì)應(yīng)結(jié)果
Indirlist=[]#間接庫(kù)列表,用于存放動(dòng)物特征的集合和定義、存放這個(gè)集合對(duì)應(yīng)數(shù)字
Dirlist=[]#直接庫(kù)列表,用于存放動(dòng)物特征的集合和定義、存放這個(gè)集合對(duì)應(yīng)數(shù)字
Indirnum=0#作為間接庫(kù)字典的值
Dirnum=0#作為直接庫(kù)字典的值
def change(str):#以字符串的形式輸入全部特征值,這個(gè)函數(shù)可以將字符串中的特征值識(shí)
#別出來(lái),并且將所有特征值存放到一個(gè)集合中
set1=set()#定義一個(gè)集合,存放特征值
str1=""
for i in range(0,len(str)):
if(str[i]!=" "):
str1+=str[i]
else:
set1.add(str1)
str1=""
i+=1
return set1
list1=[]#定義一個(gè)臨時(shí)列表,表示間接庫(kù)或直接庫(kù)
dict1=dict()#定義一個(gè)臨時(shí)字典,表示間接庫(kù)字典或直接庫(kù)字典
num1=0
def Builddata(list1,dict1,num1):#num1存放在字典中,與結(jié)果相對(duì)應(yīng)
str2=input("請(qǐng)輸入條件,以空格隔開(kāi):")#定義一個(gè)字符串,存放用戶輸入特征值
str2+=" "
while(str2!="0 "):
str3=input("請(qǐng)輸入結(jié)果:")#字符串,存放結(jié)果
dict1[num1]=str3#將值與結(jié)果在字典中相對(duì)應(yīng)
set2=change(str2)#集合,將用戶輸入特征值放入此集合內(nèi)
list1.append(set2)#將特征值集合存入列表
str2=input("請(qǐng)輸入條件,以空格隔開(kāi):")
str2+=" "
num1+=1
return num1
def Infer(animalset,list1,dict1):#推理函數(shù),將動(dòng)物條件的集合放在間接庫(kù)或直接庫(kù)中進(jìn)行匹配
for i in range(0,len(animalset)):#保證循環(huán)足夠多的次數(shù)
for j in range(0,(len(list1))):
if(list1[j].issubset(animalset) or list1[j]==animalset):
animalset.add(dict1[j])
#print(list1[j])
animalset=animalset-list1[j]
return animalset
def Rec():#識(shí)別動(dòng)物
feature=input("請(qǐng)輸入動(dòng)物的特征(不同特征之間用空格隔開(kāi)):")
feature+=" "
animalset=change(feature)
#將動(dòng)物的特征化為關(guān)鍵詞的集合
animalset=Infer(animalset,Indirlist,Indirdict)
set3=Infer(animalset,Dirlist,Dirdict)#返回經(jīng)過(guò)直接規(guī)則庫(kù)過(guò)濾后的集合
list2=list(set3)#將動(dòng)物特征集合化為列表,便于確定最后剩下多少特征值
if(len(list2)==1):
print("這個(gè)動(dòng)物是:"+list2[0])
else:
print("查無(wú)此動(dòng)物")
print("請(qǐng)輸入接下來(lái)操作(1.添加間接數(shù)據(jù)庫(kù) 2.添加直接數(shù)據(jù)庫(kù) 3.查詢動(dòng)物 0.結(jié)束操作):")
chose = input()
while (chose!='0'):
if (chose=='1'):
print("構(gòu)造間接數(shù)據(jù)庫(kù):(輸入條件時(shí)輸入0結(jié)束構(gòu)建)")
Indirnum=Builddata(Indirlist,Indirdict,Indirnum)
print("間接數(shù)據(jù)庫(kù)構(gòu)造完成!")
print("")
chose = input("請(qǐng)輸入接下來(lái)操作(1.添加間接數(shù)據(jù)庫(kù) 2.添加直接數(shù)據(jù)庫(kù) 3.查詢動(dòng)物 0.結(jié)束操作):")
elif (chose=='2'):
print("構(gòu)造直接數(shù)據(jù)庫(kù):(輸入條件時(shí)輸入0結(jié)束構(gòu)建)")
Dirnum=Builddata(Dirlist,Dirdict,Dirnum)
print("直接數(shù)據(jù)庫(kù)構(gòu)造完成!")
print("")
chose = input("請(qǐng)輸入接下來(lái)操作(1.添加間接數(shù)據(jù)庫(kù) 2.添加直接數(shù)據(jù)庫(kù) 3.查詢動(dòng)物 0.結(jié)束操作):")
elif (chose=='3'):
Rec()
print("")
chose = input("請(qǐng)輸入接下來(lái)操作(1.添加間接數(shù)據(jù)庫(kù) 2.添加直接數(shù)據(jù)庫(kù) 3.查詢動(dòng)物 0.結(jié)束操作):")
else:
print("輸入不合法,請(qǐng)重新輸入")
chose = input("請(qǐng)輸入接下來(lái)操作(1.添加間接數(shù)據(jù)庫(kù) 2.添加直接數(shù)據(jù)庫(kù) 3.查詢動(dòng)物 0.結(jié)束操作):")注:輸入條件、結(jié)果時(shí),構(gòu)建間接規(guī)則庫(kù)、構(gòu)建直接規(guī)則庫(kù)、查詢動(dòng)物時(shí)輸入形式、相同的內(nèi)容必須保持一致。 此文是借鑒大佬博客https://blog.csdn.net/weixin_46178977/article/details/105842471,是對(duì)大佬代碼的拙劣優(yōu)化。。 能夠搞懂并改寫這樣的一個(gè)不很簡(jiǎn)單的程序,也算是對(duì)大一身為python小小白的我一個(gè)交代了吧。。 |
|
|