好像是一場夢

caihaozhe發表於2024-08-19

2024年8月19日更新:修正女主角有時候走路會抖動的問題,切換場景時,天色同步。
我不想和任何人說話,大家不要打擾我。
此頁面程式自動排版有問題,一些程式被移到程式框外面了。
下面一些內容會白屏幾秒鐘,可能因為程式框內容量太大,從載入第一個程式框那,就開始白屏了,圖片也要等一會才顯示。
這篇文章的主題:unity遊戲原始碼和教程:智慧分析話語的三維唯美世界。
遊戲開發語言:C#,資料庫:單機資料庫sqlite。

這個遊戲的原始碼(含教程文件)我放到了夸克網盤(連結於2024年8月19日更新):
https://pan.quark.cn/s/df8edccd4e7a

遊戲介面:
小區:

小區傍晚的雪:

小區的晚上:

家裡:

市中心:

市街道:

郊區:

2024年8月18日增加的場景:
學校:

走廊:

教室:

圖書館:

體育館:

食堂:

天色同步:從一個傳送點到下一個場景,天色保持不變。例如是晚上過去的,到下一個場景,還是晚上。

(一)宣告
小區場景的三維模型來自於UnityStore的unity包:Low Poly Japanese Housing Complex。很多人在用,所以我的遊戲和其他人的遊戲出現這個相同場景,不是抄襲。而且那只是個三維模型,程式要自己寫,每個人寫的程式是不同的。
市中心、市街道、郊區場景,來自UnityStore的unity包:258316_Anime_Tokyo_(Japanese_City),也有很多遊戲開發者在用這個場景三維模型。
人物三維模型來自於網路上大家常見、常用的三維人物模型,我做了骨骼繫結、蒙皮、走路動畫。
雪景程式來自於unity包:Global Snow,天空盒來自於unity包:AllSky。
學校場景,來自unity包:Japanese_School_Buildings_Kit。
學校樓道場景,來自unity包:Japanese School Corridor 2.0。
教室場景,來自unity包:Japanese Classroom Set。
圖書館場景,來自unity包:Japanese School Library Set。
食堂場景,來自unity包:Japanese School Cafeteria。
體育館場景,來自unity包:Japanese School Gym。
游泳池場景,來自unity包:Japanese School Pool Clean Dirty Set。
醫務室場景,來自unity包:Japanese School Infirmary Set。

(二)基本操作
W鍵(長按):向前走。
S鍵(長按):向後走。
A鍵(長按):向左轉。
D鍵(長按):向右轉。

滑鼠左右上下移動來控制攝像機視角(螢幕視角),人物前進方向自動朝向攝像機視角。
鍵盤右邊的方向鍵:上:抬高攝像機視角,下:降低攝像機視角,左:拉近攝像機視角,右:拉遠攝像機視角。
F鍵(單擊):第三人稱視角和第一人稱視角的切換。第三人稱視角適合用在街上,第一人稱視角適合用在家裡。
樓梯上不動的時候,把螢幕視角向上仰,就可以上樓梯了。

室外場景時:空格鍵(單擊):顯示或關閉文字的輸入輸出框(預設不顯示,需要點選空格鍵才顯示)。輸入完文字後,按Enter鍵傳送。
J鍵(單擊):女主角一鍵換服裝。
M鍵(單擊):背景音樂,繼續按,是下一首好聽的背景音樂。

數字鍵1(單擊):小區場景(預設場景)。
數字鍵2(單擊):市中心場景。
數字鍵3(單擊):市街道場景。
數字鍵4(單擊):郊區場景。
數字鍵5(單擊):學校。
數字鍵6(單擊):學校走廊。
數字鍵7(單擊):教室。
數字鍵8(單擊):圖書館。
數字鍵9(單擊):食堂。
數字鍵0(單擊):體育館。

Esc鍵(單擊):退出遊戲。

小區場景中:
H鍵(單擊):一鍵回家。
小區場景、市街道場景、郊區場景中:
L鍵(單擊):正常景色和雪景的切換。
小區場景和學校樓外場景中:
G鍵(單擊):自動尋路。第一次按G鍵,男主角和女主角分開,女主角停留在原地。男主角走遠後,第二次按G鍵,女主角會自動尋路來找男主角,到男主角身邊。
小區場景和市街道場景中:
K鍵(單擊):每點選一次,就變換一次天色。小區場景:淺夜→夜晚→白天→傍晚→夜晚→清晨→白天→陰天。市街道場景:傍晚→晚上→白天。

(三)
即便沒有安裝unity編輯器的情況下,play資料夾裡DreamStart.exe可以直接執行此遊戲。

unity的一份原始碼,只能適配一個編輯器版本,這個原始碼適配的是2022.3.38,其它版本開啟此原始碼,會故障。
unity匯入此專案時,不是匯入哪個具體啟動檔案,而是用unity Hub(unity啟動器)直接開啟(匯入)DreamStart資料夾。
如果unity編輯器沒有顯示場景,就在編輯器裡手動開啟park資料夾裡的Scenes資料夾裡的park場景檔案即可。
在unity編輯器介面,不要把視窗最大化後再執行遊戲,那樣執行不了。但可以在遊戲後,再最大化視窗。
地上的藍色,是自動尋路烘培的地面,遊戲執行時不顯示那藍色。

(四)話語分析
話語分析是有用的,假如遊戲中,你是隊長,帶著NPC隊友張三和李四,路上遇到蛇,你可以說“張三打蛇,李四保護張三。”這就需要先分析出主語、謂語、賓語,程式才能處理。
輸入完成後,按Enter鍵傳送。

示例:
輸入:貓吃鼠
顯示:主語:貓,謂語動詞:吃,賓語:鼠

輸入:白色的貓吃黑色的鼠
顯示:主語:貓,謂語動詞:吃,賓語:鼠,主語的形容詞:白色的,賓語的形容詞:黑色的

輸入:兩隻貓吃3只鼠
顯示:主語:貓,謂語動詞:吃,賓語:鼠,主語的數詞:2只,賓語的數詞:3只

輸入:張三的貓吃李四的鼠
顯示:主語:貓,謂語動詞:吃,賓語:鼠,主語的名詞所有格:張三,賓語的名詞所有格:李四

輸入:張三給李四蘋果
顯示:主語:張三,謂語動詞:給,間接賓語:李四,直接賓語:蘋果

輸入:張三讓李四打掃教室
顯示:主語:張三,謂語動詞:讓,賓語:李四,賓語補足語動詞:打掃,賓語補足語名詞:教室

輸入:2024年張三在學校吃飯
顯示:主語:張三,謂語動詞:吃飯,時間:2024年,地點:學校

如果分析顯示不了,可能詞語不在詞庫裡。先找動詞分割句子,再找名詞,所以如果動詞不在詞庫裡,即便名詞在詞庫裡,也沒用。
連線的單機資料庫是garden.db,是sqlite單機資料庫,就是在使用者電腦的遊戲檔案裡的,不聯網的、不用安裝服務的、不用配置的,直接就可以用的資料庫。

(五)
人工智慧分析話語的原始碼教程:
這僅是前六章,以後我還會繼續寫。用C#語言寫的。如果找不出主語、謂語、賓語等,因為詞語不在詞庫中,那就需要手動新增進詞庫。還有,先按動詞分割句子,如果動詞找不到,後面名詞就算在詞庫,也找不到。目前詞庫裡,名詞7128個,動詞5886個,形容詞1777個。
每一章是在前一章的基礎上增加內容,從而使讀者能循序漸進的看懂。如果直接給個結果,讀者不知道怎麼一步步變化來的,那也就看不懂結果了。

前三章概述:
第一章的主要內容
判斷輸入的句子中,是否包含名詞。
找出句子的主語、謂語、賓語。
解決三個基本問題
前面的方法,靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
對於第一個問題的解決方法:
新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
所以建立一個函式:WordCover(覆蓋)。
詞語槽(WordBox)存放這些找到詞,以實現覆蓋和吸收。

第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
對於第二個問題的解決方法:
找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
所以建立一個de函式。

第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
對於第三個問題的解決方法:
建立詞性辨析表:verb_judge,詞性辨析表在資料庫裡,已經做好了。

第二章的主要內容
基本單句有六種句型:
只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
主語(動作執行者)-謂語(動作):張三摔倒。
主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
前面只說了主謂賓句型,還要處理其它句型。

雙賓語句型:
雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

賓語補足語句型:
和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

第三章的主要內容
省略主語有兩種情況:一種是主動語態省略主語,例如“跳過去”,全句指“你跳過去”。另一種是被動語態省略主語,例如“張三被打了”,沒說誰打了張三,這裡張三是賓語。如果說“李四打了張三”,李四就是主語。
被動語態的標誌是“被”字,如果沒有“被”字,而且省略了主語,就是主動語態省略主語的情況,那麼這種情況下,主語應該填什麼呢?例如“過來”,一般指“你過來”,但“走吧”一般指“我們走吧”。所以程式要根據具體的動詞來判斷省略的主語應該填什麼。但是動詞太多,每個動詞都要設定省略的主語判斷,太麻煩。所以省略主語,按最通常情況,就預設填“你”字,作為主語。如果主語是“我們”而不是“你”字,就不該省略主語。
被動語態應該還原為主動語態去理解,但被動語態往往沒有主語,那麼預設主語應該填什麼呢?畢竟不知道主語,那就填“事物”這個詞作為主語。
程式分析句子時,被動語態的主語位置的詞,是賓語。例如“李四被打了”,李四在謂語動詞左邊句,程式會把李四當成主語,但在被動語態句裡,李四不是主語,所以有“被”字的時候,主語要挪動到賓語位置,然後在主語位置補充“事物”這個詞,作為主語。
但是有些時候,被動語態的主語是說明了的,例如“李四被張三打了”就還原為主動語態“張三打了李四”,張三做主語,而不是填“事物”做主語。
簡而言之,被動語態裡,主語放到了賓語位置,賓語放到了主語位置,所以變為主動語態時,要把賓語挪回主語位置,主語挪回賓語位置。
如果被動語態有主語,例如“李四被張三打了”,那麼主語(張三)位於“被”字與謂語動詞之間。
那麼謂語動詞左邊句中,又分為“被”字左邊句和“被”字右邊句,被字左邊句裡的名詞是賓語,被字右邊句裡的名詞是主語。

名詞合併:
名詞合併:例如“足球學校”這個詞,會被當成兩個名詞“足球”和“學校”。但實際中,要把它們合併成一個組合名詞,作為主語或賓語。
合併方法:如果兩個字元(詞語)是連續的,那麼這兩個詞語之間的內容為空。

動詞合併:
例如“應該愛”是兩個動詞:情態動詞“應該”和普通動詞“愛”,應該合併成一個動詞。

動詞前面是否有否定詞,也很重要。
例如“他愛貓”和“他不愛貓”,雖然謂語動詞都是“愛”字,但前面加個“不”字,意義就相反了。所以看謂語動詞前面是否有否定詞,是很重要的事。
謂語動詞前面的否定詞,一般有不、不要、不可以、不應該、不能、別。
還有不確定肯定還是否定動詞,例如“他不一定去”,“去”字是動詞,但是動詞前的“不一定”,並不像是“不”字那樣對動詞進行否定,而是對動詞既不像是肯定,也不像是否定,而是不確定。
因此對每句話的謂語動詞,都要加一個性質:肯定、否定、不確定。
但不確定,有時候偏向於肯定,例如“他可能去”。有時候不確定偏向於否定,例如“他不太可能去”以及“他或許不去”。
那麼動詞發生機率分為五種:肯定、偏向肯定、不確定、偏向否定、否定。
這其實就是在分析事情(謂語動詞)發生的機率,這在機率分析上有用。

第五章:
對於數詞,之前用正規表示式直接抽取出數字,那種方法太簡單了,我用逐字分析的方法重寫了。
還有就是分析出時間,不僅分析出是年、月、日、時、分,還要分析出一些時間詞:
"今天", "明天", "後天", "昨天", "前天", "這個月", "下個月", "上個月", "今年", "明年", "去年"
"早晨", "上午", "中午", "下午", "傍晚", "晚上", "傍晚", "夜晚", "半夜", "黎明", "黃昏", "清晨"
"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日", "禮拜一", "禮拜二", "禮拜三", "禮拜四", "禮拜五", "禮拜六", "禮拜天"
"春天", "夏天", "秋天", "冬天", "春季", "夏季", "秋季", "冬季"
"元旦", "大年三十", "除夕", "春節", "大年初一", "大年初二", "大年初三", "正月十五", "寒假", "清明節", "五一節", "勞動節", "兒童節", "暑假", "中秋節", "國慶節", "聖誕節", "假期", "休息日"

第五章可用的動詞單位是:
"個", "名", "位", "只", "頭", "匹", "條", "棵", "朵", "片", "根", "座", "棟", "臺", "部", "本", "塊", "件", "盞", "把", "所", "輛", "艘", "架", "扇"

"米", "釐米", "毫米", "分米", "公里", "裡", "微米", "奈米", "克", "斤", "公斤", "噸", "毫克", "升"

先找到動詞單位,才能找到數詞。

第六章:
直接賓語的定語(形容詞、數詞、名詞所有格),在間接賓語和直接賓語之間。
例如張三給李四紅色的蘋果,李四是間接賓語,蘋果是直接賓語,紅色的是形容詞。

間接賓語的定語在謂語動詞和間接賓語之間,對於謂語動詞右邊句,也就是句子開始到間接賓語之間。
例如張三給美麗的李四蘋果,李四是間接賓語,美麗的是形容詞。

賓語補足語名詞的定語(形容詞、數詞、名詞所有格)在賓語補足語動詞的右邊。
例如張三讓李四打掃藍色的房子,打掃是賓語補足語的動詞,房間是賓語補足語的名詞,藍色的是形容詞。

第六章增加了猜測詞語的功能,但不建議用猜測詞語,因為如果一個詞語,詞庫裡沒有,要靠程式猜測,那麼遊戲劇情肯定對這個詞語沒做任何準備,就算猜測出這個詞,也沒用。
例如張三愛雅娜,名詞詞庫肯定沒有“雅娜”這個詞,但是謂語動詞“愛”字右邊的句子的兩個字,顯然是賓語名詞,所以猜測詞語是很容易猜測的。
就算猜測出賓語是雅娜,又怎樣了呢,對雅娜的資訊和屬性,什麼都沒有設定,程式沒法分析。甚至連雅娜到底是一個人還是一塊石頭,都沒法分析。
那麼張三帶著雅娜去海邊,到底是張三帶著女人雅娜去海邊,還是張三帶著石頭雅娜去海邊,準備扔石頭玩水漂。計算機分析程式一頭霧水,所以猜測詞語會降低計算機的分析能力。
還是勤快點吧,把詞語錄入詞庫,並給詞語設定資訊和屬性。什麼時候用猜測詞語呢?詞庫詞彙量還不夠多的時候,只能靠猜詞來補償,但這不是長遠的辦法。
這就好比程式設計強調“對變數,要先定義,後使用”,猜測詞語就好比不定義就直接使用。

猜測詞語的原理:抽取掉已知的詞語(詞庫裡有的詞語),剩下的未知的詞語(詞庫裡沒有的詞語),就是要猜測的詞。
例如“張三喜歡美麗的雅娜”,謂語動詞右邊句是“美麗的雅娜”,詞庫已有的形容詞是“美麗的”,抽取掉形容詞“美麗的”,剩下的詞語“雅娜”就是要猜測的賓語。

第一章
人工智慧處理語言的意義
假如你是隊長,帶著兩個NPC隊友張三和李四,路上遇到一條蛇。你下令張三打蛇,李四保護張三,這就需要先分析出句子的主語、謂語、賓語,程式才能操作命令。

單機資料庫的意義
這個程式用的是單機資料庫sqlite,單機遊戲一般都用單機資料庫sqlite。因為一方面,單機資料庫不聯網,在使用者電腦的遊戲檔案裡,而不是在伺服器上。另一方面,單機資料庫不用安裝服務,不用做配置,使用者啥都不用管,直接就能用。

需要的外掛說明
有詞庫的sqlite資料庫garden.db。其中名詞表noun,名詞列word_col。動詞表verb,動詞列word_col。還有詞性辨析表verb_judge。
把garden.db放到Assets資料夾的上一級資料夾,也就是程式原始碼的根目錄,就可以在編輯器環境下執行了。生成遊戲後,garden.db還要複製到生成遊戲的資料夾裡。
將C盤→Program Files→Unity→Hub→Editor→2022.3.38→Editor→Data→MoonBleedingEdge→lib→mono→net_4_x-win32資料夾裡的Mono.data.sqlite.dll和system.data.dll放到Plugins資料夾裡(在Assets資料夾裡,自己建立一個Plugins資料夾,字母P大寫,系統自動認為那是個存放外掛的資料夾)。
在sqlite官網下載sqlite3.dll也放到Plugins資料夾裡。
Mono.data.sqlite.dll、system.data.dl、sqlite3.dll是sqlite資料庫執行所需的三個外掛。

判斷輸入的句子中,是否包含名詞
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Mono.Data.Sqlite;

public class sqlitecon : MonoBehaviour
{
public TMP_Text tmpText;//輸出框物件
string ShowText;//輸出框的內容
string[] noun = new string[7128];//名詞陣列,名詞數量7128
string[] verb = new string[5886];//動詞陣列,動詞數量5886
int i = 0;//陣列用的迴圈變數
public TMP_InputField inputField;//輸入框物件

// Start is called before the first frame update
void Start()
{
    //inputField = GetComponent<TMP_InputField>();//輸入框獲取元件
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    UnityEngine.Debug.Log(i);//顯示動詞數量
}

// Update is called once per frame
void Update()
{

}

void OnInputEndEdit(string value)
{
    string shuru = inputField.text;//輸入框的值
    string jieguo = "不包含";//預設值是不包含
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞
    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (shuru.Contains(noun[n]))//包含
        {
            jieguo = "包含";
        }
    }

    tmpText.text = jieguo;//顯示結果

}
}

OnInputEndEdit函式里,稍微改變一下,也可以用於找動詞。

找出句子的主語、謂語、賓語
例如輸入:白色的貓吃黑色的鼠。主語顯示:貓,謂語動詞顯示:吃,賓語顯示:鼠。
基本原理:對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Mono.Data.Sqlite;

public class sqlitecon : MonoBehaviour
{
public TMP_Text tmpText;//輸出框物件
string ShowText;//輸出框的內容
string[] noun = new string[7128];//名詞陣列,名詞數量7128
string[] verb = new string[5886];//動詞陣列,動詞數量5886
int i = 0;//陣列用的迴圈變數
public TMP_InputField inputField;//輸入框物件
string shuru = "";//輸入框的內容

string FindSubject = "";//找到的主語
string FindVerb = "";//找到的謂語動詞
string FindObject = "";//找到的賓語

// Start is called before the first frame update
void Start()
{
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量
}

// Update is called once per frame
void Update()
{

}

void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的值

    //找謂語動詞
    string jieguo = "不包含";//預設值是不包含
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞
    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (shuru.Contains(verb[n]))//包含
        {
            jieguo = "包含";
            FindVerb = verb[n];//找到了動詞
        }
    }

    if(jieguo == "包含")
    {
        SplitSentence(FindVerb);
    }


    //tmpText.text = jieguo;//顯示結果
}

void SplitSentence(string find_verb)
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "吃";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞的位置(索引)
    int i = 0;//臨時變數
    int j = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    UnityEngine.Debug.Log(chang);//顯示9

    //計算指定字元在全句中的位置
    index = str.IndexOf(word);//從0計算,例如第2個字元,顯示為1,而不是2
    UnityEngine.Debug.Log(index);//顯示4

    //擷取第3個字元右邊的1個字元
    Substring(開始位置,向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元
    UnityEngine.Debug.Log(res);//顯示:貓

    //擷取指定字元右邊的全部字元
    i = index + 1;//指定字元的位置,由於index是從0開始計算的,所以要加1,變為從1開始計算的方式,所以是index+1
    j = chang - (index + 1);//擷取長度 = 全句長度 - 指定字元的位置長度
    UnityEngine.Debug.Log(i);//顯示5
    UnityEngine.Debug.Log(chang);//顯示9
    UnityEngine.Debug.Log(j);//顯示4
    res = str.Substring(i,j);
    UnityEngine.Debug.Log(res);//顯示:黑色的鼠
    res = str.Substring(index + 1, chang - (index + 1));//變化形式
    UnityEngine.Debug.Log(res);//顯示:黑色的鼠
    //index變為str.IndexOf(word),chang變為str.Length
    res = str.Substring(str.IndexOf(word) + 1, str.Length - (str.IndexOf(word) + 1));//變化形式
    UnityEngine.Debug.Log(res);//顯示:黑色的鼠

    //擷取指定字元左邊的全部字元
    res = str.Substring(0,index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0,str.IndexOf(word));//變化形式
    UnityEngine.Debug.Log(res);//顯示:白色的貓

    //擷取兩個指定字元之間的全部字元
    i = str.IndexOf("貓");
    j = str.IndexOf("鼠");
    res = str.Substring(i+1,j-(i+1));
    UnityEngine.Debug.Log(res);//顯示:吃黑色的
    //把i變為str.IndexOf("貓"),j變為str.IndexOf("鼠")
    res = str.Substring(str.IndexOf("貓") + 1, str.IndexOf("鼠") - (str.IndexOf("貓") + 1));//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃黑色的

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }
    */

    string LeftPart = "";//謂語動詞的左邊句
    string RightPart = "";//謂語動詞的右邊句

    LeftPart = shuru.Substring(0, shuru.IndexOf(find_verb));
    RightPart = shuru.Substring(shuru.IndexOf(find_verb) + 1, shuru.Length - (shuru.IndexOf(find_verb) + 1));

    /*
    例如句子(shuru)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);
    UnityEngine.Debug.Log(LeftPart);
    UnityEngine.Debug.Log(RightPart);
    */

    if (find_verb != "")
    {
        FindVerb = find_verb;
    }

    if (LeftPart != "")
    {
        FindSubject = SearchNoun(LeftPart);//找名詞
    }

    if (RightPart != "")
    {
        FindObject = SearchNoun(RightPart);//找名詞
    }

    UnityEngine.Debug.Log(FindSubject);
    UnityEngine.Debug.Log(FindVerb);
    UnityEngine.Debug.Log(FindObject);

}

string SearchNoun(string PartSentence)
{
    //找名詞
    string jieguo = "不包含";//預設值是不包含
    string FindNoun = "";//要找的名詞
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞
    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//包含
        {
            jieguo = "包含";
            FindNoun = noun[n];//找到了名詞
        }
    }

    if (jieguo == "包含")
    {
        return FindNoun;
    }
    else
    {
        return "";
    }
}

}

解決三個基本問題
前面的方法,靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
對於第一個問題的解決方法:
新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
所以建立一個函式:WordCover(覆蓋)。
詞語槽(WordBox)存放這些找到詞,以實現覆蓋和吸收。

第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
對於第二個問題的解決方法:
找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
所以建立一個de函式。

第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
對於第三個問題的解決方法:
建立詞性辨析表:verb_judge,詞性辨析表在資料庫裡,已經做好了。
+--------------+-------------+----------------+
| word_col | type_col | content_col |
+--------------+-------------+----------------+
| 學 | r1 | 生 |
+--------------+-------------+----------------+
| 壓 | l1 | 氣 |
+--------------+-------------+----------------+

word_col:判斷這個字是動詞還是名詞。
type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
l是字母L的小寫,不是數字1。l1是兩個不同的字元。
所以建立一個VerbJudge函式。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Mono.Data.Sqlite;

public class sqlitecon : MonoBehaviour
{
public TMP_Text tmpText;//輸出框物件
string ShowText;//輸出框的內容
string[] noun = new string[7128];//名詞陣列,名詞數量7128
string[] verb = new string[5886];//動詞陣列,動詞數量5886
int i = 0;//陣列用的迴圈變數
public TMP_InputField inputField;//輸入框物件
string shuru = "";//輸入框的內容

string FindSubject = "";//找到的主語
string FindVerb = "";//找到的謂語動詞
string FindObject = "";//找到的賓語

string WordBox1 = "";//詞語槽1
string WordBox2 = "";//詞語槽2
string WordBox3 = "";//詞語槽3
string WordBox4 = "";//詞語槽4

// Start is called before the first frame update
void Start()
{
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量

    dbConnection.Close();
}

// Update is called once per frame
void Update()
{

}

void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的值

    //找謂語動詞
    string jieguo = "不包含";//預設值是不包含
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞
    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (shuru.Contains(verb[n]))//包含
        {
            if (VerbJudge(shuru,verb[n]) == true)
            {
                jieguo = "包含";
                FindVerb = verb[n];//找到了動詞
            }
            
        }
    }

    if(jieguo == "包含")
    {
        SplitSentence(FindVerb);
    }


    //tmpText.text = jieguo;//顯示結果
}

void SplitSentence(string find_verb)
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "吃";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞的位置(索引)
    int i = 0;//臨時變數
    int j = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    UnityEngine.Debug.Log(chang);//顯示9

    //計算指定字元在全句中的位置
    index = str.IndexOf(word);//從0計算,例如第2個字元,顯示為1,而不是2
    UnityEngine.Debug.Log(index);//顯示4

    //擷取第3個字元右邊的1個字元
    Substring(開始位置,向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元
    UnityEngine.Debug.Log(res);//顯示:貓

    //擷取指定字元右邊的全部字元
    i = index + 1;//指定字元的位置,由於index是從0開始計算的,所以要加1,變為從1開始計算的方式,所以是index+1
    j = chang - (index + 1);//擷取長度 = 全句長度 - 指定字元的位置長度
    UnityEngine.Debug.Log(i);//顯示5
    UnityEngine.Debug.Log(chang);//顯示9
    UnityEngine.Debug.Log(j);//顯示4
    res = str.Substring(i,j);
    UnityEngine.Debug.Log(res);//顯示:黑色的鼠
    res = str.Substring(index + 1, chang - (index + 1));//變化形式
    UnityEngine.Debug.Log(res);//顯示:黑色的鼠
    //index變為str.IndexOf(word),chang變為str.Length
    res = str.Substring(str.IndexOf(word) + 1, str.Length - (str.IndexOf(word) + 1));//變化形式
    UnityEngine.Debug.Log(res);//顯示:黑色的鼠

    //擷取指定字元左邊的全部字元
    res = str.Substring(0,index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0,str.IndexOf(word));//變化形式
    UnityEngine.Debug.Log(res);//顯示:白色的貓

    //擷取兩個指定字元之間的全部字元
    i = str.IndexOf("貓");
    j = str.IndexOf("鼠");
    res = str.Substring(i+1,j-(i+1));
    UnityEngine.Debug.Log(res);//顯示:吃黑色的
    //把i變為str.IndexOf("貓"),j變為str.IndexOf("鼠")
    res = str.Substring(str.IndexOf("貓") + 1, str.IndexOf("鼠") - (str.IndexOf("貓") + 1));//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃黑色的

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }
    */

    string LeftPart = "";//謂語動詞的左邊句
    string RightPart = "";//謂語動詞的右邊句

    LeftPart = shuru.Substring(0, shuru.IndexOf(find_verb));
    RightPart = shuru.Substring(shuru.IndexOf(find_verb) + 1, shuru.Length - (shuru.IndexOf(find_verb) + 1));

    /*
    例如句子(shuru)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);
    UnityEngine.Debug.Log(LeftPart);
    UnityEngine.Debug.Log(RightPart);
    */

    if (find_verb != "")
    {
        FindVerb = find_verb;
    }

    if (LeftPart != "")
    {
        FindSubject = SearchNoun(LeftPart);//找名詞
    }

    if (RightPart != "")
    {
        FindObject = SearchNoun(RightPart);//找名詞
    }

    UnityEngine.Debug.Log("主語:" + FindSubject);
    UnityEngine.Debug.Log("謂語:" + FindVerb);
    UnityEngine.Debug.Log("賓語:" + FindObject);

    /*
    靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

    第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    所以建立一個函式:WordCover(覆蓋)。
    詞語槽(WordBox)存放這些找到詞,以實現覆蓋和吸收。

    第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    對於第二個問題的解決方法:
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    所以建立一個de函式。

    第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +--------------+-------------+----------------+
    | word_col | type_col | content_col |
    +--------------+-------------+----------------+
    |   學    |   r1   |    生    |
    +--------------+-------------+----------------+
    |   壓    |   l1   |    氣    |
    +--------------+-------------+----------------+
    word_col:判斷這個字是動詞還是名詞。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。
    所以建立一個VerbJudge函式。
    */
}

string SearchNoun(string PartSentence)
{
    //找名詞
    string jieguo = "不包含";//預設值是不包含
    string FindNoun = "";//要找的名詞
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞

    //for迴圈前,先把詞語槽清空,因為for迴圈時,呼叫的函式WordCover要用詞語槽,來完成詞語的覆蓋和吸收
    WordBox1 = "";
    WordBox2 = "";
    WordBox3 = "";
    WordBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//包含
        {
            jieguo = "包含";
            //FindNoun = noun[n];//找到了名詞
            if (de(PartSentence, noun[n]) == false)//找到的名詞右邊的第一個字元不是“的”字
            {
                FindNoun = WordCover(noun[n]);
            }
        }
    }

    if (jieguo == "包含")
    {
        return FindNoun;
    }
    else
    {
        return "";
    }
}

string WordCover(string FindWord)
{
    /*
    熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    詞語槽(WordBox)存放這些找到詞,以實現覆蓋和吸收。
    做了4個詞語槽(WordBox),為了以後適應複雜的句子,但簡單的主謂賓句型,一個詞語槽就夠了。
    */
    if (WordBox1 == "" && FindWord != "")//詞語槽還是空的,說明這是找到的第一個詞
    {
        WordBox1 = FindWord;//找到的第1個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽2了
    }
    else if (WordBox1 != "" && FindWord != "")//詞語槽1已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(WordBox1))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽1(WordBox1)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            WordBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽2了
        }
        else if (WordBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽1(WordBox1)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,不要這個詞了,免得填到詞語槽2了
        }
    }

    if (WordBox2 == "" && FindWord != "")//詞語槽2是空的,FindWord經過詞語槽1,沒有覆蓋或吸收,說明FindWord和詞語槽1的詞無關,例如FindWord是竹子
    {
        WordBox2 = FindWord;//找到的第2個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽3了
    }
    else if (WordBox2 != "" && FindWord != "")//詞語槽2已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(WordBox2))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽2(WordBox2)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            WordBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (WordBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽2(WordBox2)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (WordBox3 == "" && FindWord != "")//詞語槽3是空的,FindWord經過詞語槽2,沒有覆蓋或吸收,說明FindWord和詞語槽2的詞無關,例如FindWord是竹子
    {
        WordBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (WordBox3 != "" && FindWord != "")//詞語槽3已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(WordBox3))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽3(WordBox3)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            WordBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (WordBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽3(WordBox3)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (WordBox4 == "" && FindWord != "")//詞語槽4是空的,FindWord經過詞語槽3,沒有覆蓋或吸收,說明FindWord和詞語槽3的詞無關,例如FindWord是竹子
    {
        WordBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (WordBox4 != "" && FindWord != "")//詞語槽4已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(WordBox4))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽4(WordBox4)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            WordBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (WordBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽4(WordBox4)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空
        }
    }

    return WordBox1;//對於主謂賓結構,找主語時,找到的名詞只有一個,找賓語時,找到的名詞也只有一個,所以只返回WordBox1
}

bool de(string str,string word)
{
    /*
    熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    
    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }
    UnityEngine.Debug.Log(res);//顯示:的
    以上內容是解釋原理,下面是執行程式:
    */

    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果
    WordLastChar = str.IndexOf(word) + word.Length;
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }

    if (res == "的")
    {
        return true;
    }
    else
    {
        return false;
    }

}

bool VerbJudge(string str,string word)
{
    /*
    “學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +--------------+-------------+----------------+
    | word_col | type_col | content_col |
    +--------------+-------------+----------------+
    |   學    |   r1   |    生    |
    +--------------+-------------+----------------+
    |   壓    |   l1   |    氣    |
    +--------------+-------------+----------------+
    word_col:判斷這個字是動詞還是名詞,也就是辨析字。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。
    “壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。

    不容易理解的一處:
    +--------------+-------------+----------------+
    | word_col | type_col | content_col |
    +--------------+-------------+----------------+
    |   吹    |   l1   |    電    |
    +--------------+-------------+----------------+
    “吹”字本身做動詞,但在“電吹風”這個詞裡做名詞,但我不用把“電吹風”這個三個字都判斷,我只要判斷“電吹”兩個字就可以了。

    遇到單字動詞的時候,先看這個字是否在詞性辨析表裡,
    如果在,type_col要求是r1(right1,就是要辨析的字的右邊1個字元),那就看句子中要辨析的字的右邊1個字元是不是符合詞性表中的字,
    如果符合,要辨析的字就是名詞,而不是動詞了。
    例如學生看書,這句話先找到了動詞“學”,在詞性辨析表裡,“學”字的type_col是r1,content_col是“生”字,
    那就在句子中,看“學”字右邊的1個字元是不是“生”字,如果是,“學”字就不做動詞,而做名詞了。

    一個要辨析的字,type_col有四種可能:r1、r2、l1、l2,也就是右邊1個字,右邊2個字,左邊1個字,左邊2個字,那就要會四個方法:
    符合r1:找辨析字右邊1個字元:res = str.Substring(str.IndexOf(word) + word.Length, 1);
    符合r2:找辨析字右邊2個字元:res = str.Substring(str.IndexOf(word) + word.Length, 2);
    符合l1:找辨析字左邊1個字元:res = str.Substring(str.IndexOf(word) - 1, 1);
    符合l2:找辨析字左邊2個字元:res = str.Substring(str.IndexOf(word) - 2, 1);

    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
        res = str.Substring(str.IndexOf(word) + word.Length, 1);//變化形式

    }
    UnityEngine.Debug.Log(res);//顯示:的

    //指定詞語左邊1個字元
    res = str.Substring(index - 1, 1);
    res = str.Substring(str.IndexOf(word) - 1, 1);//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃
    以上內容是解釋原理,下面是執行程式:
    */

    string[] TypeCol = new string[100];//把詞性辨析表的辨析字對應的type_col值填充此陣列
    string[] ContentCol = new string[100];//把詞性辨析表的辨析字對應的content_col值填充此陣列
    string res = "";//擷取的字元
    bool shima = true;//預設判斷是動詞

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    //字元型變數要有引號,數字型變數不需要引號
    //word是變數,動態的,不能直接放到sql語句裡面
    string sqlQuery = "select type_col,content_col from verb_judge where word_col = '" + word + "'";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充詞性辨析陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();

    i = 0;
    while (dbReader.Read())
    {
        //查詢了2列(type_col和content_col),所以返回的結果集有2列,分別用GetValue(0)和GetValue(1)
        TypeCol[i] = dbReader.GetValue(0).ToString();//返回的結果集的第1列
        ContentCol[i] = dbReader.GetValue(1).ToString();//返回的結果集的第2列
        i++;//雖然定義陣列長度為10,但i不一定填滿了10
    }
    dbReader.Close();
    dbConnection.Close();
    
    if (i > 0)//在詞性辨析表裡找到內容了,否則i還是預設的0
    {
        for (int n = 0; n < i; n++)//遍歷詞性辨析表找到的各種結果
        {
            if (TypeCol[n] == "r1")//right1:右邊1個字元
            {
                if (str.IndexOf(word) + word.Length + 1 <= str.Length)//要往右判斷1個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 1);//擷取動詞右邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "r2")//right2:右邊2個字元
            {
                if (str.IndexOf(word) + word.Length + 2 <= str.Length)//要往右判斷2個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 2);//擷取動詞右邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "l1")//left1:左邊1個字元
            {
                if (str.IndexOf(word) - 1 >= 0)//要往左判斷1個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 1, 1);//擷取動詞左邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }

                }
            }
            else if (TypeCol[n] == "l2")//left2:左邊2個字元
            {
                if (str.IndexOf(word) - 2 >= 0)//要往左判斷2個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 2, 2);//擷取動詞左邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
        }
    }
    i = 0;
    return shima;
}

}

第二章
基本單句有六種句型:
只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
主語(動作執行者)-謂語(動作):張三摔倒。
主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
前面只說了主謂賓句型,還要處理其它句型。

雙賓語句型:
雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

賓語補足語句型:
和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

在主謂賓句型的基礎上,如果沒有賓語,就是主謂句型。如果沒有主語,就是省略主語,例如對一個人喊“過來”,這句話的全句顯然是“你過來”。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Mono.Data.Sqlite;

public class sqlitecon : MonoBehaviour
{
public TMP_Text tmpText;//輸出框物件
string ShowText;//輸出框的內容
string[] noun = new string[7128];//名詞陣列,名詞數量7128
string[] verb = new string[5886];//動詞陣列,動詞數量5886
int i = 0;//陣列用的迴圈變數
public TMP_InputField inputField;//輸入框物件
string shuru = "";//輸入框的內容

string FindSubject = "";//找到的主語
string FindVerb = "";//找到的謂語動詞
string FindObject = "";//找到的賓語
string FindBuVerb = "";//賓語補足語的動詞
string FindBuNoun = "";//賓語補足語的名詞
string FindJianObject = "";//找到的間接賓語
string FindZhiObject = "";//找到的直接賓語

string NounBox1 = "";//名詞槽1
string NounBox2 = "";//名詞槽2
string NounBox3 = "";//名詞槽3
string NounBox4 = "";//名詞槽4

string VerbBox1 = "";//動詞槽1
string VerbBox2 = "";//動詞槽2
string VerbBox3 = "";//動詞槽3
string VerbBox4 = "";//動詞槽4

string SentenceType = "";//句型

// Start is called before the first frame update
void Start()
{
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量

    dbConnection.Close();
}

// Update is called once per frame
void Update()
{

}

void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的值

    //找謂語動詞
    string jieguo = "不包含";//預設值是不包含動詞
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞

    VerbBox1 = "";
    VerbBox2 = "";
    VerbBox3 = "";
    VerbBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (shuru.Contains(verb[n]))//包含動詞
        {
            if (VerbJudge(shuru,verb[n]) == true)//是動詞,不是名詞
            {
                jieguo = "包含";
                FindVerb = verb[n];//找到了動詞
                VerbCover(shuru,verb[n]);//把動詞放入動詞槽裡,看看有幾個動詞
            }
            
        }
    }

    if(jieguo == "包含")//包含動詞
    {
        SentenceType = SentenceJudge();//判斷句型(僅從動詞情況來判斷句型,還不是完全清楚的判斷,之後還需進一步判斷)
        UnityEngine.Debug.Log("句型:" + SentenceType);
        
        SplitSentence();
    }
    //tmpText.text = jieguo;//顯示結果
}

void SplitSentence()
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string word = "嘲笑";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞語的起始位置
    int LastIndex = 0;//指定詞語最後一個字元在全句中的位置
    int jie = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    //計算指定字元在全句中的位置
    index = str.IndexOf(word) + 1;//預設從0計算,例如第2個字元,顯示為1,而不是2。為了調整為1開始計算,所以加1
    //計算指定詞語最後一個字元在全句中的位置
    LastIndex = str.IndexOf(word) + word.Length;

    //擷取第3個字元右邊的1個字元
    Substring(開始位置, 向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元

    //擷取指定字元右邊的全部字元
    jie = chang - LastIndex;//擷取長度 = 全句長度 - 指定詞語最後一個字元的位置長度
    res = str.Substring(LastIndex, jie);
    res = str.Substring(str.IndexOf(word) + word.Length, str.Length - (str.IndexOf(word) + word.Length));//展開形式

    //擷取指定字元左邊的全部字元
    res = str.Substring(0, index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0, str.IndexOf(word));//變化形式

    //擷取兩個指定字元之間的全部字元
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }
    */

    string LeftPart = "";//謂語動詞的左邊句
    string RightPart = "";//謂語動詞的右邊句

    //也可能找到一個動詞(主謂賓句型),也可能找到兩個動詞(賓語補足語句型)
    if (VerbBox1 != "" && VerbBox2 == "")//只找到1個動詞,那就是謂語動詞
    {
        FindVerb = VerbBox1;
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//找到2個動詞
    {
        FindVerb = VerbBox1;//位次在前面的動詞是謂語動詞
        FindBuVerb = VerbBox2;//位次在後面的動詞是賓語補足語動詞
    }

    LeftPart = shuru.Substring(0, shuru.IndexOf(FindVerb));
    RightPart = shuru.Substring(shuru.IndexOf(FindVerb) + FindVerb.Length, shuru.Length - (shuru.IndexOf(FindVerb) + FindVerb.Length));

    /*
    例如句子(shuru)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);
    UnityEngine.Debug.Log(LeftPart);
    UnityEngine.Debug.Log(RightPart);
    */

    if (LeftPart != "")
    {
        FindSubject = SearchNoun(LeftPart);//在謂語動詞左邊句找名詞(主語)
    }

    if (SentenceType == "雙賓語")//雙賓語句型
    {
        FindObject = SearchNoun(RightPart);//找名詞

        //謂語動詞右邊句裡,沒有第二個賓語名詞,那就不是雙賓語
        //例如雖然有雙賓語句的標誌動詞“教”字,但他教我數學,是雙賓語句,而他教書,是主謂賓句型
        if (NounBox2 == "")
        {
            SentenceType = "主謂賓";
        }
        else
        {
            UnityEngine.Debug.Log("主語:" + FindSubject);
            UnityEngine.Debug.Log("謂語:" + FindVerb);
            UnityEngine.Debug.Log("間接賓語:" + FindJianObject);
            UnityEngine.Debug.Log("直接賓語:" + FindZhiObject);
        }
    }

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        if (RightPart != "")
        {
            FindObject = SearchNoun(RightPart);//在謂語動詞右邊句找名詞(賓語)
        }

        //顯示結果
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
    }

    if (SentenceType == "賓語補足語")//賓語補足語句型
    {
        //謂語動詞到賓語補足語動詞之間的部分裡的名詞,是賓語名詞
        string temp = "";
        //擷取謂語動詞FindVerb和賓語補足語動詞FindBuVerb之間的部分
        temp = shuru.Substring(shuru.IndexOf(FindVerb) + FindVerb.Length, shuru.IndexOf(FindBuVerb) - (shuru.IndexOf(FindVerb) + FindVerb.Length));
        FindObject = SearchNoun(temp);//找名詞
        //賓語補足語右邊句的名詞,是賓語補足語名詞,而不是賓語名詞
        int WordLastChar = shuru.IndexOf(FindBuVerb) + FindBuVerb.Length;//賓語補足語動詞最後一個字元的位置
        if (WordLastChar < shuru.Length)//賓語補足語動詞最後一個字元的位置沒有到全句末尾,就是說賓語補足語動詞後面還有內容,那就是賓語補足語名詞
        {
            //擷取賓語補足語動詞右邊的內容
            FindBuNoun = shuru.Substring(shuru.IndexOf(FindBuVerb) + FindBuVerb.Length, shuru.Length - (shuru.IndexOf(FindBuVerb) + FindBuVerb.Length));
        }

        //顯示結果
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("賓語補足語動詞:" + FindBuVerb);
        UnityEngine.Debug.Log("賓語補足語名詞:" + FindBuNoun);
    }

    

    /*
    靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

    第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    所以建立一個函式:WordCover(覆蓋)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。

    第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    對於第二個問題的解決方法:
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    所以建立一個de函式。

    第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。
    所以建立一個VerbJudge函式。
    */
}

string SearchNoun(string PartSentence)
{
    //找名詞
    string jieguo = "不包含";//預設值是不包含
    string FindNoun = "";//要找的名詞
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞

    //for迴圈前,先把詞語槽清空,因為for迴圈時,呼叫的函式WordCover要用詞語槽,來完成詞語的覆蓋和吸收
    NounBox1 = "";
    NounBox2 = "";
    NounBox3 = "";
    NounBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//包含
        {
            jieguo = "包含";
            if (de(PartSentence, noun[n]) == false)//找到的名詞右邊的第一個字元不是“的”字,才算是名詞,否則是名詞所有格
            {
                NounCover(noun[n]);
                FindNoun = NounBox1;
            }
        }
    }

    if (jieguo == "包含")
    {
        return FindNoun;
    }
    else
    {
        return "";
    }
}

void NounCover(string FindWord)
{
    /*
    熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。
    做了4個詞語槽(NounBox),為了以後適應複雜的句子,但簡單的主謂賓句型,一個詞語槽就夠了。
    */
    if (NounBox1 == "" && FindWord != "")//詞語槽還是空的,說明這是找到的第一個詞
    {
        NounBox1 = FindWord;//找到的第1個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽2了
    }
    else if (NounBox1 != "" && FindWord != "")//詞語槽1已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox1))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽1(NounBox1)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽2了
        }
        else if (NounBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽1(NounBox1)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,不要這個詞了,免得填到詞語槽2了
        }
    }

    if (NounBox2 == "" && FindWord != "")//詞語槽2是空的,FindWord經過詞語槽1,沒有覆蓋或吸收,說明FindWord和詞語槽1的詞無關,例如FindWord是竹子
    {
        NounBox2 = FindWord;//找到的第2個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽3了
    }
    else if (NounBox2 != "" && FindWord != "")//詞語槽2已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox2))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽2(NounBox2)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (NounBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽2(NounBox2)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (NounBox3 == "" && FindWord != "")//詞語槽3是空的,FindWord經過詞語槽2,沒有覆蓋或吸收,說明FindWord和詞語槽2的詞無關,例如FindWord是竹子
    {
        NounBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (NounBox3 != "" && FindWord != "")//詞語槽3已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox3))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽3(NounBox3)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (NounBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽3(NounBox3)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (NounBox4 == "" && FindWord != "")//詞語槽4是空的,FindWord經過詞語槽3,沒有覆蓋或吸收,說明FindWord和詞語槽3的詞無關,例如FindWord是竹子
    {
        NounBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (NounBox4 != "" && FindWord != "")//詞語槽4已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox4))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽4(NounBox4)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (NounBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽4(NounBox4)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空
        }
    }

    //排序
    if (NounBox1 != "" && NounBox2 != "")//招到了2個名詞,放在NounBox1和NounBox2
    {
        string temp = "";//臨時變數
        if (shuru.IndexOf(NounBox1) > shuru.IndexOf(NounBox2))//如果NounBox1的名詞在句子中的位置大於NounBox2的名詞在句子中的位置
        {
            //交換位置,在句子中位置小的名詞放前面,從而確保雙賓語句型時,NounBox1放的是間接賓語,NounBox2放的是直接賓語,畢竟間接賓語在直接賓語前面
            temp = NounBox1;
            NounBox1 = NounBox2;
            NounBox2 = temp;
        }
        FindJianObject = NounBox1;
        FindZhiObject = NounBox2;
    }

}

void VerbCover(string str,string FindWord)
{
    if (VerbBox1 == "" && FindWord != "")//動詞槽還是空的,說明這是找到的第一個詞
    {
        VerbBox1 = FindWord;//找到的第1個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽2了
    }
    else if (VerbBox1 != "" && FindWord != "")//動詞槽1已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox1))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽1(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“敲打”覆蓋“打”
            FindWord = "";//置空,免得填到動詞槽2了
        }
        else if (VerbBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽1(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,不要這個詞了,免得填到動詞槽2了
        }
    }

    if (VerbBox2 == "" && FindWord != "")//動詞槽2是空的,FindWord經過動詞槽1,沒有覆蓋或吸收,說明FindWord和動詞槽1的詞無關,例如FindWord是喜歡
    {
        VerbBox2 = FindWord;//找到的第2個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽3了
    }
    else if (VerbBox2 != "" && FindWord != "")//動詞槽2已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox2))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽2(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (VerbBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽2(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (VerbBox3 == "" && FindWord != "")//動詞槽3是空的,FindWord經過動詞槽1和2,沒有覆蓋或吸收,說明FindWord和動詞槽1、2的詞無關,例如FindWord是喜歡
    {
        VerbBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (VerbBox3 != "" && FindWord != "")//動詞槽3已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox3))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽3(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (VerbBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽3(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (VerbBox4 == "" && FindWord != "")//動詞槽4是空的,FindWord經過動詞槽1、2、3,沒有覆蓋或吸收,說明FindWord和動詞槽1、2、3的詞無關,例如FindWord是喜歡
    {
        VerbBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (VerbBox4 != "" && FindWord != "")//動詞槽4已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox4))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽4(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (VerbBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽4(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空
        }
    }

    //排序
    if (VerbBox1 != "" && VerbBox2 != "")//招到了個動詞,放在VerbBox1和VerbBox2
    {
        string temp;//臨時變數
        if (shuru.IndexOf(VerbBox1) > shuru.IndexOf(VerbBox2))//如果VerbBox1的動詞在句子中的位置大於VerbBox2的動詞在句子中的位置
        {
            //交換位置,在句子中位置小動詞的放前面,從而確保VerbBox1放的是謂語動詞,而賓語補足語動詞放到VerbBox2
            temp = VerbBox1;
            VerbBox1 = VerbBox2;
            VerbBox2 = temp;
        }
    }
    
}

bool de(string str,string word)
{
    /*
    熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    
    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }
    UnityEngine.Debug.Log(res);//顯示:的
    以上內容是解釋原理,下面是執行程式:
    */

    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果
    WordLastChar = str.IndexOf(word) + word.Length;
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }

    if (res == "的")
    {
        return true;
    }
    else
    {
        return false;
    }

}

bool VerbJudge(string str,string word)
{
    /*
    “學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞,也就是辨析字。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。
    “壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。

    不容易理解的一處:
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   吹     |   l1    |      電      |
    +----------+---------+--------------+
    “吹”字本身做動詞,但在“電吹風”這個詞裡做名詞,但我不用把“電吹風”這個三個字都判斷,我只要判斷“電吹”兩個字就可以了。

    遇到單字動詞的時候,先看這個字是否在詞性辨析表裡,
    如果在,type_col要求是r1(right1,就是要辨析的字的右邊1個字元),那就看句子中要辨析的字的右邊1個字元是不是符合詞性表中的字,
    如果符合,要辨析的字就是名詞,而不是動詞了。
    例如學生看書,這句話先找到了動詞“學”,在詞性辨析表裡,“學”字的type_col是r1,content_col是“生”字,
    那就在句子中,看“學”字右邊的1個字元是不是“生”字,如果是,“學”字就不做動詞,而做名詞了。

    一個要辨析的字,type_col有四種可能:r1、r2、l1、l2,也就是右邊1個字,右邊2個字,左邊1個字,左邊2個字,那就要會四個方法:
    符合r1:找辨析字右邊1個字元:res = str.Substring(str.IndexOf(word) + word.Length, 1);
    符合r2:找辨析字右邊2個字元:res = str.Substring(str.IndexOf(word) + word.Length, 2);
    符合l1:找辨析字左邊1個字元:res = str.Substring(str.IndexOf(word) - 1, 1);
    符合l2:找辨析字左邊2個字元:res = str.Substring(str.IndexOf(word) - 2, 1);

    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
        res = str.Substring(str.IndexOf(word) + word.Length, 1);//變化形式

    }
    UnityEngine.Debug.Log(res);//顯示:的

    //指定詞語左邊1個字元
    res = str.Substring(index - 1, 1);
    res = str.Substring(str.IndexOf(word) - 1, 1);//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃
    以上內容是解釋原理,下面是執行程式:
    */

    string[] TypeCol = new string[100];//把詞性辨析表的辨析字對應的type_col值填充此陣列
    string[] ContentCol = new string[100];//把詞性辨析表的辨析字對應的content_col值填充此陣列
    string res = "";//擷取的字元
    bool shima = true;//預設判斷是動詞

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    //字元型變數要有引號,數字型變數不需要引號
    //word是變數,動態的,不能直接放到sql語句裡面
    string sqlQuery = "select type_col,content_col from verb_judge where word_col = '" + word + "'";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充詞性辨析陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();

    i = 0;
    while (dbReader.Read())
    {
        //查詢了2列(type_col和content_col),所以返回的結果集有2列,分別用GetValue(0)和GetValue(1)
        TypeCol[i] = dbReader.GetValue(0).ToString();//返回的結果集的第1列
        ContentCol[i] = dbReader.GetValue(1).ToString();//返回的結果集的第2列
        i++;//雖然定義陣列長度為10,但i不一定填滿了10
    }
    dbReader.Close();
    dbConnection.Close();
    
    if (i > 0)//在詞性辨析表裡找到內容了,否則i還是預設的0
    {
        for (int n = 0; n < i; n++)//遍歷詞性辨析表找到的各種結果
        {
            if (TypeCol[n] == "r1")//right1:右邊1個字元
            {
                if (str.IndexOf(word) + word.Length + 1 <= str.Length)//要往右判斷1個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 1);//擷取動詞右邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "r2")//right2:右邊2個字元
            {
                if (str.IndexOf(word) + word.Length + 2 <= str.Length)//要往右判斷2個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 2);//擷取動詞右邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "l1")//left1:左邊1個字元
            {
                if (str.IndexOf(word) - 1 >= 0)//要往左判斷1個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 1, 1);//擷取動詞左邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }

                }
            }
            else if (TypeCol[n] == "l2")//left2:左邊2個字元
            {
                if (str.IndexOf(word) - 2 >= 0)//要往左判斷2個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 2, 2);//擷取動詞左邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
        }
    }
    i = 0;
    return shima;
}

string SentenceJudge()
{
    /*
    判斷句型:
    基本單句有六種句型:
    只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
    主語(動作執行者)-謂語(動作):張三摔倒。
    主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
    主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
    雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
    賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
    前面只說了主謂賓句型,還要處理其它句型。

    雙賓語句型:
    雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
    但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
    雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
    那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
    還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
    僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
    名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

    賓語補足語句型:
    和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
    因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
    但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
    既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
    動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
    賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

    雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

    在主謂賓句型的基礎上,如果沒有賓語,就是主謂句型。如果沒有主語,就是省略主語,例如對一個人喊“過來”,這句話的全句顯然是“你過來”。
    */

    if (VerbBox1 == "")//沒有動詞
    {
        return "只有性質狀態";//只有性質狀態的句型
    }
    else if (VerbBox1 != "" && VerbBox2 == "")//有1個動詞
    {
        if (VerbBox1 == "給" || VerbBox1 == "送" || VerbBox1 == "送給" || VerbBox1 == "教")//雙賓語句型的常見動詞(標誌詞)
        {
            return "雙賓語";//雙賓語句型
        }
        else
        {
            return "主謂賓";//主謂賓句型
        }
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//有2個動詞
    {
        return "賓語補足語";//賓語補足語句型
    }
    else
    {
        return "其它";
    }
}

}

第三章

省略主語有兩種情況:一種是主動語態省略主語,例如“跳過去”,全句指“你跳過去”。另一種是被動語態省略主語,例如“張三被打了”,沒說誰打了張三,這裡張三是賓語。如果說“李四打了張三”,李四就是主語。
被動語態的標誌是“被”字,如果沒有“被”字,而且省略了主語,就是主動語態省略主語的情況,那麼這種情況下,主語應該填什麼呢?例如“過來”,一般指“你過來”,但“走吧”一般指“我們走吧”。所以程式要根據具體的動詞來判斷省略的主語應該填什麼。但是動詞太多,每個動詞都要設定省略的主語判斷,太麻煩。所以省略主語,按最通常情況,就預設填“你”字,作為主語。如果主語是“我們”而不是“你”字,就不該省略主語。
被動語態應該還原為主動語態去理解,但被動語態往往沒有主語,那麼預設主語應該填什麼呢?畢竟不知道主語,那就填“事物”這個詞作為主語。
程式分析句子時,被動語態的主語位置的詞,是賓語。例如“李四被打了”,李四在謂語動詞左邊句,程式會把李四當成主語,但在被動語態句裡,李四不是主語,所以有“被”字的時候,主語要挪動到賓語位置,然後在主語位置補充“事物”這個詞,作為主語。
但是有些時候,被動語態的主語是說明了的,例如“李四被張三打了”就還原為主動語態“張三打了李四”,張三做主語,而不是填“事物”做主語。
簡而言之,被動語態裡,主語放到了賓語位置,賓語放到了主語位置,所以變為主動語態時,要把賓語挪回主語位置,主語挪回賓語位置。
如果被動語態有主語,例如“李四被張三打了”,那麼主語(張三)位於“被”字與謂語動詞之間。
那麼謂語動詞左邊句中,又分為“被”字左邊句和“被”字右邊句,被字左邊句裡的名詞是賓語,被字右邊句裡的名詞是主語。

名詞合併:
名詞合併:例如“足球學校”這個詞,會被當成兩個名詞“足球”和“學校”。但實際中,要把它們合併成一個組合名詞,作為主語或賓語。
合併方法:如果兩個字元(詞語)是連續的,那麼這兩個詞語之間的內容為空。

動詞合併:
例如“應該愛”是兩個動詞:情態動詞“應該”和普通動詞“愛”,應該合併成一個動詞。

動詞前面是否有否定詞,也很重要。
例如“他愛貓”和“他不愛貓”,雖然謂語動詞都是“愛”字,但前面加個“不”字,意義就相反了。所以看謂語動詞前面是否有否定詞,是很重要的事。
謂語動詞前面的否定詞,一般有不、不要、不可以、不應該、不能、別。
還有不確定肯定還是否定動詞,例如“他不一定去”,“去”字是動詞,但是動詞前的“不一定”,並不像是“不”字那樣對動詞進行否定,而是對動詞既不像是肯定,也不像是否定,而是不確定。
因此對每句話的謂語動詞,都要加一個性質:肯定、否定、不確定。
但不確定,有時候偏向於肯定,例如“他可能去”。有時候不確定偏向於否定,例如“他不太可能去”以及“他或許不去”。
那麼動詞發生機率分為五種:肯定、偏向肯定、不確定、偏向否定、否定。
這其實就是在分析事情(謂語動詞)發生的機率,這在機率分析上有用。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Mono.Data.Sqlite;

public class sqlitecon : MonoBehaviour
{
public TMP_Text tmpText;//輸出框物件
string ShowText;//輸出框的內容
string[] noun = new string[7128];//名詞陣列,名詞數量7128
string[] verb = new string[5886];//動詞陣列,動詞數量5886
int i = 0;//陣列用的迴圈變數
public TMP_InputField inputField;//輸入框物件
string shuru = "";//輸入框的內容

string FindSubject = "";//找到的主語
string FindVerb = "";//找到的謂語動詞
string FindObject = "";//找到的賓語
string FindBuVerb = "";//賓語補足語的動詞
string FindBuNoun = "";//賓語補足語的名詞
string FindJianObject = "";//找到的間接賓語
string FindZhiObject = "";//找到的直接賓語

string SentenceType = "";//句型
string yutai = "";//語態:主動語態還是被動語態
string VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定

string NounBox1 = "";//名詞槽1
string NounBox2 = "";//名詞槽2
string NounBox3 = "";//名詞槽3
string NounBox4 = "";//名詞槽4

string VerbBox1 = "";//動詞槽1
string VerbBox2 = "";//動詞槽2
string VerbBox3 = "";//動詞槽3
string VerbBox4 = "";//動詞槽4

// Start is called before the first frame update
void Start()
{
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量

    dbConnection.Close();
}

// Update is called once per frame
void Update()
{

}

void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的值

    //找謂語動詞
    string jieguo = "不包含";//預設值是不包含動詞
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞

    VerbBox1 = "";
    VerbBox2 = "";
    VerbBox3 = "";
    VerbBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (shuru.Contains(verb[n]))//包含動詞
        {
            if (VerbJudge(shuru,verb[n]) == true)//是動詞,不是名詞
            {
                jieguo = "包含";
                FindVerb = verb[n];//找到了動詞
                VerbCover(shuru,verb[n]);//把動詞放入動詞槽裡,看看有幾個動詞
                VerbOrder();//動詞排序
                VerbJoin();//動詞結合
            }
        }
    }

    if(jieguo == "包含")//包含動詞
    {
        VerbRateJudge();//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
        SentenceType = SentenceJudge();//判斷句型(僅從動詞情況來判斷句型,還不是完全清楚的判斷,之後還需進一步判斷)
        SplitSentence();
    }
}

void SplitSentence()
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string word = "嘲笑";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞語的起始位置
    int LastIndex = 0;//指定詞語最後一個字元在全句中的位置
    int jie = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    //計算指定字元在全句中的位置
    index = str.IndexOf(word) + 1;//預設從0計算,例如第2個字元,顯示為1,而不是2。為了調整為1開始計算,所以加1
    //計算指定詞語最後一個字元在全句中的位置
    LastIndex = str.IndexOf(word) + word.Length;

    //擷取第3個字元右邊的1個字元
    Substring(開始位置, 向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元

    //擷取指定字元右邊的全部字元
    jie = chang - LastIndex;//擷取長度 = 全句長度 - 指定詞語最後一個字元的位置長度
    res = str.Substring(LastIndex, jie);
    res = str.Substring(str.IndexOf(word) + word.Length, str.Length - (str.IndexOf(word) + word.Length));//展開形式

    //擷取指定字元左邊的全部字元
    res = str.Substring(0, index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0, str.IndexOf(word));//變化形式

    //擷取兩個指定字元之間的全部字元
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    以上註釋掉的內容,只是解釋原理,下面是執行的程式:
    */

    string LeftPart = "";//謂語動詞的左邊句
    string RightPart = "";//謂語動詞的右邊句

    //也可能找到一個動詞(主謂賓句型),也可能找到兩個動詞(賓語補足語句型)
    if (VerbBox1 != "" && VerbBox2 == "")//只找到1個動詞,那就是謂語動詞
    {
        FindVerb = VerbBox1;
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//找到2個動詞
    {
        FindVerb = VerbBox1;//位次在前面的動詞是謂語動詞
        FindBuVerb = VerbBox2;//位次在後面的動詞是賓語補足語動詞
    }

    LeftPart = shuru.Substring(0, shuru.IndexOf(FindVerb));
    RightPart = shuru.Substring(shuru.IndexOf(FindVerb) + FindVerb.Length, shuru.Length - (shuru.IndexOf(FindVerb) + FindVerb.Length));

    /*
    例如句子(shuru)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);
    UnityEngine.Debug.Log(LeftPart);
    UnityEngine.Debug.Log(RightPart);
    */

    /*
    省略主語有兩種情況:一種是主動語態省略主語,例如“跳過去”,全句指“你跳過去”。另一種是被動語態省略主語,例如“張三被打了”,沒說誰打了張三,這裡張三是賓語。如果說“李四打了張三”,李四就是主語。
    被動語態的標誌是“被”字,如果沒有“被”字,而且省略了主語,就是主動語態省略主語的情況,那麼這種情況下,主語應該填什麼呢?例如“過來”,一般指“你過來”,但“走吧”一般指“我們走吧”。所以程式要根據具體的動詞來判斷省略的主語應該填什麼。但是動詞太多,每個動詞都要設定省略的主語判斷,太麻煩。所以省略主語,按最通常情況,就預設填“你”字,作為主語。如果主語是“我們”而不是“你”字,就不該省略主語。
    被動語態應該還原為主動語態去理解,但被動語態往往沒有主語,那麼預設主語應該填什麼呢?畢竟不知道主語,那就填“事物”這個詞作為主語。
    程式分析句子時,被動語態的主語位置的詞,是賓語。例如“李四被打了”,李四在謂語動詞左邊句,程式會把李四當成主語,但在被動語態句裡,李四不是主語,所以有“被”字的時候,主語要挪動到賓語位置,然後在主語位置補充“事物”這個詞,作為主語。
    但是有些時候,被動語態的主語是說明了的,例如“李四被張三打了”就還原為主動語態“張三打了李四”,張三做主語,而不是填“事物”做主語。
    簡而言之,被動語態裡,主語放到了賓語位置,賓語放到了主語位置,所以變為主動語態時,要把賓語挪回主語位置,主語挪回賓語位置。
    如果被動語態有主語,例如“李四被張三打了”,那麼主語(張三)位於“被”字與謂語動詞之間。
    那麼謂語動詞左邊句中,又分為“被”字左邊句和“被”字右邊句,被字左邊句裡的名詞是賓語,被字右邊句裡的名詞是主語。
    */
    yutai = "主動";//預設主動語態
    if (SentenceType == "主謂賓" && shuru.Contains("被"))//語句中包含“被”字
    {
        if (shuru.Contains("被子") == false && shuru.Contains("被褥") == false)//語句中包含“被”字,但不是“被子”這個名詞,才能指被動語態的“被”字
        {
            yutai = "被動";//被動語態
        }
        else
        {
            yutai = "主動";//主動語態
        }
    }
    else//語句中沒有包含“被”字
    {
        yutai = "主動";//主動語態
    }

    if (LeftPart != "")//謂語動詞左邊句有內容
    {
        if (yutai == "主動")//主動語態
        {
            FindSubject = SearchNoun(LeftPart);//在謂語動詞左邊句找名詞(主語)
        }
        else if (yutai == "被動")//被動語態
        {
            string bei = "被";
            string BeiLeft = "";
            string BeiRight = "";

            //被字左邊句
            BeiLeft = LeftPart.Substring(0, LeftPart.IndexOf(bei));
            FindObject = SearchNoun(BeiLeft);//被字左邊句的名詞是賓語
            //被字右邊句
            BeiRight = LeftPart.Substring(LeftPart.IndexOf(bei) + bei.Length, LeftPart.Length - (LeftPart.IndexOf(bei) + bei.Length));
            FindSubject = SearchNoun(BeiRight);//被字右邊句的名詞是主語
            //如果沒有主語,就填補“事物”這個詞作為主語,畢竟被動語態經常沒有主語
            if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
            {
                FindSubject = "事物";
            }
        }
    }

    //如果省略主語,則填補省略的主語
    if (yutai == "主動")
    {
        if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
        {
            FindSubject = "你";//預設填補“你”字做主語
        }
    }

    if (SentenceType == "雙賓語")//雙賓語句型
    {
        FindObject = SearchNoun(RightPart);//找名詞

        //謂語動詞右邊句裡,沒有第二個賓語名詞,那就不是雙賓語
        //例如雖然有雙賓語句的標誌動詞“教”字,但他教我數學,是雙賓語句,而他教書,是主謂賓句型
        if (NounBox2 == "")
        {
            SentenceType = "主謂賓";
        }
        else
        {
            ShowResult();//顯示最終輸出結果
        }
    }

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        if (RightPart != "")
        {
            if (yutai == "主動")
            {
                FindObject = SearchNoun(RightPart);//在謂語動詞右邊句找名詞(賓語)
            }
        }

        ShowResult();//顯示最終輸出結果
    }

    if (SentenceType == "賓語補足語")//賓語補足語句型
    {
        //謂語動詞到賓語補足語動詞之間的部分裡的名詞,是賓語名詞
        string temp = "";
        //擷取謂語動詞FindVerb和賓語補足語動詞FindBuVerb之間的部分
        temp = shuru.Substring(shuru.IndexOf(FindVerb) + FindVerb.Length, shuru.IndexOf(FindBuVerb) - (shuru.IndexOf(FindVerb) + FindVerb.Length));
        FindObject = SearchNoun(temp);//找名詞
        //賓語補足語右邊句的名詞,是賓語補足語名詞,而不是賓語名詞
        int WordLastChar = shuru.IndexOf(FindBuVerb) + FindBuVerb.Length;//賓語補足語動詞最後一個字元的位置
        if (WordLastChar < shuru.Length)//賓語補足語動詞最後一個字元的位置沒有到全句末尾,就是說賓語補足語動詞後面還有內容,那就是賓語補足語名詞
        {
            //擷取賓語補足語動詞右邊的內容
            FindBuNoun = shuru.Substring(shuru.IndexOf(FindBuVerb) + FindBuVerb.Length, shuru.Length - (shuru.IndexOf(FindBuVerb) + FindBuVerb.Length));
        }

        ShowResult();//顯示最終輸出結果
    }

    /*
    靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

    第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    所以建立一個函式:WordCover(覆蓋)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。

    第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    對於第二個問題的解決方法:
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    所以建立一個de函式。

    第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。
    所以建立一個VerbJudge函式。
    */
}

string SearchNoun(string PartSentence)
{
    //找名詞
    string jieguo = "不包含";//預設值是不包含
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞

    //for迴圈前,先把詞語槽清空,因為for迴圈時,呼叫的函式WordCover要用詞語槽,來完成詞語的覆蓋和吸收
    NounBox1 = "";
    NounBox2 = "";
    NounBox3 = "";
    NounBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//包含
        {
            jieguo = "包含";
            if (de(PartSentence, noun[n]) == false)//找到的名詞右邊的第一個字元不是“的”字,才算是名詞,否則是名詞所有格
            {
                NounCover(noun[n]);
            }
        }
    }

    if (jieguo == "包含")//找到了名詞
    {
        NounOrder();//名詞排序
        //名詞要先排序,才能合併名詞,否則“足球”和“學校”的順序如果變成“學校”和“足球”,那就合併成“學校足球”這個詞了,而不是“足球學校”

        //如果雙賓語句型進行名詞合併,就可能會把間接賓語名詞和直接賓語名詞合併到一起,成為一個名詞,就不對了
        if (SentenceType != "雙賓語")//不是雙賓語句型
        {
            NounJoin();//名詞合併,例如把“足球”和“學校”合併成“足球學校”這一個名詞
        }
        else if (SentenceType == "雙賓語")//是雙賓語句型
        {
            //但是如果現在處理的是雙賓語結構的謂語動詞左邊句,也就是處理主語,還是可以名詞合併的
            if (shuru.IndexOf(NounBox1) < shuru.IndexOf(FindVerb))
            {
                NounJoin();//名詞合併
            }
        }

        return NounBox1;
    }
    else
    {
        return "";
    }
}

void NounCover(string FindWord)
{
    /*
    熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。
    做了4個詞語槽(NounBox),為了以後適應複雜的句子,但簡單的主謂賓句型,一個詞語槽就夠了。
    */
    if (NounBox1 == "" && FindWord != "")//詞語槽還是空的,說明這是找到的第一個詞
    {
        NounBox1 = FindWord;//找到的第1個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽2了
    }
    else if (NounBox1 != "" && FindWord != "")//詞語槽1已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox1))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽1(NounBox1)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽2了
        }
        else if (NounBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽1(NounBox1)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,不要這個詞了,免得填到詞語槽2了
        }
    }

    if (NounBox2 == "" && FindWord != "")//詞語槽2是空的,FindWord經過詞語槽1,沒有覆蓋或吸收,說明FindWord和詞語槽1的詞無關,例如FindWord是竹子
    {
        NounBox2 = FindWord;//找到的第2個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽3了
    }
    else if (NounBox2 != "" && FindWord != "")//詞語槽2已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox2))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽2(NounBox2)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (NounBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽2(NounBox2)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (NounBox3 == "" && FindWord != "")//詞語槽3是空的,FindWord經過詞語槽2,沒有覆蓋或吸收,說明FindWord和詞語槽2的詞無關,例如FindWord是竹子
    {
        NounBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (NounBox3 != "" && FindWord != "")//詞語槽3已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox3))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽3(NounBox3)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (NounBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽3(NounBox3)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (NounBox4 == "" && FindWord != "")//詞語槽4是空的,FindWord經過詞語槽3,沒有覆蓋或吸收,說明FindWord和詞語槽3的詞無關,例如FindWord是竹子
    {
        NounBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (NounBox4 != "" && FindWord != "")//詞語槽4已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox4))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽4(NounBox4)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (NounBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽4(NounBox4)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空
        }
    }

    /*
    “足球”這個詞,會找到三個名詞:足、球、足球。
    先找到第一個詞:足,放入NounBox1。
    再找到第二個詞:球,放入NounBox2。
    再找到第三個詞:足球,會覆蓋NounBox1的“足”字,但卻無法覆蓋NounBox2的球字。
    因此程式做一些改進。

    但如果幸運的:
    先找到第一個詞:足球,放入NounBox1。
    再找到第二個詞:足,被NounBox1“足球”這個詞吸收,不會進入到NounBox2。
    再找到第三個詞:球,被NounBox1“足球”這個詞吸收,也不會進入到NounBox2。
    那麼就不用執行下面這段程式了。
    先找到那個詞是不確定的,詞庫詞語可能按筆畫排序,也可能按首字母排序,就不知道先找到那個詞了。

    如果輸入的是“皮球”這個詞,而詞庫裡沒有“皮球”這個詞,但有“皮”字和“球”字這兩個詞。
    那麼,NounBox1是“皮”字,NounBox2是“球”字,或NounBox1是“球”字,NounBox2是“皮”字,沒有覆蓋和吸收。
    */
    if (NounBox1.Contains(NounBox2))//NounBox1包含了NounBox2,例如“足球”包含“球”字
    {
        NounBox2 = "";
        if (NounBox3 != "")
        {
            NounBox2 = NounBox3;
            NounBox3 = "";
        }
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox2.Contains(NounBox3))//NounBox2包含了NounBox3
    {
        NounBox3 = "";
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox3.Contains(NounBox4))//NounBox3包含了NounBox4
    {
        NounBox4 = "";
    }
}

void VerbCover(string str,string FindWord)
{
    if (VerbBox1 == "" && FindWord != "")//動詞槽還是空的,說明這是找到的第一個詞
    {
        VerbBox1 = FindWord;//找到的第1個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽2了
    }
    else if (VerbBox1 != "" && FindWord != "")//動詞槽1已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox1))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽1(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“敲打”覆蓋“打”
            FindWord = "";//置空,免得填到動詞槽2了
        }
        else if (VerbBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽1(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,不要這個詞了,免得填到動詞槽2了
        }
    }

    if (VerbBox2 == "" && FindWord != "")//動詞槽2是空的,FindWord經過動詞槽1,沒有覆蓋或吸收,說明FindWord和動詞槽1的詞無關,例如FindWord是喜歡
    {
        VerbBox2 = FindWord;//找到的第2個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽3了
    }
    else if (VerbBox2 != "" && FindWord != "")//動詞槽2已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox2))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽2(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (VerbBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽2(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (VerbBox3 == "" && FindWord != "")//動詞槽3是空的,FindWord經過動詞槽1和2,沒有覆蓋或吸收,說明FindWord和動詞槽1、2的詞無關,例如FindWord是喜歡
    {
        VerbBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (VerbBox3 != "" && FindWord != "")//動詞槽3已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox3))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽3(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (VerbBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽3(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (VerbBox4 == "" && FindWord != "")//動詞槽4是空的,FindWord經過動詞槽1、2、3,沒有覆蓋或吸收,說明FindWord和動詞槽1、2、3的詞無關,例如FindWord是喜歡
    {
        VerbBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (VerbBox4 != "" && FindWord != "")//動詞槽4已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox4))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽4(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (VerbBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽4(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空
        }
    }

    /*
    “敲打”這個詞,會找到三個動詞:敲、打、敲打
    先找到第一個詞:敲,放入VerbBox1
    再找到第二個詞:打,放入VerbBox2
    再找到第三個詞:敲打,會覆蓋VerbBox1的“敲”字,但卻無法覆蓋VerbBox2的“打”字
    因此程式做一些改進。 
    */
    if (VerbBox1.Contains(VerbBox2))//VerbBox1包含了VerbBox2
    {
        VerbBox2 = "";
        if (VerbBox3 != "")
        {
            VerbBox2 = VerbBox3;
            VerbBox3 = "";
        }
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox2.Contains(VerbBox3))//VerbBox2包含了VerbBox3
    {
        VerbBox3 = "";
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox3.Contains(VerbBox4))//VerbBox3包含了VerbBox4
    {
        VerbBox4 = "";
    }
}

bool de(string str,string word)
{
    /*
    熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    
    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }
    UnityEngine.Debug.Log(res);//顯示:的
    以上註釋掉的內容只是解釋原理,下面是執行程式:
    */

    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果
    WordLastChar = str.IndexOf(word) + word.Length;
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }

    if (res == "的")
    {
        return true;
    }
    else
    {
        return false;
    }

}

bool VerbJudge(string str,string word)
{
    /*
    “學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞,也就是辨析字。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。
    “壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。

    不容易理解的一處:
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   吹     |   l1    |      電      |
    +----------+---------+--------------+
    “吹”字本身做動詞,但在“電吹風”這個詞裡做名詞,但我不用把“電吹風”這個三個字都判斷,我只要判斷“電吹”兩個字就可以了。

    遇到單字動詞的時候,先看這個字是否在詞性辨析表裡,
    如果在,type_col要求是r1(right1,就是要辨析的字的右邊1個字元),那就看句子中要辨析的字的右邊1個字元是不是符合詞性表中的字,
    如果符合,要辨析的字就是名詞,而不是動詞了。
    例如學生看書,這句話先找到了動詞“學”,在詞性辨析表裡,“學”字的type_col是r1,content_col是“生”字,
    那就在句子中,看“學”字右邊的1個字元是不是“生”字,如果是,“學”字就不做動詞,而做名詞了。

    一個要辨析的字,type_col有四種可能:r1、r2、l1、l2,也就是右邊1個字,右邊2個字,左邊1個字,左邊2個字,那就要會四個方法:
    符合r1:找辨析字右邊1個字元:res = str.Substring(str.IndexOf(word) + word.Length, 1);
    符合r2:找辨析字右邊2個字元:res = str.Substring(str.IndexOf(word) + word.Length, 2);
    符合l1:找辨析字左邊1個字元:res = str.Substring(str.IndexOf(word) - 1, 1);
    符合l2:找辨析字左邊2個字元:res = str.Substring(str.IndexOf(word) - 2, 1);

    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
        res = str.Substring(str.IndexOf(word) + word.Length, 1);//變化形式

    }
    UnityEngine.Debug.Log(res);//顯示:的

    //指定詞語左邊1個字元
    res = str.Substring(index - 1, 1);
    res = str.Substring(str.IndexOf(word) - 1, 1);//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃
    以上註釋掉的內容,只是解釋原理,下面是執行程式:
    */

    string[] TypeCol = new string[100];//把詞性辨析表的辨析字對應的type_col值填充此陣列
    string[] ContentCol = new string[100];//把詞性辨析表的辨析字對應的content_col值填充此陣列
    string res = "";//擷取的字元
    bool shima = true;//預設判斷是動詞

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    //字元型變數要有引號,數字型變數不需要引號
    //word是變數,動態的,不能直接放到sql語句裡面
    string sqlQuery = "select type_col,content_col from verb_judge where word_col = '" + word + "'";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充詞性辨析陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();

    i = 0;
    while (dbReader.Read())
    {
        //查詢了2列(type_col和content_col),所以返回的結果集有2列,分別用GetValue(0)和GetValue(1)
        TypeCol[i] = dbReader.GetValue(0).ToString();//返回的結果集的第1列
        ContentCol[i] = dbReader.GetValue(1).ToString();//返回的結果集的第2列
        i++;//雖然定義陣列長度為10,但i不一定填滿了10
    }
    dbReader.Close();
    dbConnection.Close();
    
    if (i > 0)//在詞性辨析表裡找到內容了,否則i還是預設的0
    {
        for (int n = 0; n < i; n++)//遍歷詞性辨析表找到的各種結果
        {
            if (TypeCol[n] == "r1")//right1:右邊1個字元
            {
                if (str.IndexOf(word) + word.Length + 1 <= str.Length)//要往右判斷1個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 1);//擷取動詞右邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "r2")//right2:右邊2個字元
            {
                if (str.IndexOf(word) + word.Length + 2 <= str.Length)//要往右判斷2個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 2);//擷取動詞右邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "l1")//left1:左邊1個字元
            {
                if (str.IndexOf(word) - 1 >= 0)//要往左判斷1個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 1, 1);//擷取動詞左邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }

                }
            }
            else if (TypeCol[n] == "l2")//left2:左邊2個字元
            {
                if (str.IndexOf(word) - 2 >= 0)//要往左判斷2個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 2, 2);//擷取動詞左邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
        }
    }
    i = 0;
    return shima;
}

string SentenceJudge()
{
    /*
    判斷句型:
    基本單句有六種句型:
    只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
    主語(動作執行者)-謂語(動作):張三摔倒。
    主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
    主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
    雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
    賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
    前面只說了主謂賓句型,還要處理其它句型。

    雙賓語句型:
    雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
    但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
    雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
    那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
    還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
    僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
    名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

    賓語補足語句型:
    和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
    因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
    但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
    既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
    動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
    賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

    雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

    在主謂賓句型的基礎上,如果沒有賓語,就是主謂句型。如果沒有主語,就是省略主語,例如對一個人喊“過來”,這句話的全句顯然是“你過來”。
    */

    if (VerbBox1 == "")//沒有動詞
    {
        return "只有性質狀態";//只有性質狀態的句型
    }
    else if (VerbBox1 != "" && VerbBox2 == "")//有1個動詞
    {
        if (VerbBox1 == "給" || VerbBox1 == "送" || VerbBox1 == "送給" || VerbBox1 == "教")//雙賓語句型的常見動詞(標誌詞)
        {
            return "雙賓語";//雙賓語句型
        }
        else
        {
            return "主謂賓";//主謂賓句型
        }
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//有2個動詞
    {
        return "賓語補足語";//賓語補足語句型
    }
    else
    {
        return "其它";
    }
}

void NounOrder()
{
    //名詞排序
    if (NounBox1 != "" && NounBox2 != "")//招到了2個名詞,放在NounBox1和NounBox2
    {
        string temp = "";//臨時變數
        if (shuru.IndexOf(NounBox1) > shuru.IndexOf(NounBox2))//如果NounBox1的名詞在句子中的位置大於NounBox2的名詞在句子中的位置
        {
            //交換位置,在句子中位置小的名詞放前面,從而確保雙賓語句型時,NounBox1放的是間接賓語,NounBox2放的是直接賓語,畢竟間接賓語在直接賓語前面
            temp = NounBox1;
            NounBox1 = NounBox2;
            NounBox2 = temp;
        }
        FindJianObject = NounBox1;
        FindZhiObject = NounBox2;
    }
}

void NounJoin()
{
    /*
    名詞合併:例如“足球學校”這個詞,會被當成兩個名詞“足球”和“學校”。但實際中,要把它們合併成一個組合名詞,作為主語或賓語。
    前面說了判斷兩個字元之間的內容,如果兩個字元(詞語)是連續的,那麼這兩個詞語之間的內容為空。
    示例:
    //擷取兩個指定字元之間的全部字元
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string res = "";//結果
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式
    if (res == "")
    {
        UnityEngine.Debug.Log("連續");
    }
    else
    {
        UnityEngine.Debug.Log("不連續");
    }
    */
    
    string res;
    //判斷NounBox1和NounBox2的名詞是否需要合併
    if (NounBox1 != "" && NounBox2 != "")
    {
        res = "";
        //判斷NounBox1和NounBox2之間是否有內容,如果沒內容(res為空),就說明NounBox1和NounBox2是連續的名詞(中間沒有字元間隔),需要合併
        res = shuru.Substring(shuru.IndexOf(NounBox1) + NounBox1.Length, shuru.IndexOf(NounBox2) - (shuru.IndexOf(NounBox1) + NounBox1.Length));
        if (res == "")
        {
            NounBox1 = NounBox1 + NounBox2;//名詞合併
            NounBox2 = "";//合併後,置空
            if (NounBox3 != "")
            {
                NounBox2 = NounBox3;//填補置空的值,否則NounBox1有值,NounBox2為空,NounBox3又有值,就間隔了
                NounBox3 = "";//合併後,置空
                if (NounBox4 != "")
                {
                    NounBox3 = NounBox4;
                    NounBox4 = "";//合併後,置空
                }
            }
        }
    }

    /*
    //判斷NounBox2和NounBox3的名詞是否需要合併
    if (NounBox2 != "" && NounBox3 != "")
    {
        res = "";
        //判斷NounBox2和NounBox3之間是否有內容,如果沒內容(res為空),就說明NounBox2和NounBox3是連續的名詞,需要合併
        res = shuru.Substring(shuru.IndexOf(NounBox2) + NounBox2.Length, shuru.IndexOf(NounBox3) - (shuru.IndexOf(NounBox2) + NounBox2.Length));
        if (res == "")
        {
            NounBox2 = NounBox2 + NounBox3;//名詞合併
            NounBox3 = "";//合併後,置空
            if (NounBox4 != "")
            {
                NounBox3 = NounBox4;//填補置空的值
                NounBox4 = "";//合併後,置空
            }
        }
    }

    //判斷NounBox3和NounBox4的名詞是否需要合併
    if (NounBox3 != "" && NounBox4 != "")
    {
        res = "";
        //判斷NounBox3和NounBox4之間是否有內容,如果沒內容(res為空),就說明NounBox3和NounBox4是連續的名詞,需要合併
        res = shuru.Substring(shuru.IndexOf(NounBox3) + NounBox3.Length, shuru.IndexOf(NounBox4) - (shuru.IndexOf(NounBox3) + NounBox3.Length));
        if (res == "")
        {
            NounBox3 = NounBox3 + NounBox4;//名詞合併
            NounBox4 = "";//合併後,置空
        }
    }
    */
}

void VerbOrder()
{
    /*
    動詞排序:
    如果不排序會怎樣?句子中找到的第一個動詞,可能不是謂語動詞,而是賓語補足語動詞,以賓語補足語動詞分割句子,就錯了。
    謂語動詞和賓語補足語動詞,先找到哪個,取決於這兩個詞,誰在動詞表前面排序,而動詞的排序是不可知的,或許按筆劃排序,或者按首字母排序
    */
    string temp = "";//臨時變數
    if (VerbBox1 != "" && VerbBox2 != "")//招到了個動詞,放在VerbBox1和VerbBox2
    {
        if (shuru.IndexOf(VerbBox1) > shuru.IndexOf(VerbBox2))//如果VerbBox1的動詞在句子中的位置大於VerbBox2的動詞在句子中的位置
        {
            //交換位置,在句子中位置小動詞的放前面,從而確保VerbBox1放的是謂語動詞,而賓語補足語動詞放到VerbBox2
            temp = VerbBox1;
            VerbBox1 = VerbBox2;
            VerbBox2 = temp;
        }

    }
    if (VerbBox3 != "")
    {
        if (shuru.IndexOf(VerbBox1) > shuru.IndexOf(VerbBox3))
        {
            temp = VerbBox1;
            VerbBox1 = VerbBox3;
            VerbBox3 = temp;
        }
        if (shuru.IndexOf(VerbBox2) > shuru.IndexOf(VerbBox3))
        {
            temp = VerbBox2;
            VerbBox2 = VerbBox3;
            VerbBox3 = temp;
        }
    }
    FindVerb = VerbBox1;
}

void VerbJoin()
{
    //動詞合併:例如“應該愛”是兩個動詞:情態動詞“應該”和普通動詞“愛”,應該合併成一個動詞
    string res;
    //判斷VerbBox1和VerbBox2的動詞是否需要合併
    if (VerbBox1 != "" && VerbBox2 != "")
    {
        res = "";
        //判斷VerbBox1和VerbBox2之間是否有內容,如果沒內容(res為空),就說明VerbBox1和VerbBox2是連續的動詞(中間沒有字元間隔),需要合併
        res = shuru.Substring(shuru.IndexOf(VerbBox1) + VerbBox1.Length, shuru.IndexOf(VerbBox2) - (shuru.IndexOf(VerbBox1) + VerbBox1.Length));
        if (res == "")
        {
            VerbBox1 = VerbBox1 + VerbBox2;//名詞合併
            FindVerb = VerbBox1;
            VerbBox2 = "";//合併後,置空
            if (VerbBox3 != "")
            {
                VerbBox2 = VerbBox3;//填補置空的值,否則VerbBox1有值,VerbBox2為空,VerbBox3又有值,就間隔了
                VerbBox3 = "";//合併後,置空
                if (VerbBox4 != "")
                {
                    VerbBox3 = VerbBox4;
                    VerbBox4 = "";//合併後,置空
                }
            }
        }
    }

}

void VerbRateJudge()
{
    /*
    動詞前面是否有否定詞,也很重要。
    例如“他愛貓”和“他不愛貓”,雖然謂語動詞都是“愛”字,但前面加個“不”字,意義就相反了。所以看謂語動詞前面是否有否定詞,是很重要的事。
    謂語動詞前面的否定詞,一般有不、不要、不可以、不應該、不能、別。
    還有不確定肯定還是否定動詞,例如“他不一定去”,“去”字是動詞,但是動詞前的“不一定”,並不像是“不”字那樣對動詞進行否定,而是對動詞既不像是肯定,也不像是否定,而是不確定。
    因此對每句話的謂語動詞,都要加一個性質:肯定、否定、不確定。
    但不確定,有時候偏向於肯定,例如“他可能去”。有時候不確定偏向於否定,例如“他不太可能去”以及“他或許不去”。
    那麼動詞發生機率分為五種:肯定、偏向肯定、不確定、偏向否定、否定。
    這其實就是在分析事情(謂語動詞)發生的機率,這在機率分析上有用。
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 1, 1);
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 2, 1);
    */

    VerbRate = "肯定";//預設值:肯定
    string temp = "";//臨時變數

    //先判斷謂語動詞左邊的1個字元,是否是否定詞
    temp = shuru.Substring(shuru.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不"))
    {
        VerbRate = "否定";
    }
    else if(temp.Contains("別"))
    {
        VerbRate = "否定";
    }

    //判斷謂語動詞左邊的2個字元,是否是否定詞
    temp = shuru.Substring(shuru.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不要"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不能"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("可能"))
    {
        VerbRate = "不確定";
    }
    else if (temp.Contains("或許"))
    {
        VerbRate = "不確定";
    }

    //判斷謂語動詞左邊的3個字元,是否是否定詞
    temp = shuru.Substring(shuru.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不可以"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不應該"))
    {
        VerbRate = "否定";
    }
}

//顯示最終輸出結果
void ShowResult()
{
    //tmpText.text = "";//Text Mesh Pro控制元件顯示文字

    UnityEngine.Debug.Log("句型:" + SentenceType);

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("語態:" + yutai);
    }
    else if (SentenceType == "雙賓語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("間接賓語:" + FindJianObject);
        UnityEngine.Debug.Log("直接賓語:" + FindZhiObject);
    }
    else if (SentenceType == "賓語補足語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("賓語補足語動詞:" + FindBuVerb);
        UnityEngine.Debug.Log("賓語補足語名詞:" + FindBuNoun);
    }
    else if (SentenceType == "只有性質狀態")
    {
        UnityEngine.Debug.Log("只有性質狀態:" + shuru);
    }

    UnityEngine.Debug.Log("動詞發生機率:" + VerbRate);

    //清空變數
    FindSubject = "";
    FindVerb = "";
    FindObject = "";
    FindBuVerb = "";
    FindBuNoun = "";
    FindJianObject = "";
    FindZhiObject = "";
    yutai = "";
}

}

第四章
在這一章:
第一,一次可以輸入多句話,但只能用逗號或句號隔開,不能用問號和感嘆號分隔句子。
第二,對主謂賓結構可以分析出定語(形容詞、數詞、名詞所有格),但雙賓語句型和賓語補足語句型,還沒有做定語分析程式,而且數詞只能用阿拉伯數字,也就是1、2、3這類數字,還不能用漢字型數字。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//Canvas框顯示輸入框和輸出框所需
using TMPro;//Text Mesh Pro文字控制元件所需
using Mono.Data.Sqlite;//連線sqlite資料庫所需
using System.Text.RegularExpressions;//正規表示式找出數字所需

public class sqlitecon : MonoBehaviour
{
//輸入和輸出
public TMP_InputField inputField;//輸入框物件(把層級皮膚上的輸入框控制元件拖動到此框裡)
string shuru = "";//輸入框內容
//public TMP_Text tmpText;//輸出框物件(把層級皮膚上的輸出框控制元件拖動到此框裡)
//string mes;//輸出框內容
//詞庫
string[] noun = new string[7128];//名詞陣列,名詞數量7128(資料庫增加名詞後,此處也要修改,以免造成溢位)
string[] verb = new string[5886];//動詞陣列,動詞數量5886(資料庫增加動詞後,此處也要修改,以免造成溢位)
string[] adj = new string[1777];//形容詞陣列,形容詞數量1777(資料庫增加形容詞後,此處也要修改,以免造成溢位)
int i = 0;//陣列用的迴圈變數
//按標點符號分割句子
string dan = "";//按標點符號分割出的基本單句
string[] danju = new string[100];//單句的陣列儲存
int dan_num = 1;//第幾個單句
//基本單句的語法結構
string FindSubject = "";//主語
string FindVerb = "";//謂語動詞
string FindObject = "";//賓語
string FindBuVerb = "";//賓語補足語的動詞
string FindBuNoun = "";//賓語補足語的名詞
string FindJianObject = "";//間接賓語
string FindZhiObject = "";//直接賓語
//名詞所有格(例如張三的貓,張三就是名詞所有格,“的”字就不寫了)
string SubjectSuoyouge = "";//主語的名詞所有格
string ObjectSuoyouge = "";//賓語的名詞所有格
//string JianSuoyouge = "";//間接賓語的名詞所有格
//string ZhiSuoyouge = "";//直接賓語的名詞所有格
//string BuSuoyouge = "";//賓語補足語的名詞所有格
string TempSuoyouge = "";//臨時存放名詞所有格
//形容詞
string SubjectAdj = "";//主語的形容詞
string ObjectAdj = "";//賓語的形容詞
//string JianAdj = "";//間接賓語的形容詞
//string ZhiAdj = "";//直接賓語的形容詞
//string BuAdj = "";//賓語補足語的形容詞
//數詞
string SubjectNum = "";//主語的數詞
string ObjectNum = "";//賓語的數詞
//string JianNum = "";//間接賓語的數詞
//string ZhiNum = "";//直接賓語的數詞
//string BuNum = "";//賓語補足語的數詞
//語法結構的相關描述
string SentenceType = "";//句型
string yutai = "";//語態:主動語態還是被動語態
string VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
//名詞槽(名詞之間相互覆蓋時用)
string NounBox1 = "";//名詞槽1
string NounBox2 = "";//名詞槽2
string NounBox3 = "";//名詞槽3
string NounBox4 = "";//名詞槽4
//動詞槽(動詞之間相互覆蓋時用)
string VerbBox1 = "";//動詞槽1
string VerbBox2 = "";//動詞槽2
string VerbBox3 = "";//動詞槽3
string VerbBox4 = "";//動詞槽4

// Start is called before the first frame update
void Start()
{
    ciku();//填充詞庫
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應(按Enter鍵傳送)
}

// Update is called once per frame
void Update()
{

}

//填充詞庫(資料庫的詞庫填充到陣列中)
void ciku()
{
    //生成遊戲後,需要把sqlite資料庫複製到生成的遊戲的資料夾裡,那個資料夾自動生成的這個資料庫是0kb,無效的,需要重新複製過去
    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量

    //填充形容詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM adj";//sql指令
    //第二步:執行指令
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        adj[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示形容詞數量

    dbConnection.Close();//關閉資料庫連線
}

//輸入完成後,按Enter鍵傳送,便開始執行此函式
void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的內容
    SplitSay();//按標點符號,分割輸入內容
}

//按標點符號,分割輸入內容,分割成基本單句
void SplitSay()
{
    /*
    輸入的內容可能是一大段內容,需要分割成一個個基本單句,從而逐一處理。
    基本單句就是主語-謂語-賓語,或主語-謂語-間接賓語-直接賓語,或主語-謂語-賓語-賓語補足語,這類語法上的基本單句。
    那就需要按逗號分割句子,按句號分割句子,才能拆分成一個個這樣的基本單句。

    按逗號分割句子:
    string str = "早晨,中午,下午";
    string word = ",";
    string[] shuzu = str.Split(word);//按word指定的分隔符,分割字串,並存入陣列中
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    按逗號和句號分割句子:
    string str = "早晨,中午。下午,傍晚";
    string word = ",";
    string[] shuzu = str.Split(word);//按word指定的分隔符(逗號),分割字串,並存入陣列中
    foreach (string part in shuzu)
    {
        string word2 = "。";
        string[] shuzu2 = part.Split(word2);//按word2指定的分隔符(句號),分割字串,並存入陣列中
        foreach (string part2 in shuzu2)
        {
            UnityEngine.Debug.Log(part2);
        }
    }

    計算標點符號的數量:
    string str = "早晨,中午。下午,傍晚";
    string temp = "";

    int dou = 0;//逗號數量
    int ju = 0;//句號數量
    int str_length = str.Length;//句子長度

    temp = str.Replace(",", "");//把逗號替換為空無,就是去掉逗號
    int str_length_delete_dou = temp.Length;//去掉逗號後,句子的長度
    dou = str_length - str_length_delete_dou;//兩者相減,就是逗號的數量

    temp = str.Replace("。", "");//把句號替換為空無,就是去掉句號
    int str_length_delete_ju = temp.Length;//去掉句號後,句子的長度
    ju = str_length - str_length_delete_ju;//兩者相減,就是句號的數量

    以上註釋掉的內容,只是解釋說明,下面才是執行的程式:
    */

    //計算標點符號的數量
    string temp = "";
    int dou = 0;//逗號數量
    int ju = 0;//句號數量
    int str_length = shuru.Length;//句子長度
    //計算逗號的數量
    temp = shuru.Replace(",", "");//把逗號替換為空無,就是去掉逗號
    int str_length_delete_dou = temp.Length;//去掉逗號後,句子的長度
    dou = str_length - str_length_delete_dou;//兩者相減,就是逗號的數量
    //計算句號的數量
    temp = shuru.Replace("。", "");//把句號替換為空無,就是去掉句號
    int str_length_delete_ju = temp.Length;//去掉句號後,句子的長度
    ju = str_length - str_length_delete_ju;//兩者相減,就是句號的數量

    //按標點符號分割句子
    if (dou > 0 || ju > 0)//逗號大於0或句號大於0,就是輸入的內容有標點符號
    {
        string word = ",";//分割符:中文的逗號
        string[] shuzu = shuru.Split(word);//按word指定的分隔符(逗號),分割字串,並存入陣列中
        foreach (string part in shuzu)//逐個處理
        {
            string word2 = "。";//分割符:中文的句號
            string[] shuzu2 = part.Split(word2);//按word2指定的分隔符(句號),分割字串,並存入陣列中
            foreach (string part2 in shuzu2)//逐個處理
            {
                dan = part2;//基本單句已經分割出來了,在part2裡,並賦值給dan(基本單句)
                danju[dan_num - 1] = part2;//陣列從0開始計算,而danju從1開始計算,所以換算上要減1
                ClearData();//清除上次的變數資料
                //UnityEngine.Debug.Log("單句:" + dan);
                SearchVerb(dan);//找謂語動詞(這是單句處理的第一步)
                dan = "";
                dan_num++;
            }
        }
    }
    else//輸入的內容,沒有標點符號
    {
        if (shuru != "")//有輸入的內容
        {
            dan = shuru;//輸入的內容就是一個基本單句
            danju[0] = shuru;
            SearchVerb(dan);//找謂語動詞
            dan = "";
        }
    }
}

//清除上次迴圈(基本單句處理)的變數資料
void ClearData()
{
    FindSubject = "";//主語
    FindVerb = "";//謂語動詞
    FindObject = "";//賓語
    FindBuVerb = "";//賓語補足語的動詞
    FindBuNoun = "";//賓語補足語的名詞
    FindJianObject = "";//間接賓語
    FindZhiObject = "";//直接賓語
    SubjectSuoyouge = "";//主語的名詞所有格
    ObjectSuoyouge = "";//賓語的名詞所有格
    TempSuoyouge = "";//臨時存放名詞所有格
    SubjectAdj = "";//主語的形容詞
    ObjectAdj = "";//賓語的形容詞
    SubjectNum = "";//主語的數詞
    ObjectNum = "";//賓語的數詞
    SentenceType = "";//句型
    yutai = "";//語態:主動語態還是被動語態
    VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
    NounBox1 = "";//名詞槽1
    NounBox2 = "";//名詞槽2
    NounBox3 = "";//名詞槽3
    NounBox4 = "";//名詞槽4
    VerbBox1 = "";//動詞槽1
    VerbBox2 = "";//動詞槽2
    VerbBox3 = "";//動詞槽3
    VerbBox4 = "";//動詞槽4
    i = 0;
}

//找謂語動詞
void SearchVerb(string str)
{
    string jieguo = "不包含";//預設值是不包含動詞
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞

    VerbBox1 = "";
    VerbBox2 = "";
    VerbBox3 = "";
    VerbBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (str.Contains(verb[n]))//包含動詞
        {
            if (VerbJudge(str, verb[n]) == true)//是動詞,不是名詞
            {
                jieguo = "包含";
                FindVerb = verb[n];//找到了動詞
                VerbCover(str, verb[n]);//把動詞放入動詞槽裡,看看有幾個動詞
                VerbOrder();//動詞排序
                VerbJoin();//動詞結合
            }
        }
    }

    if (jieguo == "包含")//包含動詞
    {
        VerbRateJudge();//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
        SentenceType = SentenceJudge();//判斷句型(僅從動詞情況來判斷句型,還不是完全清楚的判斷,之後還需進一步判斷)
        SplitSentence();//以謂語動詞為分割符,來分割句子
    }
}

//以謂語動詞為分割符,來分割句子
void SplitSentence()
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string word = "嘲笑";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞語的起始位置
    int LastIndex = 0;//指定詞語最後一個字元在全句中的位置
    int jie = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    //計算指定字元在全句中的位置
    index = str.IndexOf(word) + 1;//預設從0計算,例如第2個字元,顯示為1,而不是2。為了調整為1開始計算,所以加1
    //計算指定詞語最後一個字元在全句中的位置
    LastIndex = str.IndexOf(word) + word.Length;

    //擷取第3個字元右邊的1個字元
    Substring(開始位置, 向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元

    //擷取指定字元右邊的全部字元
    jie = chang - LastIndex;//擷取長度 = 全句長度 - 指定詞語最後一個字元的位置長度
    res = str.Substring(LastIndex, jie);
    res = str.Substring(str.IndexOf(word) + word.Length, str.Length - (str.IndexOf(word) + word.Length));//展開形式

    //擷取指定字元左邊的全部字元
    res = str.Substring(0, index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0, str.IndexOf(word));//變化形式

    //擷取兩個指定字元之間的全部字元
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    以上註釋掉的內容,只是解釋原理,下面是執行的程式:
    */

    string LeftPart = "";//謂語動詞的左邊句
    string RightPart = "";//謂語動詞的右邊句

    //也可能找到一個動詞(主謂賓句型),也可能找到兩個動詞(賓語補足語句型)
    if (VerbBox1 != "" && VerbBox2 == "")//只找到1個動詞,那就是謂語動詞
    {
        FindVerb = VerbBox1;
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//找到2個動詞
    {
        FindVerb = VerbBox1;//位次在前面的動詞是謂語動詞
        FindBuVerb = VerbBox2;//位次在後面的動詞是賓語補足語動詞
    }

    //謂語動詞左邊句(LeftPart)和謂語動詞右邊句(RightPart)是一個重要的轉折,為以後的句子處理奠定了基礎
    LeftPart = dan.Substring(0, dan.IndexOf(FindVerb));
    RightPart = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.Length - (dan.IndexOf(FindVerb) + FindVerb.Length));

    /*
    例如句子(dan)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);//謂語動詞
    UnityEngine.Debug.Log(LeftPart);//謂語動詞的左邊句
    UnityEngine.Debug.Log(RightPart);//謂語動詞的右邊句
    */

    /*
    省略主語有兩種情況:一種是主動語態省略主語,例如“跳過去”,全句指“你跳過去”。另一種是被動語態省略主語,例如“張三被打了”,沒說誰打了張三,這裡張三是賓語。如果說“李四打了張三”,李四就是主語。
    被動語態的標誌是“被”字,如果沒有“被”字,而且省略了主語,就是主動語態省略主語的情況,那麼這種情況下,主語應該填什麼呢?例如“過來”,一般指“你過來”,但“走吧”一般指“我們走吧”。所以程式要根據具體的動詞來判斷省略的主語應該填什麼。但是動詞太多,每個動詞都要設定省略的主語判斷,太麻煩。所以省略主語,按最通常情況,就預設填“你”字,作為主語。如果主語是“我們”而不是“你”字,就不該省略主語。
    被動語態應該還原為主動語態去理解,但被動語態往往沒有主語,那麼預設主語應該填什麼呢?畢竟不知道主語,那就填“事物”這個詞作為主語。
    程式分析句子時,被動語態的主語位置的詞,是賓語。例如“李四被打了”,李四在謂語動詞左邊句,程式會把李四當成主語,但在被動語態句裡,李四不是主語,所以有“被”字的時候,主語要挪動到賓語位置,然後在主語位置補充“事物”這個詞,作為主語。
    但是有些時候,被動語態的主語是說明了的,例如“李四被張三打了”就還原為主動語態“張三打了李四”,張三做主語,而不是填“事物”做主語。
    簡而言之,被動語態裡,主語放到了賓語位置,賓語放到了主語位置,所以變為主動語態時,要把賓語挪回主語位置,主語挪回賓語位置。
    如果被動語態有主語,例如“李四被張三打了”,那麼主語(張三)位於“被”字與謂語動詞之間。
    那麼謂語動詞左邊句中,又分為“被”字左邊句和“被”字右邊句,被字左邊句裡的名詞是賓語,被字右邊句裡的名詞是主語。
    */
    yutai = "主動";//預設主動語態
    if (SentenceType == "主謂賓" && dan.Contains("被"))//語句中包含“被”字
    {
        if (dan.Contains("被子") == false && dan.Contains("被褥") == false)//語句中包含“被”字,但不是“被子”這個名詞,才能指被動語態的“被”字
        {
            yutai = "被動";//被動語態
        }
        else
        {
            yutai = "主動";//主動語態
        }
    }
    else//語句中沒有包含“被”字
    {
        yutai = "主動";//主動語態
    }

    //對謂語動詞左邊句(LeftPart)的處理
    if (LeftPart != "")//謂語動詞左邊句有內容
    {
        if (yutai == "主動")//主動語態
        {
            //找名詞(主語)和名詞所有格
            FindSubject = SearchNoun(LeftPart);//在謂語動詞左邊句找名詞(主語)
            if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
            {
                SubjectSuoyouge = TempSuoyouge;//是主語的名詞所有格
                TempSuoyouge = "";//置空
            }
            //找形容詞(主語的形容詞)
            SubjectAdj = SearchAdj(LeftPart);
            //找數詞
            SubjectNum = SearchNum(LeftPart);
        }
        else if (yutai == "被動")//被動語態
        {
            string bei = "被";
            string BeiLeft = "";
            string BeiRight = "";

            //被字左邊句
            BeiLeft = LeftPart.Substring(0, LeftPart.IndexOf(bei));
            if (BeiLeft != "")
            {
                FindObject = SearchNoun(BeiLeft);//被字左邊句的名詞是賓語
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
                    TempSuoyouge = "";//置空
                }
                //找形容詞(賓語的形容詞)
                ObjectAdj = SearchAdj(BeiLeft);
                //找數詞
                ObjectNum = SearchNum(BeiLeft);
            }

            //被字右邊句
            BeiRight = LeftPart.Substring(LeftPart.IndexOf(bei) + bei.Length, LeftPart.Length - (LeftPart.IndexOf(bei) + bei.Length));
            
            if (BeiRight != "")
            {
                FindSubject = SearchNoun(BeiRight);//被字右邊句的名詞是主語
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    SubjectSuoyouge = TempSuoyouge;//是主語的名詞所有格
                    TempSuoyouge = "";//置空
                }
                //找形容詞(主語的形容詞)
                SubjectAdj = SearchAdj(BeiRight);
                //找數詞
                SubjectNum = SearchNum(BeiRight);
            }
            //如果沒有主語,就填補“事物”這個詞作為主語,畢竟被動語態經常沒有主語
            if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
            {
                FindSubject = "事物";
            }
        }
    }

    //如果省略主語,則填補省略的主語
    if (yutai == "主動")
    {
        if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
        {
            FindSubject = "你";//預設填補“你”字做主語
        }
    }

    //對謂語動詞右邊句(RightPart)的處理
    if (SentenceType == "雙賓語")//雙賓語句型
    {
        FindObject = SearchNoun(RightPart);//找名詞

        //謂語動詞右邊句裡,沒有第二個賓語名詞,那就不是雙賓語
        //例如雖然有雙賓語句的標誌動詞“教”字,但他教我數學,是雙賓語句,而他教書,是主謂賓句型
        if (NounBox2 == "")
        {
            SentenceType = "主謂賓";
        }
        else
        {
            ShowResult();//顯示最終輸出結果
        }
    }

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        if (RightPart != "")
        {
            if (yutai == "主動")
            {
                //找名詞和名詞所有格
                FindObject = SearchNoun(RightPart);//在謂語動詞右邊句找名詞(賓語)
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
                    TempSuoyouge = "";//置空
                }

                //找形容詞(賓語的形容詞)
                ObjectAdj = SearchAdj(RightPart);
                //找數詞
                ObjectNum = SearchNum(RightPart);
            }
            
        }

        ShowResult();//顯示最終輸出結果
    }

    if (SentenceType == "賓語補足語")//賓語補足語句型
    {
        //謂語動詞到賓語補足語動詞之間的部分裡的名詞,是賓語名詞
        string temp = "";
        //擷取謂語動詞FindVerb和賓語補足語動詞FindBuVerb之間的部分
        temp = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.IndexOf(FindBuVerb) - (dan.IndexOf(FindVerb) + FindVerb.Length));
        FindObject = SearchNoun(temp);//找名詞
        if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
        {
            ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
            TempSuoyouge = "";//置空
        }
        //賓語補足語右邊句的名詞,是賓語補足語名詞,而不是賓語名詞
        int WordLastChar = dan.IndexOf(FindBuVerb) + FindBuVerb.Length;//賓語補足語動詞最後一個字元的位置
        if (WordLastChar < dan.Length)//賓語補足語動詞最後一個字元的位置沒有到全句末尾,就是說賓語補足語動詞後面還有內容,那就是賓語補足語名詞
        {
            //擷取賓語補足語動詞右邊的內容
            FindBuNoun = dan.Substring(dan.IndexOf(FindBuVerb) + FindBuVerb.Length, dan.Length - (dan.IndexOf(FindBuVerb) + FindBuVerb.Length));
            //以後再寫找賓語補足語名詞的名詞所有格
        }

        ShowResult();//顯示最終輸出結果
    }

    /*
    靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

    第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    所以建立一個函式:WordCover(覆蓋)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。

    第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    對於第二個問題的解決方法:
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    所以建立一個de函式。

    第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。
    所以建立一個VerbJudge函式。
    */
}

//找名詞(也包括找名詞所有格)
string SearchNoun(string PartSentence)
{
    string jieguo = "不包含";//預設值是不包含
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞

    //for迴圈前,先把詞語槽清空,因為for迴圈時,呼叫的函式WordCover要用詞語槽,來完成詞語的覆蓋和吸收
    NounBox1 = "";
    NounBox2 = "";
    NounBox3 = "";
    NounBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//包含
        {
            jieguo = "包含";
            if (de(PartSentence, noun[n]) == false)//找到的名詞右邊的第一個字元不是“的”字,才算是名詞,否則是名詞所有格
            {
                NounCover(noun[n]);
            }
            else//名詞右邊的第一個字是“的”字,就意味著是名詞所有格
            {
                TempSuoyouge = noun[n];//找到的名詞所有格
            }
        }
    }

    if (jieguo == "包含")//找到了名詞
    {
        NounOrder();//名詞排序
        //名詞要先排序,才能合併名詞,否則“足球”和“學校”的順序如果變成“學校”和“足球”,那就合併成“學校足球”這個詞了,而不是“足球學校”

        //如果雙賓語句型進行名詞合併,就可能會把間接賓語名詞和直接賓語名詞合併到一起,成為一個名詞,就不對了
        if (SentenceType != "雙賓語")//不是雙賓語句型
        {
            NounJoin();//名詞合併,例如把“足球”和“學校”合併成“足球學校”這一個名詞
        }
        else if (SentenceType == "雙賓語")//是雙賓語句型
        {
            //但是如果現在處理的是雙賓語結構的謂語動詞左邊句,也就是處理主語,還是可以名詞合併的
            if (dan.IndexOf(NounBox1) < dan.IndexOf(FindVerb))
            {
                NounJoin();//名詞合併
            }
        }

        return NounBox1;
    }
    else
    {
        return "";
    }
}

//名詞之間的覆蓋
void NounCover(string FindWord)
{
    /*
    熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。
    做了4個詞語槽(NounBox),為了以後適應複雜的句子,但簡單的主謂賓句型,一個詞語槽就夠了。
    */
    if (NounBox1 == "" && FindWord != "")//詞語槽還是空的,說明這是找到的第一個詞
    {
        NounBox1 = FindWord;//找到的第1個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽2了
    }
    else if (NounBox1 != "" && FindWord != "")//詞語槽1已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox1))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽1(NounBox1)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽2了
        }
        else if (NounBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽1(NounBox1)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,不要這個詞了,免得填到詞語槽2了
        }
    }

    if (NounBox2 == "" && FindWord != "")//詞語槽2是空的,FindWord經過詞語槽1,沒有覆蓋或吸收,說明FindWord和詞語槽1的詞無關,例如FindWord是竹子
    {
        NounBox2 = FindWord;//找到的第2個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽3了
    }
    else if (NounBox2 != "" && FindWord != "")//詞語槽2已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox2))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽2(NounBox2)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (NounBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽2(NounBox2)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (NounBox3 == "" && FindWord != "")//詞語槽3是空的,FindWord經過詞語槽2,沒有覆蓋或吸收,說明FindWord和詞語槽2的詞無關,例如FindWord是竹子
    {
        NounBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (NounBox3 != "" && FindWord != "")//詞語槽3已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox3))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽3(NounBox3)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (NounBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽3(NounBox3)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (NounBox4 == "" && FindWord != "")//詞語槽4是空的,FindWord經過詞語槽3,沒有覆蓋或吸收,說明FindWord和詞語槽3的詞無關,例如FindWord是竹子
    {
        NounBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (NounBox4 != "" && FindWord != "")//詞語槽4已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox4))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽4(NounBox4)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (NounBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽4(NounBox4)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空
        }
    }

    /*
    “足球”這個詞,會找到三個名詞:足、球、足球。
    先找到第一個詞:足,放入NounBox1。
    再找到第二個詞:球,放入NounBox2。
    再找到第三個詞:足球,會覆蓋NounBox1的“足”字,但卻無法覆蓋NounBox2的球字。
    因此程式做一些改進。

    但如果幸運的:
    先找到第一個詞:足球,放入NounBox1。
    再找到第二個詞:足,被NounBox1“足球”這個詞吸收,不會進入到NounBox2。
    再找到第三個詞:球,被NounBox1“足球”這個詞吸收,也不會進入到NounBox2。
    那麼就不用執行下面這段程式了。
    先找到那個詞是不確定的,詞庫詞語可能按筆畫排序,也可能按首字母排序,就不知道先找到那個詞了。

    如果輸入的是“皮球”這個詞,而詞庫裡沒有“皮球”這個詞,但有“皮”字和“球”字這兩個詞。
    那麼,NounBox1是“皮”字,NounBox2是“球”字,或NounBox1是“球”字,NounBox2是“皮”字,沒有覆蓋和吸收。
    */
    if (NounBox1.Contains(NounBox2))//NounBox1包含了NounBox2,例如“足球”包含“球”字
    {
        NounBox2 = "";
        if (NounBox3 != "")
        {
            NounBox2 = NounBox3;
            NounBox3 = "";
        }
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox2.Contains(NounBox3))//NounBox2包含了NounBox3
    {
        NounBox3 = "";
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox3.Contains(NounBox4))//NounBox3包含了NounBox4
    {
        NounBox4 = "";
    }
}

//動詞之間的覆蓋
void VerbCover(string str,string FindWord)
{
    if (VerbBox1 == "" && FindWord != "")//動詞槽還是空的,說明這是找到的第一個詞
    {
        VerbBox1 = FindWord;//找到的第1個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽2了
    }
    else if (VerbBox1 != "" && FindWord != "")//動詞槽1已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox1))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽1(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“敲打”覆蓋“打”
            FindWord = "";//置空,免得填到動詞槽2了
        }
        else if (VerbBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽1(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,不要這個詞了,免得填到動詞槽2了
        }
    }

    if (VerbBox2 == "" && FindWord != "")//動詞槽2是空的,FindWord經過動詞槽1,沒有覆蓋或吸收,說明FindWord和動詞槽1的詞無關,例如FindWord是喜歡
    {
        VerbBox2 = FindWord;//找到的第2個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽3了
    }
    else if (VerbBox2 != "" && FindWord != "")//動詞槽2已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox2))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽2(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (VerbBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽2(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (VerbBox3 == "" && FindWord != "")//動詞槽3是空的,FindWord經過動詞槽1和2,沒有覆蓋或吸收,說明FindWord和動詞槽1、2的詞無關,例如FindWord是喜歡
    {
        VerbBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (VerbBox3 != "" && FindWord != "")//動詞槽3已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox3))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽3(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (VerbBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽3(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (VerbBox4 == "" && FindWord != "")//動詞槽4是空的,FindWord經過動詞槽1、2、3,沒有覆蓋或吸收,說明FindWord和動詞槽1、2、3的詞無關,例如FindWord是喜歡
    {
        VerbBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (VerbBox4 != "" && FindWord != "")//動詞槽4已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox4))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽4(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (VerbBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽4(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空
        }
    }

    /*
    “敲打”這個詞,會找到三個動詞:敲、打、敲打
    先找到第一個詞:敲,放入VerbBox1
    再找到第二個詞:打,放入VerbBox2
    再找到第三個詞:敲打,會覆蓋VerbBox1的“敲”字,但卻無法覆蓋VerbBox2的“打”字
    因此程式做一些改進。 
    */
    if (VerbBox1.Contains(VerbBox2))//VerbBox1包含了VerbBox2
    {
        VerbBox2 = "";
        if (VerbBox3 != "")
        {
            VerbBox2 = VerbBox3;
            VerbBox3 = "";
        }
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox2.Contains(VerbBox3))//VerbBox2包含了VerbBox3
    {
        VerbBox3 = "";
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox3.Contains(VerbBox4))//VerbBox3包含了VerbBox4
    {
        VerbBox4 = "";
    }
}

//名詞後面是否包含“的”字
bool de(string str,string word)
{
    /*
    熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    
    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }
    UnityEngine.Debug.Log(res);//顯示:的
    以上註釋掉的內容只是解釋原理,下面是執行程式:
    */

    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果
    WordLastChar = str.IndexOf(word) + word.Length;
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }

    if (res == "的")
    {
        return true;
    }
    else
    {
        return false;
    }

}

//判斷一個字是動詞還是名詞
bool VerbJudge(string str,string word)
{
    /*
    “學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞,也就是辨析字。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。
    “壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。

    不容易理解的一處:
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   吹     |   l1    |      電      |
    +----------+---------+--------------+
    “吹”字本身做動詞,但在“電吹風”這個詞裡做名詞,但我不用把“電吹風”這個三個字都判斷,我只要判斷“電吹”兩個字就可以了。

    遇到單字動詞的時候,先看這個字是否在詞性辨析表裡,
    如果在,type_col要求是r1(right1,就是要辨析的字的右邊1個字元),那就看句子中要辨析的字的右邊1個字元是不是符合詞性表中的字,
    如果符合,要辨析的字就是名詞,而不是動詞了。
    例如學生看書,這句話先找到了動詞“學”,在詞性辨析表裡,“學”字的type_col是r1,content_col是“生”字,
    那就在句子中,看“學”字右邊的1個字元是不是“生”字,如果是,“學”字就不做動詞,而做名詞了。

    一個要辨析的字,type_col有四種可能:r1、r2、l1、l2,也就是右邊1個字,右邊2個字,左邊1個字,左邊2個字,那就要會四個方法:
    符合r1:找辨析字右邊1個字元:res = str.Substring(str.IndexOf(word) + word.Length, 1);
    符合r2:找辨析字右邊2個字元:res = str.Substring(str.IndexOf(word) + word.Length, 2);
    符合l1:找辨析字左邊1個字元:res = str.Substring(str.IndexOf(word) - 1, 1);
    符合l2:找辨析字左邊2個字元:res = str.Substring(str.IndexOf(word) - 2, 1);

    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
        res = str.Substring(str.IndexOf(word) + word.Length, 1);//變化形式

    }
    UnityEngine.Debug.Log(res);//顯示:的

    //指定詞語左邊1個字元
    res = str.Substring(index - 1, 1);
    res = str.Substring(str.IndexOf(word) - 1, 1);//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃
    以上註釋掉的內容,只是解釋原理,下面是執行程式:
    */

    string[] TypeCol = new string[100];//把詞性辨析表的辨析字對應的type_col值填充此陣列
    string[] ContentCol = new string[100];//把詞性辨析表的辨析字對應的content_col值填充此陣列
    string res = "";//擷取的字元
    bool shima = true;//預設判斷是動詞

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    //字元型變數要有引號,數字型變數不需要引號
    //word是變數,動態的,不能直接放到sql語句裡面
    string sqlQuery = "select type_col,content_col from verb_judge where word_col = '" + word + "'";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充詞性辨析陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();

    i = 0;
    while (dbReader.Read())
    {
        //查詢了2列(type_col和content_col),所以返回的結果集有2列,分別用GetValue(0)和GetValue(1)
        TypeCol[i] = dbReader.GetValue(0).ToString();//返回的結果集的第1列
        ContentCol[i] = dbReader.GetValue(1).ToString();//返回的結果集的第2列
        i++;//雖然定義陣列長度為10,但i不一定填滿了10
    }
    dbReader.Close();
    dbConnection.Close();
    
    if (i > 0)//在詞性辨析表裡找到內容了,否則i還是預設的0
    {
        for (int n = 0; n < i; n++)//遍歷詞性辨析表找到的各種結果
        {
            if (TypeCol[n] == "r1")//right1:右邊1個字元
            {
                if (str.IndexOf(word) + word.Length + 1 <= str.Length)//要往右判斷1個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 1);//擷取動詞右邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "r2")//right2:右邊2個字元
            {
                if (str.IndexOf(word) + word.Length + 2 <= str.Length)//要往右判斷2個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 2);//擷取動詞右邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "l1")//left1:左邊1個字元
            {
                if (str.IndexOf(word) - 1 >= 0)//要往左判斷1個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 1, 1);//擷取動詞左邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }

                }
            }
            else if (TypeCol[n] == "l2")//left2:左邊2個字元
            {
                if (str.IndexOf(word) - 2 >= 0)//要往左判斷2個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 2, 2);//擷取動詞左邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
        }
    }
    i = 0;
    return shima;
}

//判斷句型
string SentenceJudge()
{
    /*
    基本單句有六種句型:
    只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
    主語(動作執行者)-謂語(動作):張三摔倒。
    主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
    主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
    雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
    賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
    前面只說了主謂賓句型,還要處理其它句型。

    雙賓語句型:
    雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
    但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
    雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
    那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
    還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
    僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
    名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

    賓語補足語句型:
    和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
    因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
    但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
    既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
    動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
    賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

    雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

    在主謂賓句型的基礎上,如果沒有賓語,就是主謂句型。如果沒有主語,就是省略主語,例如對一個人喊“過來”,這句話的全句顯然是“你過來”。
    */

    if (VerbBox1 == "")//沒有動詞
    {
        return "只有性質狀態";//只有性質狀態的句型
    }
    else if (VerbBox1 != "" && VerbBox2 == "")//有1個動詞
    {
        if (VerbBox1 == "給" || VerbBox1 == "送" || VerbBox1 == "送給" || VerbBox1 == "教")//雙賓語句型的常見動詞(標誌詞)
        {
            return "雙賓語";//雙賓語句型
        }
        else
        {
            return "主謂賓";//主謂賓句型
        }
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//有2個動詞
    {
        return "賓語補足語";//賓語補足語句型
    }
    else
    {
        return "其它";
    }
}

//名詞排序
void NounOrder()
{
    if (NounBox1 != "" && NounBox2 != "")//招到了2個名詞,放在NounBox1和NounBox2
    {
        string temp = "";//臨時變數
        if (dan.IndexOf(NounBox1) > dan.IndexOf(NounBox2))//如果NounBox1的名詞在句子中的位置大於NounBox2的名詞在句子中的位置
        {
            //交換位置,在句子中位置小的名詞放前面,從而確保雙賓語句型時,NounBox1放的是間接賓語,NounBox2放的是直接賓語,畢竟間接賓語在直接賓語前面
            temp = NounBox1;
            NounBox1 = NounBox2;
            NounBox2 = temp;
        }
        FindJianObject = NounBox1;
        FindZhiObject = NounBox2;
        //間接賓語和直接賓語的名詞所有格,之後再做
    }
}

//名詞結合成名詞片語
void NounJoin()
{
    /*
    名詞合併:例如“足球學校”這個詞,會被當成兩個名詞“足球”和“學校”。但實際中,要把它們合併成一個組合名詞,作為主語或賓語。
    前面說了判斷兩個字元之間的內容,如果兩個字元(詞語)是連續的,那麼這兩個詞語之間的內容為空。
    示例:
    //擷取兩個指定字元之間的全部字元
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string res = "";//結果
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式
    if (res == "")
    {
        UnityEngine.Debug.Log("連續");
    }
    else
    {
        UnityEngine.Debug.Log("不連續");
    }
    */
    
    string res;
    //判斷NounBox1和NounBox2的名詞是否需要合併
    if (NounBox1 != "" && NounBox2 != "")
    {
        res = "";
        //判斷NounBox1和NounBox2之間是否有內容,如果沒內容(res為空),就說明NounBox1和NounBox2是連續的名詞(中間沒有字元間隔),需要合併
        res = dan.Substring(dan.IndexOf(NounBox1) + NounBox1.Length, dan.IndexOf(NounBox2) - (dan.IndexOf(NounBox1) + NounBox1.Length));
        if (res == "")
        {
            NounBox1 = NounBox1 + NounBox2;//名詞合併
            NounBox2 = "";//合併後,置空
            if (NounBox3 != "")
            {
                NounBox2 = NounBox3;//填補置空的值,否則NounBox1有值,NounBox2為空,NounBox3又有值,就間隔了
                NounBox3 = "";//合併後,置空
                if (NounBox4 != "")
                {
                    NounBox3 = NounBox4;
                    NounBox4 = "";//合併後,置空
                }
            }
        }
    }

    /*
    //判斷NounBox2和NounBox3的名詞是否需要合併
    if (NounBox2 != "" && NounBox3 != "")
    {
        res = "";
        //判斷NounBox2和NounBox3之間是否有內容,如果沒內容(res為空),就說明NounBox2和NounBox3是連續的名詞,需要合併
        res = dan.Substring(dan.IndexOf(NounBox2) + NounBox2.Length, dan.IndexOf(NounBox3) - (dan.IndexOf(NounBox2) + NounBox2.Length));
        if (res == "")
        {
            NounBox2 = NounBox2 + NounBox3;//名詞合併
            NounBox3 = "";//合併後,置空
            if (NounBox4 != "")
            {
                NounBox3 = NounBox4;//填補置空的值
                NounBox4 = "";//合併後,置空
            }
        }
    }

    //判斷NounBox3和NounBox4的名詞是否需要合併
    if (NounBox3 != "" && NounBox4 != "")
    {
        res = "";
        //判斷NounBox3和NounBox4之間是否有內容,如果沒內容(res為空),就說明NounBox3和NounBox4是連續的名詞,需要合併
        res = dan.Substring(dan.IndexOf(NounBox3) + NounBox3.Length, dan.IndexOf(NounBox4) - (dan.IndexOf(NounBox3) + NounBox3.Length));
        if (res == "")
        {
            NounBox3 = NounBox3 + NounBox4;//名詞合併
            NounBox4 = "";//合併後,置空
        }
    }
    */
}

//動詞排序
void VerbOrder()
{
    /*
    如果不排序會怎樣?句子中找到的第一個動詞,可能不是謂語動詞,而是賓語補足語動詞,以賓語補足語動詞分割句子,就錯了。
    謂語動詞和賓語補足語動詞,先找到哪個,取決於這兩個詞,誰在動詞表前面排序,而動詞的排序是不可知的,或許按筆劃排序,或者按首字母排序
    */
    string temp = "";//臨時變數
    if (VerbBox1 != "" && VerbBox2 != "")//招到了個動詞,放在VerbBox1和VerbBox2
    {
        if (dan.IndexOf(VerbBox1) > dan.IndexOf(VerbBox2))//如果VerbBox1的動詞在句子中的位置大於VerbBox2的動詞在句子中的位置
        {
            //交換位置,在句子中位置小動詞的放前面,從而確保VerbBox1放的是謂語動詞,而賓語補足語動詞放到VerbBox2
            temp = VerbBox1;
            VerbBox1 = VerbBox2;
            VerbBox2 = temp;
        }

    }
    if (VerbBox3 != "")
    {
        if (dan.IndexOf(VerbBox1) > dan.IndexOf(VerbBox3))
        {
            temp = VerbBox1;
            VerbBox1 = VerbBox3;
            VerbBox3 = temp;
        }
        if (dan.IndexOf(VerbBox2) > dan.IndexOf(VerbBox3))
        {
            temp = VerbBox2;
            VerbBox2 = VerbBox3;
            VerbBox3 = temp;
        }
    }
    FindVerb = VerbBox1;
}

//動詞結合成動詞片語
void VerbJoin()
{
    //動詞合併:例如“應該愛”是兩個動詞:情態動詞“應該”和普通動詞“愛”,應該合併成一個動詞
    string res;
    //判斷VerbBox1和VerbBox2的動詞是否需要合併
    if (VerbBox1 != "" && VerbBox2 != "")
    {
        res = "";
        //判斷VerbBox1和VerbBox2之間是否有內容,如果沒內容(res為空),就說明VerbBox1和VerbBox2是連續的動詞(中間沒有字元間隔),需要合併
        res = dan.Substring(dan.IndexOf(VerbBox1) + VerbBox1.Length, dan.IndexOf(VerbBox2) - (dan.IndexOf(VerbBox1) + VerbBox1.Length));
        if (res == "")
        {
            VerbBox1 = VerbBox1 + VerbBox2;//名詞合併
            FindVerb = VerbBox1;
            VerbBox2 = "";//合併後,置空
            if (VerbBox3 != "")
            {
                VerbBox2 = VerbBox3;//填補置空的值,否則VerbBox1有值,VerbBox2為空,VerbBox3又有值,就間隔了
                VerbBox3 = "";//合併後,置空
                if (VerbBox4 != "")
                {
                    VerbBox3 = VerbBox4;
                    VerbBox4 = "";//合併後,置空
                }
            }
        }
    }

}

//謂語動詞的發生機率
void VerbRateJudge()
{
    /*
    動詞前面是否有否定詞,也很重要。
    例如“他愛貓”和“他不愛貓”,雖然謂語動詞都是“愛”字,但前面加個“不”字,意義就相反了。所以看謂語動詞前面是否有否定詞,是很重要的事。
    謂語動詞前面的否定詞,一般有不、不要、不可以、不應該、不能、別。
    還有不確定肯定還是否定動詞,例如“他不一定去”,“去”字是動詞,但是動詞前的“不一定”,並不像是“不”字那樣對動詞進行否定,而是對動詞既不像是肯定,也不像是否定,而是不確定。
    因此對每句話的謂語動詞,都要加一個性質:肯定、否定、不確定。
    但不確定,有時候偏向於肯定,例如“他可能去”。有時候不確定偏向於否定,例如“他不太可能去”以及“他或許不去”。
    那麼動詞發生機率分為五種:肯定、偏向肯定、不確定、偏向否定、否定。
    這其實就是在分析事情(謂語動詞)發生的機率,這在機率分析上有用。
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 1, 1);
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 2, 1);
    */

    VerbRate = "肯定";//預設值:肯定
    string temp = "";//臨時變數

    //先判斷謂語動詞左邊的1個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不"))
    {
        VerbRate = "否定";
    }
    else if(temp.Contains("別"))
    {
        VerbRate = "否定";
    }

    //判斷謂語動詞左邊的2個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不要"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不能"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("可能"))
    {
        VerbRate = "不確定";
    }
    else if (temp.Contains("或許"))
    {
        VerbRate = "不確定";
    }

    //判斷謂語動詞左邊的3個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不可以"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不應該"))
    {
        VerbRate = "否定";
    }
}

//找形容詞
string SearchAdj(string str)
{
    string jieguo = "不包含";//預設值是不包含
    int m = adj.Length;//形容詞陣列的長度,也就是有多少個形容詞
    string temp  = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和形容詞的包含關係
        就是用句子和形容詞陣列的形容詞,一一比對,來判斷是否包含形容詞
        n的值從0逐漸增長到形容詞陣列的形容詞數量值,這樣陣列也就經歷了所有形容詞
        */
        if (str.Contains(adj[n]))//包含
        {
            jieguo = "包含";
            temp = adj[n];
        }
    }

    if (jieguo == "包含")//找到了形容詞
    {
        return temp;
    }
    else
    {
        return "";
    }
}

//找數詞
string SearchNum(string str)
{
    /*
    找出數字(找出含有1、2、3這樣的阿拉伯數字,而不是一、二、三這樣的漢字型數字)。
    這種找數字方法用到了正規表示式。
    replace函式把不是數字的部分變為空無,這樣就只剩下數字部分。
    */
    string res = "";
    res = Regex.Replace(str, @"[^0-9]+", "");
    return res;
}

//顯示最終輸出結果
void ShowResult()
{
    UnityEngine.Debug.Log("第" + dan_num + "句:" + danju[dan_num-1]);
    UnityEngine.Debug.Log("句型:" + SentenceType);

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("語態:" + yutai);
    }
    else if (SentenceType == "雙賓語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("間接賓語:" + FindJianObject);
        UnityEngine.Debug.Log("直接賓語:" + FindZhiObject);
    }
    else if (SentenceType == "賓語補足語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("賓語補足語動詞:" + FindBuVerb);
        UnityEngine.Debug.Log("賓語補足語名詞:" + FindBuNoun);
    }
    else if (SentenceType == "只有性質狀態")
    {
        UnityEngine.Debug.Log("只有性質狀態:" + dan);
    }

    UnityEngine.Debug.Log("動詞發生機率:" + VerbRate);

    //顯示名詞所有格
    if (SubjectSuoyouge != "")
    {
        UnityEngine.Debug.Log("主語的名詞所有格:" + SubjectSuoyouge);
    }
    if (ObjectSuoyouge != "")
    {
        UnityEngine.Debug.Log("賓語的名詞所有格:" + ObjectSuoyouge);
    }
    /*
    if (JianSuoyouge != "")
    {
        UnityEngine.Debug.Log("間接賓語的名詞所有格:" + JianSuoyouge);
    }
    if (ZhiSuoyouge != "")
    {
        UnityEngine.Debug.Log("直接賓語的名詞所有格:" + ZhiSuoyouge);
    }
    if (BuSuoyouge != "")
    {
        UnityEngine.Debug.Log("賓語補足語的名詞所有格:" + BuSuoyouge);
    }
    */

    //顯示形容詞
    if (SubjectAdj != "")
    {
        UnityEngine.Debug.Log("主語的形容詞:" + SubjectAdj);
    }
    if (ObjectAdj != "")
    {
        UnityEngine.Debug.Log("賓語的形容詞:" + ObjectAdj);
    }
    /*
    if (JianAdj != "")
    {
        UnityEngine.Debug.Log("間接賓語的形容詞:" + JianAdj);
    }
    if (ZhiAdj != "")
    {
        UnityEngine.Debug.Log("直接賓語的形容詞:" + ZhiAdj);
    }
    if (BuAdj != "")
    {
        UnityEngine.Debug.Log("賓語補足語的形容詞:" + BuAdj);
    }
    */

    //顯示數詞
    if (SubjectNum != "")
    {
        UnityEngine.Debug.Log("主語的數詞:" + SubjectNum);
    }
    if (ObjectNum != "")
    {
        UnityEngine.Debug.Log("賓語的數詞:" + ObjectNum);
    }
    /*
    if (JianNum != "")
    {
        UnityEngine.Debug.Log("間接賓語的形容詞:" + JianNum);
    }
    if (ZhiNum != "")
    {
        UnityEngine.Debug.Log("直接賓語的形容詞:" + ZhiNum);
    }
    if (BuNum != "")
    {
        UnityEngine.Debug.Log("賓語補足語的形容詞:" + BuNum);
    }
    */

    //tmpText.text = mes;

    //清空變數
    FindSubject = "";
    FindVerb = "";
    FindObject = "";
    FindBuVerb = "";
    FindBuNoun = "";
    FindJianObject = "";
    FindZhiObject = "";
    yutai = "";
    SubjectSuoyouge = "";
    ObjectSuoyouge = "";
    /*
    JianSuoyouge = "";
    ZhiSuoyouge = "";
    BuSuoyouge = "";
    */
}

}

第五章

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//Canvas框顯示輸入框和輸出框所需
using TMPro;//Text Mesh Pro文字控制元件所需
using Mono.Data.Sqlite;//連線sqlite資料庫所需

public class sqlitecon : MonoBehaviour
{
//輸入和輸出
public TMP_InputField inputField;//輸入框物件(把層級皮膚上的輸入框控制元件拖動到此框裡)
string shuru = "";//輸入框內容
//public TMP_Text tmpText;//輸出框物件(把層級皮膚上的輸出框控制元件拖動到此框裡)
//string mes;//輸出框內容
//詞庫
string[] noun = new string[7128];//名詞陣列,名詞數量7128(資料庫增加名詞後,此處也要修改,以免造成溢位)
string[] verb = new string[5886];//動詞陣列,動詞數量5886(資料庫增加動詞後,此處也要修改,以免造成溢位)
string[] adj = new string[1777];//形容詞陣列,形容詞數量1777(資料庫增加形容詞後,此處也要修改,以免造成溢位)
int i = 0;//陣列用的迴圈變數
//按標點符號分割句子
string dan = "";//按標點符號分割出的基本單句
string[] danju = new string[100];//單句的陣列儲存
int dan_num = 1;//第幾個單句
//基本單句的語法結構
string FindSubject = "";//主語
string FindVerb = "";//謂語動詞
string FindObject = "";//賓語
string FindBuVerb = "";//賓語補足語的動詞
string FindBuNoun = "";//賓語補足語的名詞
string FindJianObject = "";//間接賓語
string FindZhiObject = "";//直接賓語
//名詞所有格(例如張三的貓,張三就是名詞所有格,“的”字就不寫了)
string SubjectSuoyouge = "";//主語的名詞所有格
string ObjectSuoyouge = "";//賓語的名詞所有格
//string JianSuoyouge = "";//間接賓語的名詞所有格
//string ZhiSuoyouge = "";//直接賓語的名詞所有格
//string BuSuoyouge = "";//賓語補足語的名詞所有格
string TempSuoyouge = "";//臨時存放名詞所有格
//形容詞
string SubjectAdj = "";//主語的形容詞
string ObjectAdj = "";//賓語的形容詞
//string JianAdj = "";//間接賓語的形容詞
//string ZhiAdj = "";//直接賓語的形容詞
//string BuAdj = "";//賓語補足語的形容詞
//數詞
string SubjectNum = "";//主語的數詞
string ObjectNum = "";//賓語的數詞
//string JianNum = "";//間接賓語的數詞
//string ZhiNum = "";//直接賓語的數詞
//string BuNum = "";//賓語補足語的數詞
//語法結構的相關描述
string SentenceType = "";//句型
string yutai = "";//語態:主動語態還是被動語態
string VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
//名詞槽(名詞之間相互覆蓋時用)
string NounBox1 = "";//名詞槽1
string NounBox2 = "";//名詞槽2
string NounBox3 = "";//名詞槽3
string NounBox4 = "";//名詞槽4
//動詞槽(動詞之間相互覆蓋時用)
string VerbBox1 = "";//動詞槽1
string VerbBox2 = "";//動詞槽2
string VerbBox3 = "";//動詞槽3
string VerbBox4 = "";//動詞槽4
//數詞和時間
string FindNum = "";//要找的數詞的數字
string NumDanwei = "";//數詞單位
string FindTime_year = "";//要找的時間:年
string FindTime_month = "";//要找的時間:月
string FindTime_day = "";//要找的時間:日
string FindTime_hour = "";//要找的時間:小時
string FindTime_minute = "";//要找的時間:分鐘
string FindTime2 = "";//要找的時間(文字形式,例如下午、星期一)
string num_type = "";//數字型別:阿拉伯數字(例如1、2、3)還是漢字型數字(例如一、二、三)

// Start is called before the first frame update
void Start()
{
    ciku();//填充詞庫
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應(按Enter鍵傳送)
}

// Update is called once per frame
void Update()
{

}

//填充詞庫(資料庫的詞庫填充到陣列中)
void ciku()
{
    //生成遊戲後,需要把sqlite資料庫複製到生成的遊戲的資料夾裡,那個資料夾自動生成的這個資料庫是0kb,無效的,需要重新複製過去
    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量

    //填充形容詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM adj";//sql指令
    //第二步:執行指令
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        adj[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示形容詞數量

    dbConnection.Close();//關閉資料庫連線
}

//輸入完成後,按Enter鍵傳送,便開始執行此函式
void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的內容
    SplitSay();//按標點符號,分割輸入內容
}

//按標點符號,分割輸入內容,分割成基本單句
void SplitSay()
{
    /*
    輸入的內容可能是一大段內容,需要分割成一個個基本單句,從而逐一處理。
    基本單句就是主語-謂語-賓語,或主語-謂語-間接賓語-直接賓語,或主語-謂語-賓語-賓語補足語,這類語法上的基本單句。
    那就需要按逗號分割句子,按句號分割句子,才能拆分成一個個這樣的基本單句。

    按逗號分割句子:
    string str = "早晨,中午,下午";
    string word = ",";
    string[] shuzu = str.Split(word);//按word指定的分隔符,分割字串,並存入陣列中
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    按逗號和句號分割句子:
    string str = "早晨,中午。下午,傍晚";
    string word = ",";
    string[] shuzu = str.Split(word);//按word指定的分隔符(逗號),分割字串,並存入陣列中
    foreach (string part in shuzu)
    {
        string word2 = "。";
        string[] shuzu2 = part.Split(word2);//按word2指定的分隔符(句號),分割字串,並存入陣列中
        foreach (string part2 in shuzu2)
        {
            UnityEngine.Debug.Log(part2);
        }
    }

    計算標點符號的數量:
    string str = "早晨,中午。下午,傍晚";
    string temp = "";

    int dou = 0;//逗號數量
    int ju = 0;//句號數量
    int str_length = str.Length;//句子長度

    temp = str.Replace(",", "");//把逗號替換為空無,就是去掉逗號
    int str_length_delete_dou = temp.Length;//去掉逗號後,句子的長度
    dou = str_length - str_length_delete_dou;//兩者相減,就是逗號的數量

    temp = str.Replace("。", "");//把句號替換為空無,就是去掉句號
    int str_length_delete_ju = temp.Length;//去掉句號後,句子的長度
    ju = str_length - str_length_delete_ju;//兩者相減,就是句號的數量

    以上註釋掉的內容,只是解釋說明,下面才是執行的程式:
    */

    //計算標點符號的數量
    string temp = "";
    int dou = 0;//逗號數量
    int ju = 0;//句號數量
    int str_length = shuru.Length;//句子長度
    //計算逗號的數量
    temp = shuru.Replace(",", "");//把逗號替換為空無,就是去掉逗號
    int str_length_delete_dou = temp.Length;//去掉逗號後,句子的長度
    dou = str_length - str_length_delete_dou;//兩者相減,就是逗號的數量
    //計算句號的數量
    temp = shuru.Replace("。", "");//把句號替換為空無,就是去掉句號
    int str_length_delete_ju = temp.Length;//去掉句號後,句子的長度
    ju = str_length - str_length_delete_ju;//兩者相減,就是句號的數量

    //按標點符號分割句子
    if (dou > 0 || ju > 0)//逗號大於0或句號大於0,就是輸入的內容有標點符號
    {
        string word = ",";//分割符:中文的逗號
        string[] shuzu = shuru.Split(word);//按word指定的分隔符(逗號),分割字串,並存入陣列中
        foreach (string part in shuzu)//逐個處理
        {
            string word2 = "。";//分割符:中文的句號
            string[] shuzu2 = part.Split(word2);//按word2指定的分隔符(句號),分割字串,並存入陣列中
            foreach (string part2 in shuzu2)//逐個處理
            {
                dan = part2;//基本單句已經分割出來了,在part2裡,並賦值給dan(基本單句)
                danju[dan_num - 1] = part2;//陣列從0開始計算,而danju從1開始計算,所以換算上要減1
                ClearData();//清除上次的變數資料
                //UnityEngine.Debug.Log("單句:" + dan);
                SearchVerb(dan);//找謂語動詞(這是單句處理的第一步)
                dan = "";
                dan_num++;
            }
        }
    }
    else//輸入的內容,沒有標點符號
    {
        if (shuru != "")//有輸入的內容
        {
            dan = shuru;//輸入的內容就是一個基本單句
            danju[0] = shuru;
            SearchVerb(dan);//找謂語動詞
            dan = "";
        }
    }
}

//清除上次迴圈(基本單句處理)的變數資料
void ClearData()
{
    FindSubject = "";//主語
    FindVerb = "";//謂語動詞
    FindObject = "";//賓語
    FindBuVerb = "";//賓語補足語的動詞
    FindBuNoun = "";//賓語補足語的名詞
    FindJianObject = "";//間接賓語
    FindZhiObject = "";//直接賓語
    SubjectSuoyouge = "";//主語的名詞所有格
    ObjectSuoyouge = "";//賓語的名詞所有格
    TempSuoyouge = "";//臨時存放名詞所有格
    SubjectAdj = "";//主語的形容詞
    ObjectAdj = "";//賓語的形容詞
    SubjectNum = "";//主語的數詞
    ObjectNum = "";//賓語的數詞
    SentenceType = "";//句型
    yutai = "";//語態:主動語態還是被動語態
    VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
    NounBox1 = "";//名詞槽1
    NounBox2 = "";//名詞槽2
    NounBox3 = "";//名詞槽3
    NounBox4 = "";//名詞槽4
    VerbBox1 = "";//動詞槽1
    VerbBox2 = "";//動詞槽2
    VerbBox3 = "";//動詞槽3
    VerbBox4 = "";//動詞槽4
    FindNum = "";
    NumDanwei = "";
    num_type = "";
    i = 0;
}

//找謂語動詞
void SearchVerb(string str)
{
    string jieguo = "不包含";//預設值是不包含動詞
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞

    VerbBox1 = "";
    VerbBox2 = "";
    VerbBox3 = "";
    VerbBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (str.Contains(verb[n]))//包含動詞
        {
            if (VerbJudge(str, verb[n]) == true)//是動詞,不是名詞
            {
                jieguo = "包含";
                FindVerb = verb[n];//找到了動詞
                VerbCover(str, verb[n]);//把動詞放入動詞槽裡,看看有幾個動詞
                VerbOrder();//動詞排序
                VerbJoin();//動詞結合
            }
        }
    }

    if (jieguo == "包含")//包含動詞
    {
        VerbRateJudge();//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
        SentenceType = SentenceJudge();//判斷句型(僅從動詞情況來判斷句型,還不是完全清楚的判斷,之後還需進一步判斷)
        SplitSentence();//以謂語動詞為分割符,來分割句子
    }
}

//以謂語動詞為分割符,來分割句子
void SplitSentence()
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string word = "嘲笑";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞語的起始位置
    int LastIndex = 0;//指定詞語最後一個字元在全句中的位置
    int jie = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    //計算指定字元在全句中的位置
    index = str.IndexOf(word) + 1;//預設從0計算,例如第2個字元,顯示為1,而不是2。為了調整為1開始計算,所以加1
    //計算指定詞語最後一個字元在全句中的位置
    LastIndex = str.IndexOf(word) + word.Length;

    //擷取第3個字元右邊的1個字元
    Substring(開始位置, 向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元

    //擷取指定字元右邊的全部字元
    jie = chang - LastIndex;//擷取長度 = 全句長度 - 指定詞語最後一個字元的位置長度
    res = str.Substring(LastIndex, jie);
    res = str.Substring(str.IndexOf(word) + word.Length, str.Length - (str.IndexOf(word) + word.Length));//展開形式

    //擷取指定字元左邊的全部字元
    res = str.Substring(0, index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0, str.IndexOf(word));//變化形式

    //擷取兩個指定字元之間的全部字元
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    以上註釋掉的內容,只是解釋原理,下面是執行的程式:
    */

    string LeftPart = "";//謂語動詞的左邊句
    string RightPart = "";//謂語動詞的右邊句

    //也可能找到一個動詞(主謂賓句型),也可能找到兩個動詞(賓語補足語句型)
    if (VerbBox1 != "" && VerbBox2 == "")//只找到1個動詞,那就是謂語動詞
    {
        FindVerb = VerbBox1;
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//找到2個動詞
    {
        FindVerb = VerbBox1;//位次在前面的動詞是謂語動詞
        FindBuVerb = VerbBox2;//位次在後面的動詞是賓語補足語動詞
    }

    //謂語動詞左邊句(LeftPart)和謂語動詞右邊句(RightPart)是一個重要的轉折,為以後的句子處理奠定了基礎
    LeftPart = dan.Substring(0, dan.IndexOf(FindVerb));
    RightPart = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.Length - (dan.IndexOf(FindVerb) + FindVerb.Length));

    /*
    例如句子(dan)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);//謂語動詞
    UnityEngine.Debug.Log(LeftPart);//謂語動詞的左邊句
    UnityEngine.Debug.Log(RightPart);//謂語動詞的右邊句
    */

    /*
    省略主語有兩種情況:一種是主動語態省略主語,例如“跳過去”,全句指“你跳過去”。另一種是被動語態省略主語,例如“張三被打了”,沒說誰打了張三,這裡張三是賓語。如果說“李四打了張三”,李四就是主語。
    被動語態的標誌是“被”字,如果沒有“被”字,而且省略了主語,就是主動語態省略主語的情況,那麼這種情況下,主語應該填什麼呢?例如“過來”,一般指“你過來”,但“走吧”一般指“我們走吧”。所以程式要根據具體的動詞來判斷省略的主語應該填什麼。但是動詞太多,每個動詞都要設定省略的主語判斷,太麻煩。所以省略主語,按最通常情況,就預設填“你”字,作為主語。如果主語是“我們”而不是“你”字,就不該省略主語。
    被動語態應該還原為主動語態去理解,但被動語態往往沒有主語,那麼預設主語應該填什麼呢?畢竟不知道主語,那就填“事物”這個詞作為主語。
    程式分析句子時,被動語態的主語位置的詞,是賓語。例如“李四被打了”,李四在謂語動詞左邊句,程式會把李四當成主語,但在被動語態句裡,李四不是主語,所以有“被”字的時候,主語要挪動到賓語位置,然後在主語位置補充“事物”這個詞,作為主語。
    但是有些時候,被動語態的主語是說明了的,例如“李四被張三打了”就還原為主動語態“張三打了李四”,張三做主語,而不是填“事物”做主語。
    簡而言之,被動語態裡,主語放到了賓語位置,賓語放到了主語位置,所以變為主動語態時,要把賓語挪回主語位置,主語挪回賓語位置。
    如果被動語態有主語,例如“李四被張三打了”,那麼主語(張三)位於“被”字與謂語動詞之間。
    那麼謂語動詞左邊句中,又分為“被”字左邊句和“被”字右邊句,被字左邊句裡的名詞是賓語,被字右邊句裡的名詞是主語。
    */
    yutai = "主動";//預設主動語態
    if (SentenceType == "主謂賓" && dan.Contains("被"))//語句中包含“被”字
    {
        if (dan.Contains("被子") == false && dan.Contains("被褥") == false)//語句中包含“被”字,但不是“被子”這個名詞,才能指被動語態的“被”字
        {
            yutai = "被動";//被動語態
        }
        else
        {
            yutai = "主動";//主動語態
        }
    }
    else//語句中沒有包含“被”字
    {
        yutai = "主動";//主動語態
    }

    //對謂語動詞左邊句(LeftPart)的處理
    if (LeftPart != "")//謂語動詞左邊句有內容
    {
        if (yutai == "主動")//主動語態
        {
            //找名詞(主語)和名詞所有格
            FindSubject = SearchNoun(LeftPart);//在謂語動詞左邊句找名詞(主語)
            if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
            {
                SubjectSuoyouge = TempSuoyouge;//是主語的名詞所有格
                TempSuoyouge = "";//置空
            }
            //找形容詞(主語的形容詞)
            SubjectAdj = SearchAdj(LeftPart);
            //找數詞
            FindNum = "";
            NumDanwei = "";
            num_type = "";
            SearchNum(LeftPart);
            SubjectNum = FindNum + NumDanwei;
            //找時間
            SearchTime1(LeftPart);//找時間:文字形式,例如今天、星期一
            SearchTime2(LeftPart);//找時間:年月日時分
        }
        else if (yutai == "被動")//被動語態
        {
            string bei = "被";
            string BeiLeft = "";
            string BeiRight = "";

            //被字左邊句
            BeiLeft = LeftPart.Substring(0, LeftPart.IndexOf(bei));
            if (BeiLeft != "")
            {
                FindObject = SearchNoun(BeiLeft);//被字左邊句的名詞是賓語
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
                    TempSuoyouge = "";//置空
                }
                //找形容詞(賓語的形容詞)
                ObjectAdj = SearchAdj(BeiLeft);
                //找數詞
                FindNum = "";
                NumDanwei = "";
                num_type = "";
                SearchNum(BeiLeft);
                ObjectNum = FindNum + NumDanwei;
            }

            //被字右邊句
            BeiRight = LeftPart.Substring(LeftPart.IndexOf(bei) + bei.Length, LeftPart.Length - (LeftPart.IndexOf(bei) + bei.Length));
            
            if (BeiRight != "")
            {
                FindSubject = SearchNoun(BeiRight);//被字右邊句的名詞是主語
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    SubjectSuoyouge = TempSuoyouge;//是主語的名詞所有格
                    TempSuoyouge = "";//置空
                }
                //找形容詞(主語的形容詞)
                SubjectAdj = SearchAdj(BeiRight);
                //找數詞
                FindNum = "";
                NumDanwei = "";
                num_type = "";
                SearchNum(BeiRight);
                SubjectNum = FindNum + NumDanwei;
            }
            //如果沒有主語,就填補“事物”這個詞作為主語,畢竟被動語態經常沒有主語
            if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
            {
                FindSubject = "事物";
            }
        }
    }

    //如果省略主語,則填補省略的主語
    if (yutai == "主動")
    {
        if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
        {
            FindSubject = "你";//預設填補“你”字做主語
        }
    }

    //對謂語動詞右邊句(RightPart)的處理
    if (SentenceType == "雙賓語")//雙賓語句型
    {
        FindObject = SearchNoun(RightPart);//找名詞

        //謂語動詞右邊句裡,沒有第二個賓語名詞,那就不是雙賓語
        //例如雖然有雙賓語句的標誌動詞“教”字,但他教我數學,是雙賓語句,而他教書,是主謂賓句型
        if (NounBox2 == "")
        {
            SentenceType = "主謂賓";
        }
        else
        {
            ShowResult();//顯示最終輸出結果
        }
    }

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        if (RightPart != "")
        {
            if (yutai == "主動")
            {
                //找名詞和名詞所有格
                FindObject = SearchNoun(RightPart);//在謂語動詞右邊句找名詞(賓語)
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
                    TempSuoyouge = "";//置空
                }

                //找形容詞(賓語的形容詞)
                ObjectAdj = SearchAdj(RightPart);
                //找數詞
                FindNum = "";
                NumDanwei = "";
                num_type = "";
                SearchNum(RightPart);
                ObjectNum = FindNum + NumDanwei;
            }
        }

        ShowResult();//顯示最終輸出結果
    }

    if (SentenceType == "賓語補足語")//賓語補足語句型
    {
        //謂語動詞到賓語補足語動詞之間的部分裡的名詞,是賓語名詞
        string temp = "";
        //擷取謂語動詞FindVerb和賓語補足語動詞FindBuVerb之間的部分
        temp = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.IndexOf(FindBuVerb) - (dan.IndexOf(FindVerb) + FindVerb.Length));
        FindObject = SearchNoun(temp);//找名詞
        if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
        {
            ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
            TempSuoyouge = "";//置空
        }
        //賓語補足語右邊句的名詞,是賓語補足語名詞,而不是賓語名詞
        int WordLastChar = dan.IndexOf(FindBuVerb) + FindBuVerb.Length;//賓語補足語動詞最後一個字元的位置
        if (WordLastChar < dan.Length)//賓語補足語動詞最後一個字元的位置沒有到全句末尾,就是說賓語補足語動詞後面還有內容,那就是賓語補足語名詞
        {
            //擷取賓語補足語動詞右邊的內容
            FindBuNoun = dan.Substring(dan.IndexOf(FindBuVerb) + FindBuVerb.Length, dan.Length - (dan.IndexOf(FindBuVerb) + FindBuVerb.Length));
            //以後再寫找賓語補足語名詞的名詞所有格
        }

        ShowResult();//顯示最終輸出結果
    }

    /*
    靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

    第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    所以建立一個函式:WordCover(覆蓋)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。

    第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    對於第二個問題的解決方法:
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    所以建立一個de函式。

    第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。
    所以建立一個VerbJudge函式。
    */
}

//找名詞(也包括找名詞所有格)
string SearchNoun(string PartSentence)
{
    string jieguo = "不包含";//預設值是不包含
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞

    //for迴圈前,先把詞語槽清空,因為for迴圈時,呼叫的函式WordCover要用詞語槽,來完成詞語的覆蓋和吸收
    NounBox1 = "";
    NounBox2 = "";
    NounBox3 = "";
    NounBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//包含
        {
            jieguo = "包含";
            if (de(PartSentence, noun[n]) == false)//找到的名詞右邊的第一個字元不是“的”字,才算是名詞,否則是名詞所有格
            {
                NounCover(noun[n]);
            }
            else//名詞右邊的第一個字是“的”字,就意味著是名詞所有格
            {
                TempSuoyouge = noun[n];//找到的名詞所有格
            }
        }
    }

    if (jieguo == "包含")//找到了名詞
    {
        NounOrder();//名詞排序
        //名詞要先排序,才能合併名詞,否則“足球”和“學校”的順序如果變成“學校”和“足球”,那就合併成“學校足球”這個詞了,而不是“足球學校”

        //如果雙賓語句型進行名詞合併,就可能會把間接賓語名詞和直接賓語名詞合併到一起,成為一個名詞,就不對了
        if (SentenceType != "雙賓語")//不是雙賓語句型
        {
            NounJoin();//名詞合併,例如把“足球”和“學校”合併成“足球學校”這一個名詞
        }
        else if (SentenceType == "雙賓語")//是雙賓語句型
        {
            //但是如果現在處理的是雙賓語結構的謂語動詞左邊句,也就是處理主語,還是可以名詞合併的
            if (dan.IndexOf(NounBox1) < dan.IndexOf(FindVerb))
            {
                NounJoin();//名詞合併
            }
        }

        return NounBox1;
    }
    else
    {
        return "";
    }
}

//名詞之間的覆蓋
void NounCover(string FindWord)
{
    /*
    熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。
    做了4個詞語槽(NounBox),為了以後適應複雜的句子,但簡單的主謂賓句型,一個詞語槽就夠了。
    */
    if (NounBox1 == "" && FindWord != "")//詞語槽還是空的,說明這是找到的第一個詞
    {
        NounBox1 = FindWord;//找到的第1個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽2了
    }
    else if (NounBox1 != "" && FindWord != "")//詞語槽1已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox1))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽1(NounBox1)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽2了
        }
        else if (NounBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽1(NounBox1)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,不要這個詞了,免得填到詞語槽2了
        }
    }

    if (NounBox2 == "" && FindWord != "")//詞語槽2是空的,FindWord經過詞語槽1,沒有覆蓋或吸收,說明FindWord和詞語槽1的詞無關,例如FindWord是竹子
    {
        NounBox2 = FindWord;//找到的第2個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽3了
    }
    else if (NounBox2 != "" && FindWord != "")//詞語槽2已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox2))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽2(NounBox2)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (NounBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽2(NounBox2)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (NounBox3 == "" && FindWord != "")//詞語槽3是空的,FindWord經過詞語槽2,沒有覆蓋或吸收,說明FindWord和詞語槽2的詞無關,例如FindWord是竹子
    {
        NounBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (NounBox3 != "" && FindWord != "")//詞語槽3已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox3))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽3(NounBox3)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (NounBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽3(NounBox3)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (NounBox4 == "" && FindWord != "")//詞語槽4是空的,FindWord經過詞語槽3,沒有覆蓋或吸收,說明FindWord和詞語槽3的詞無關,例如FindWord是竹子
    {
        NounBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (NounBox4 != "" && FindWord != "")//詞語槽4已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox4))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽4(NounBox4)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (NounBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽4(NounBox4)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空
        }
    }

    /*
    “足球”這個詞,會找到三個名詞:足、球、足球。
    先找到第一個詞:足,放入NounBox1。
    再找到第二個詞:球,放入NounBox2。
    再找到第三個詞:足球,會覆蓋NounBox1的“足”字,但卻無法覆蓋NounBox2的球字。
    因此程式做一些改進。

    但如果幸運的:
    先找到第一個詞:足球,放入NounBox1。
    再找到第二個詞:足,被NounBox1“足球”這個詞吸收,不會進入到NounBox2。
    再找到第三個詞:球,被NounBox1“足球”這個詞吸收,也不會進入到NounBox2。
    那麼就不用執行下面這段程式了。
    先找到那個詞是不確定的,詞庫詞語可能按筆畫排序,也可能按首字母排序,就不知道先找到那個詞了。

    如果輸入的是“皮球”這個詞,而詞庫裡沒有“皮球”這個詞,但有“皮”字和“球”字這兩個詞。
    那麼,NounBox1是“皮”字,NounBox2是“球”字,或NounBox1是“球”字,NounBox2是“皮”字,沒有覆蓋和吸收。
    */
    if (NounBox1.Contains(NounBox2))//NounBox1包含了NounBox2,例如“足球”包含“球”字
    {
        NounBox2 = "";
        if (NounBox3 != "")
        {
            NounBox2 = NounBox3;
            NounBox3 = "";
        }
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox2.Contains(NounBox3))//NounBox2包含了NounBox3
    {
        NounBox3 = "";
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox3.Contains(NounBox4))//NounBox3包含了NounBox4
    {
        NounBox4 = "";
    }
}

//動詞之間的覆蓋
void VerbCover(string str,string FindWord)
{
    if (VerbBox1 == "" && FindWord != "")//動詞槽還是空的,說明這是找到的第一個詞
    {
        VerbBox1 = FindWord;//找到的第1個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽2了
    }
    else if (VerbBox1 != "" && FindWord != "")//動詞槽1已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox1))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽1(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“敲打”覆蓋“打”
            FindWord = "";//置空,免得填到動詞槽2了
        }
        else if (VerbBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽1(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,不要這個詞了,免得填到動詞槽2了
        }
    }

    if (VerbBox2 == "" && FindWord != "")//動詞槽2是空的,FindWord經過動詞槽1,沒有覆蓋或吸收,說明FindWord和動詞槽1的詞無關,例如FindWord是喜歡
    {
        VerbBox2 = FindWord;//找到的第2個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽3了
    }
    else if (VerbBox2 != "" && FindWord != "")//動詞槽2已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox2))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽2(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (VerbBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽2(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (VerbBox3 == "" && FindWord != "")//動詞槽3是空的,FindWord經過動詞槽1和2,沒有覆蓋或吸收,說明FindWord和動詞槽1、2的詞無關,例如FindWord是喜歡
    {
        VerbBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (VerbBox3 != "" && FindWord != "")//動詞槽3已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox3))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽3(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (VerbBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽3(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (VerbBox4 == "" && FindWord != "")//動詞槽4是空的,FindWord經過動詞槽1、2、3,沒有覆蓋或吸收,說明FindWord和動詞槽1、2、3的詞無關,例如FindWord是喜歡
    {
        VerbBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (VerbBox4 != "" && FindWord != "")//動詞槽4已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox4))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽4(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (VerbBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽4(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空
        }
    }

    /*
    “敲打”這個詞,會找到三個動詞:敲、打、敲打
    先找到第一個詞:敲,放入VerbBox1
    再找到第二個詞:打,放入VerbBox2
    再找到第三個詞:敲打,會覆蓋VerbBox1的“敲”字,但卻無法覆蓋VerbBox2的“打”字
    因此程式做一些改進。 
    */
    if (VerbBox1.Contains(VerbBox2))//VerbBox1包含了VerbBox2
    {
        VerbBox2 = "";
        if (VerbBox3 != "")
        {
            VerbBox2 = VerbBox3;
            VerbBox3 = "";
        }
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox2.Contains(VerbBox3))//VerbBox2包含了VerbBox3
    {
        VerbBox3 = "";
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox3.Contains(VerbBox4))//VerbBox3包含了VerbBox4
    {
        VerbBox4 = "";
    }
}

//名詞後面是否包含“的”字
bool de(string str,string word)
{
    /*
    熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    
    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }
    UnityEngine.Debug.Log(res);//顯示:的
    以上註釋掉的內容只是解釋原理,下面是執行程式:
    */

    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果
    WordLastChar = str.IndexOf(word) + word.Length;
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }

    if (res == "的")
    {
        return true;
    }
    else
    {
        return false;
    }

}

//判斷一個字是動詞還是名詞
bool VerbJudge(string str,string word)
{
    /*
    “學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞,也就是辨析字。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。
    “壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。

    不容易理解的一處:
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   吹     |   l1    |      電      |
    +----------+---------+--------------+
    “吹”字本身做動詞,但在“電吹風”這個詞裡做名詞,但我不用把“電吹風”這個三個字都判斷,我只要判斷“電吹”兩個字就可以了。

    遇到單字動詞的時候,先看這個字是否在詞性辨析表裡,
    如果在,type_col要求是r1(right1,就是要辨析的字的右邊1個字元),那就看句子中要辨析的字的右邊1個字元是不是符合詞性表中的字,
    如果符合,要辨析的字就是名詞,而不是動詞了。
    例如學生看書,這句話先找到了動詞“學”,在詞性辨析表裡,“學”字的type_col是r1,content_col是“生”字,
    那就在句子中,看“學”字右邊的1個字元是不是“生”字,如果是,“學”字就不做動詞,而做名詞了。

    一個要辨析的字,type_col有四種可能:r1、r2、l1、l2,也就是右邊1個字,右邊2個字,左邊1個字,左邊2個字,那就要會四個方法:
    符合r1:找辨析字右邊1個字元:res = str.Substring(str.IndexOf(word) + word.Length, 1);
    符合r2:找辨析字右邊2個字元:res = str.Substring(str.IndexOf(word) + word.Length, 2);
    符合l1:找辨析字左邊1個字元:res = str.Substring(str.IndexOf(word) - 1, 1);
    符合l2:找辨析字左邊2個字元:res = str.Substring(str.IndexOf(word) - 2, 1);

    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
        res = str.Substring(str.IndexOf(word) + word.Length, 1);//變化形式

    }
    UnityEngine.Debug.Log(res);//顯示:的

    //指定詞語左邊1個字元
    res = str.Substring(index - 1, 1);
    res = str.Substring(str.IndexOf(word) - 1, 1);//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃
    以上註釋掉的內容,只是解釋原理,下面是執行程式:
    */

    string[] TypeCol = new string[100];//把詞性辨析表的辨析字對應的type_col值填充此陣列
    string[] ContentCol = new string[100];//把詞性辨析表的辨析字對應的content_col值填充此陣列
    string res = "";//擷取的字元
    bool shima = true;//預設判斷是動詞

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    //字元型變數要有引號,數字型變數不需要引號
    //word是變數,動態的,不能直接放到sql語句裡面
    string sqlQuery = "select type_col,content_col from verb_judge where word_col = '" + word + "'";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充詞性辨析陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();

    i = 0;
    while (dbReader.Read())
    {
        //查詢了2列(type_col和content_col),所以返回的結果集有2列,分別用GetValue(0)和GetValue(1)
        TypeCol[i] = dbReader.GetValue(0).ToString();//返回的結果集的第1列
        ContentCol[i] = dbReader.GetValue(1).ToString();//返回的結果集的第2列
        i++;//雖然定義陣列長度為10,但i不一定填滿了10
    }
    dbReader.Close();
    dbConnection.Close();
    
    if (i > 0)//在詞性辨析表裡找到內容了,否則i還是預設的0
    {
        for (int n = 0; n < i; n++)//遍歷詞性辨析表找到的各種結果
        {
            if (TypeCol[n] == "r1")//right1:右邊1個字元
            {
                if (str.IndexOf(word) + word.Length + 1 <= str.Length)//要往右判斷1個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 1);//擷取動詞右邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "r2")//right2:右邊2個字元
            {
                if (str.IndexOf(word) + word.Length + 2 <= str.Length)//要往右判斷2個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 2);//擷取動詞右邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "l1")//left1:左邊1個字元
            {
                if (str.IndexOf(word) - 1 >= 0)//要往左判斷1個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 1, 1);//擷取動詞左邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }

                }
            }
            else if (TypeCol[n] == "l2")//left2:左邊2個字元
            {
                if (str.IndexOf(word) - 2 >= 0)//要往左判斷2個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 2, 2);//擷取動詞左邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
        }
    }
    i = 0;
    return shima;
}

//判斷句型
string SentenceJudge()
{
    /*
    基本單句有六種句型:
    只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
    主語(動作執行者)-謂語(動作):張三摔倒。
    主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
    主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
    雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
    賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
    前面只說了主謂賓句型,還要處理其它句型。

    雙賓語句型:
    雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
    但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
    雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
    那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
    還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
    僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
    名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

    賓語補足語句型:
    和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
    因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
    但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
    既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
    動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
    賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

    雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

    在主謂賓句型的基礎上,如果沒有賓語,就是主謂句型。如果沒有主語,就是省略主語,例如對一個人喊“過來”,這句話的全句顯然是“你過來”。
    */

    if (VerbBox1 == "")//沒有動詞
    {
        return "只有性質狀態";//只有性質狀態的句型
    }
    else if (VerbBox1 != "" && VerbBox2 == "")//有1個動詞
    {
        if (VerbBox1 == "給" || VerbBox1 == "送" || VerbBox1 == "送給" || VerbBox1 == "教")//雙賓語句型的常見動詞(標誌詞)
        {
            return "雙賓語";//雙賓語句型
        }
        else
        {
            return "主謂賓";//主謂賓句型
        }
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//有2個動詞
    {
        return "賓語補足語";//賓語補足語句型
    }
    else
    {
        return "其它";
    }
}

//名詞排序
void NounOrder()
{
    if (NounBox1 != "" && NounBox2 != "")//招到了2個名詞,放在NounBox1和NounBox2
    {
        string temp = "";//臨時變數
        if (dan.IndexOf(NounBox1) > dan.IndexOf(NounBox2))//如果NounBox1的名詞在句子中的位置大於NounBox2的名詞在句子中的位置
        {
            //交換位置,在句子中位置小的名詞放前面,從而確保雙賓語句型時,NounBox1放的是間接賓語,NounBox2放的是直接賓語,畢竟間接賓語在直接賓語前面
            temp = NounBox1;
            NounBox1 = NounBox2;
            NounBox2 = temp;
        }
        FindJianObject = NounBox1;
        FindZhiObject = NounBox2;
        //間接賓語和直接賓語的名詞所有格,之後再做
    }
}

//名詞結合成名詞片語
void NounJoin()
{
    /*
    名詞合併:例如“足球學校”這個詞,會被當成兩個名詞“足球”和“學校”。但實際中,要把它們合併成一個組合名詞,作為主語或賓語。
    前面說了判斷兩個字元之間的內容,如果兩個字元(詞語)是連續的,那麼這兩個詞語之間的內容為空。
    示例:
    //擷取兩個指定字元之間的全部字元
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string res = "";//結果
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式
    if (res == "")
    {
        UnityEngine.Debug.Log("連續");
    }
    else
    {
        UnityEngine.Debug.Log("不連續");
    }
    */
    
    string res;
    //判斷NounBox1和NounBox2的名詞是否需要合併
    if (NounBox1 != "" && NounBox2 != "")
    {
        res = "";
        //判斷NounBox1和NounBox2之間是否有內容,如果沒內容(res為空),就說明NounBox1和NounBox2是連續的名詞(中間沒有字元間隔),需要合併
        res = dan.Substring(dan.IndexOf(NounBox1) + NounBox1.Length, dan.IndexOf(NounBox2) - (dan.IndexOf(NounBox1) + NounBox1.Length));
        if (res == "")
        {
            NounBox1 = NounBox1 + NounBox2;//名詞合併
            NounBox2 = "";//合併後,置空
            if (NounBox3 != "")
            {
                NounBox2 = NounBox3;//填補置空的值,否則NounBox1有值,NounBox2為空,NounBox3又有值,就間隔了
                NounBox3 = "";//合併後,置空
                if (NounBox4 != "")
                {
                    NounBox3 = NounBox4;
                    NounBox4 = "";//合併後,置空
                }
            }
        }
    }

    /*
    //判斷NounBox2和NounBox3的名詞是否需要合併
    if (NounBox2 != "" && NounBox3 != "")
    {
        res = "";
        //判斷NounBox2和NounBox3之間是否有內容,如果沒內容(res為空),就說明NounBox2和NounBox3是連續的名詞,需要合併
        res = dan.Substring(dan.IndexOf(NounBox2) + NounBox2.Length, dan.IndexOf(NounBox3) - (dan.IndexOf(NounBox2) + NounBox2.Length));
        if (res == "")
        {
            NounBox2 = NounBox2 + NounBox3;//名詞合併
            NounBox3 = "";//合併後,置空
            if (NounBox4 != "")
            {
                NounBox3 = NounBox4;//填補置空的值
                NounBox4 = "";//合併後,置空
            }
        }
    }

    //判斷NounBox3和NounBox4的名詞是否需要合併
    if (NounBox3 != "" && NounBox4 != "")
    {
        res = "";
        //判斷NounBox3和NounBox4之間是否有內容,如果沒內容(res為空),就說明NounBox3和NounBox4是連續的名詞,需要合併
        res = dan.Substring(dan.IndexOf(NounBox3) + NounBox3.Length, dan.IndexOf(NounBox4) - (dan.IndexOf(NounBox3) + NounBox3.Length));
        if (res == "")
        {
            NounBox3 = NounBox3 + NounBox4;//名詞合併
            NounBox4 = "";//合併後,置空
        }
    }
    */
}

//動詞排序
void VerbOrder()
{
    /*
    如果不排序會怎樣?句子中找到的第一個動詞,可能不是謂語動詞,而是賓語補足語動詞,以賓語補足語動詞分割句子,就錯了。
    謂語動詞和賓語補足語動詞,先找到哪個,取決於這兩個詞,誰在動詞表前面排序,而動詞的排序是不可知的,或許按筆劃排序,或者按首字母排序
    */
    string temp = "";//臨時變數
    if (VerbBox1 != "" && VerbBox2 != "")//招到了個動詞,放在VerbBox1和VerbBox2
    {
        if (dan.IndexOf(VerbBox1) > dan.IndexOf(VerbBox2))//如果VerbBox1的動詞在句子中的位置大於VerbBox2的動詞在句子中的位置
        {
            //交換位置,在句子中位置小動詞的放前面,從而確保VerbBox1放的是謂語動詞,而賓語補足語動詞放到VerbBox2
            temp = VerbBox1;
            VerbBox1 = VerbBox2;
            VerbBox2 = temp;
        }

    }
    if (VerbBox3 != "")
    {
        if (dan.IndexOf(VerbBox1) > dan.IndexOf(VerbBox3))
        {
            temp = VerbBox1;
            VerbBox1 = VerbBox3;
            VerbBox3 = temp;
        }
        if (dan.IndexOf(VerbBox2) > dan.IndexOf(VerbBox3))
        {
            temp = VerbBox2;
            VerbBox2 = VerbBox3;
            VerbBox3 = temp;
        }
    }
    FindVerb = VerbBox1;
}

//動詞結合成動詞片語
void VerbJoin()
{
    //動詞合併:例如“應該愛”是兩個動詞:情態動詞“應該”和普通動詞“愛”,應該合併成一個動詞
    string res;
    //判斷VerbBox1和VerbBox2的動詞是否需要合併
    if (VerbBox1 != "" && VerbBox2 != "")
    {
        res = "";
        //判斷VerbBox1和VerbBox2之間是否有內容,如果沒內容(res為空),就說明VerbBox1和VerbBox2是連續的動詞(中間沒有字元間隔),需要合併
        res = dan.Substring(dan.IndexOf(VerbBox1) + VerbBox1.Length, dan.IndexOf(VerbBox2) - (dan.IndexOf(VerbBox1) + VerbBox1.Length));
        if (res == "")
        {
            VerbBox1 = VerbBox1 + VerbBox2;//名詞合併
            FindVerb = VerbBox1;
            VerbBox2 = "";//合併後,置空
            if (VerbBox3 != "")
            {
                VerbBox2 = VerbBox3;//填補置空的值,否則VerbBox1有值,VerbBox2為空,VerbBox3又有值,就間隔了
                VerbBox3 = "";//合併後,置空
                if (VerbBox4 != "")
                {
                    VerbBox3 = VerbBox4;
                    VerbBox4 = "";//合併後,置空
                }
            }
        }
    }

}

//謂語動詞的發生機率
void VerbRateJudge()
{
    /*
    動詞前面是否有否定詞,也很重要。
    例如“他愛貓”和“他不愛貓”,雖然謂語動詞都是“愛”字,但前面加個“不”字,意義就相反了。所以看謂語動詞前面是否有否定詞,是很重要的事。
    謂語動詞前面的否定詞,一般有不、不要、不可以、不應該、不能、別。
    還有不確定肯定還是否定動詞,例如“他不一定去”,“去”字是動詞,但是動詞前的“不一定”,並不像是“不”字那樣對動詞進行否定,而是對動詞既不像是肯定,也不像是否定,而是不確定。
    因此對每句話的謂語動詞,都要加一個性質:肯定、否定、不確定。
    但不確定,有時候偏向於肯定,例如“他可能去”。有時候不確定偏向於否定,例如“他不太可能去”以及“他或許不去”。
    那麼動詞發生機率分為五種:肯定、偏向肯定、不確定、偏向否定、否定。
    這其實就是在分析事情(謂語動詞)發生的機率,這在機率分析上有用。
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 1, 1);
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 2, 1);
    */

    VerbRate = "肯定";//預設值:肯定
    string temp = "";//臨時變數

    //先判斷謂語動詞左邊的1個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不"))
    {
        VerbRate = "否定";
    }
    else if(temp.Contains("別"))
    {
        VerbRate = "否定";
    }

    //判斷謂語動詞左邊的2個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不要"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不能"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("可能"))
    {
        VerbRate = "不確定";
    }
    else if (temp.Contains("或許"))
    {
        VerbRate = "不確定";
    }

    //判斷謂語動詞左邊的3個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不可以"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不應該"))
    {
        VerbRate = "否定";
    }
}

//找形容詞
string SearchAdj(string str)
{
    string jieguo = "不包含";//預設值是不包含
    int m = adj.Length;//形容詞陣列的長度,也就是有多少個形容詞
    string temp  = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和形容詞的包含關係
        就是用句子和形容詞陣列的形容詞,一一比對,來判斷是否包含形容詞
        n的值從0逐漸增長到形容詞陣列的形容詞數量值,這樣陣列也就經歷了所有形容詞
        */
        if (str.Contains(adj[n]))//包含
        {
            jieguo = "包含";
            temp = adj[n];
        }
    }

    if (jieguo == "包含")//找到了形容詞
    {
        return temp;
    }
    else
    {
        return "";
    }
}

//找數詞
void SearchNum(string str)
{
    //先確定數詞單位
    int StrLength = str.Length;//全句長度
    string temp = "";
    string NumDanwei_type = "";//數字單位型別

    string[] shuzu_danwei_mignci = new string[] { "個", "名", "位", "只", "頭", "匹", "條", "棵", "朵", "片", "根", "座", "棟", "臺", "部", "本", "塊", "件", "盞", "把", "所", "輛", "艘", "架", "扇" };
    string[] shuzu_danwei_jiliang = new string[] { "米", "釐米", "毫米", "分米", "公里", "裡", "微米", "奈米", "克", "斤", "公斤", "噸", "毫克", "升" };

    //字串從右向左,每次讀取一個字元進行處理
    for (int n = StrLength; n > 0; n--)
    {
        temp = str.Substring(n - 1, 1);//每次擷取的一個字元,例如“年”字

        if (NumDanwei_type == "")
        {
            //名詞單位陣列
            foreach (string m in shuzu_danwei_mignci)//判斷這個擷取的字元是否在名詞陣列中
            {
                if (temp == m)//擷取的字元屬於名詞陣列(shuzu_danwei_mignci)中的字元,例如“個”字屬於名詞陣列
                {
                    NumDanwei = m;
                    NumDanwei_type = "名詞單位";
                    SearchNum2(str, NumDanwei, NumDanwei_type);

                    if (num_type == "漢字型數字")
                    {
                        FindNum = SearchNum3(FindNum);
                    }
                    break;
                }
            }
        }

        if (NumDanwei_type == "")
        {
            //計量陣列
            foreach (string m in shuzu_danwei_jiliang)//判斷這個擷取的字元是否在計量陣列中
            {
                if (temp == m)//擷取的字元屬於計量陣列(shuzu_danwei_jiliang)中的字元,例如“米”字屬於計量陣列
                {
                    NumDanwei = m;
                    if (str.Contains("釐"))
                    {
                        NumDanwei = "釐" + NumDanwei;
                    }
                    else if (str.Contains("毫"))
                    {
                        NumDanwei = "毫" + NumDanwei;
                    }
                    else if (str.Contains("公"))
                    {
                        NumDanwei = "公" + NumDanwei;
                    }
                    NumDanwei_type = "計量單位";
                    SearchNum2(str, NumDanwei, NumDanwei_type);
                    if (num_type == "漢字型數字")
                    {
                        FindNum = SearchNum3(FindNum);
                    }
                    break;
                }
            }
        }
    }

    /*
    找數字的其它方法:正規表示式。
    需要using System.Text.RegularExpressions;//正規表示式找出數字所需
    replace函式把不是數字的部分變為空無,這樣就只剩下數字部分。
    string res = "";
    res = Regex.Replace(str, @"[^0-9]+", "");
    return res;
    */
}

void SearchNum2(string str, string temp, string NumDanwei_type)
{
    //找數字
    string[] shuzu_num = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
    string[] shuzu_num_cn = new string[] { "一", "二", "兩", "三", "四", "五", "六", "七", "八", "九", "零", "十", "百", "千", "萬" };

    //數量單位字元左邊的字串
    string WordLeft = str.Substring(0, str.IndexOf(temp));//例如“有6米”的“有6”

    //找阿拉伯數字,例如1、2、3這類數字
    //逐一處理該字元左邊的每個字元
    int WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
    string temp2 = "";
    //從右向左,逐字擷取
    for (int j = WordleftLength; j > 0; j--)
    {
        temp2 = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元
                                             //從右到左,遇到不是數字的時候,就退出迴圈
        if (temp2 != "1" && temp2 != "2" && temp2 != "3" && temp2 != "4" && temp2 != "5" && temp2 != "6" && temp2 != "7" && temp2 != "8" && temp2 != "9" && temp2 != "0")
        {
            break;
        }
        foreach (string m2 in shuzu_num)//判斷這個擷取的字元是否在數字陣列中
        {
            if (temp2 == m2)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
            {
                if (NumDanwei_type == "名詞單位" || NumDanwei_type == "計量單位")
                {
                    //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                    if (FindNum == "")
                    {
                        FindNum = temp2;
                    }
                    else
                    {
                        FindNum = temp2 + FindNum;
                    }
                    num_type = "阿拉伯數字";
                }
            }
        }
    }

    if (NumDanwei_type == "名詞單位" || NumDanwei_type == "計量單位")
    {
        if (FindNum == "")//沒有找到阿拉伯數字
        {
            //找漢字型數字,例如一、二、三
            WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
            temp2 = "";
            //從右向左,逐字擷取
            for (int j = WordleftLength; j > 0; j--)
            {
                temp2 = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元
                foreach (string m2 in shuzu_num_cn)//判斷這個擷取的字元是否在數字陣列中
                {
                    if (temp2 == m2)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
                    {
                        //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                        if (FindNum == "")
                        {
                            FindNum = temp2;
                        }
                        else
                        {
                            FindNum = temp2 + FindNum;
                        }
                        num_type = "漢字型數字";
                    }
                }
            }
        }
    }
}

string SearchNum3(string find_num)
{
    //漢字型數字轉化為阿拉伯數字,例如“二十”轉化為“20”
    //這個轉化有時候不準確
    int old = 1;
    int result = 0;
    string temp = "";
    int temp_num = 0;

    //old(上一位數字)需要初始化為1,不能初始化為0,也不能不賦值
    //因為如果數字開始(從左到右)第一個字元就是翻倍數(例如十),那麼翻倍的上一位數(old)不能預設0或NULL
    //如果翻倍數沒有上一位數,拿預設1當上一位數(old初始化為1),翻倍數乘以1,就等於翻倍數翻倍自身,這樣才正確

    for (int n = 1; n <= find_num.Length; n++)
    {
        temp = find_num.Substring(n - 1, 1);//每次擷取的一個字元
        switch (temp)
        {
            case "一":
                temp_num = 1;
                break;
            case "二":
                temp_num = 2;
                break;
            case "兩":
                temp_num = 2;
                break;
            case "三":
                temp_num = 3;
                break;
            case "四":
                temp_num = 4;
                break;
            case "五":
                temp_num = 5;
                break;
            case "六":
                temp_num = 6;
                break;
            case "七":
                temp_num = 7;
                break;
            case "八":
                temp_num = 8;
                break;
            case "九":
                temp_num = 9;
                break;
            case "零":
                temp_num = 0;
                break;
            case "十":
                temp_num = 10;
                break;
            case "百":
                temp_num = 100;
                break;
            case "千":
                temp_num = 1000;
                break;
            case "萬":
                temp_num = 10000;
                break;
            default:
                break;
        }

        if (temp_num != 10 && temp_num != 100 && temp_num != 1000 && temp_num != 10000)//不是翻倍字元(十、百、千、萬),而是0到9的數字
        {
            old = temp_num;//把數字存起來,下一次迴圈時,被下一位翻倍數所翻倍
            if (n == find_num.Length)//當i的長度等於總數字的長度,也就是到了最後一位數(個位數),不用翻倍了
            {
                result = result + temp_num;//個位數不用翻倍,直接加
            }
        }
        else//不是0到9的數字字元,而是翻倍字元,就要翻倍
        {
            //翻倍物件是上一位數字,就是old裡存的數字。因為這次迴圈走else路線,所以temp_num沒有賦值給old,因此old裡還是上一位的數字
            result = result + (old * temp_num);//此時的temp_num是翻倍單位(十、百、千、萬),不是0到9的數字,翻倍上一位數字(old)
        }
    }

    if (result != 0)
    {
        find_num = result.ToString();
        return find_num;
    }
    else
    {
        return "";
    }
}

//找時間(文字形式)
void SearchTime1(string str)
{
    string[] shuzu_danwei_time1 = new string[] { "今天", "明天", "後天", "昨天", "前天", "這個月", "下個月", "上個月", "今年", "明年", "去年" };
    string[] shuzu_danwei_time2 = new string[] { "早晨", "上午", "中午", "下午", "傍晚", "晚上", "傍晚", "夜晚", "半夜", "黎明", "黃昏", "清晨" };
    string[] shuzu_danwei_time3 = new string[] { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日", "禮拜一", "禮拜二", "禮拜三", "禮拜四", "禮拜五", "禮拜六", "禮拜天" };
    string[] shuzu_danwei_time4 = new string[] { "春天", "夏天", "秋天", "冬天", "春季", "夏季", "秋季", "冬季" };
    string[] shuzu_danwei_time5 = new string[] { "元旦", "大年三十", "除夕", "春節", "大年初一", "大年初二", "大年初三", "正月十五", "寒假", "清明節", "五一節", "勞動節", "兒童節", "暑假", "中秋節", "國慶節", "聖誕節", "假期", "休息日" };

    foreach (string m in shuzu_danwei_time1)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time2)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time3)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time4)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time5)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }
}

//找時間(年月日時分,佈置框架)
void SearchTime2(string str)
{
    //找年月日時分
    string TimeDanwei = "";

    if (str.Contains("年"))
    {
        TimeDanwei = "年";
        FindTime_year = SearchTime3(str, TimeDanwei);
    }
    if (str.Contains("月"))
    {
        TimeDanwei = "月";
        FindTime_month = SearchTime3(str, TimeDanwei);
        if (num_type == "漢字型數字")
        {
            FindTime_month = SearchNum3(FindTime_month);
        }
    }
    if (str.Contains("日"))
    {
        TimeDanwei = "日";
        FindTime_day = SearchTime3(str, TimeDanwei);
    }
    if (str.Contains("點"))
    {
        TimeDanwei = "點";
        FindTime_day = SearchTime3(str, TimeDanwei);
    }
    if (str.Contains("分"))
    {
        TimeDanwei = "分";
        FindTime_day = SearchTime3(str, TimeDanwei);
    }
}

//找時間(年月日時分,具體找)
string SearchTime3(string str, string TimeDanwei)
{
    //找數字
    string num = "";
    string[] shuzu_num = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
    string[] shuzu_num_cn = new string[] { "一", "二", "兩", "三", "四", "五", "六", "七", "八", "九", "零", "十", "百", "千", "萬" };

    //數量單位字元左邊的字串
    string WordLeft = str.Substring(0, str.IndexOf(TimeDanwei));
    //找阿拉伯數字,例如1、2、3這類數字
    //逐一處理該字元左邊的每個字元
    int WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
    string temp = "";
    //從右向左,逐字擷取
    for (int j = WordleftLength; j > 0; j--)
    {
        temp = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元

        //從右到左,遇到不是數字的時候,就退出迴圈
        if (temp != "1" && temp != "2" && temp != "3" && temp != "4" && temp != "5" && temp != "6" && temp != "7" && temp != "8" && temp != "9" && temp != "0")
        {
            break;
        }

        foreach (string m in shuzu_num)//判斷這個擷取的字元是否在數字陣列中
        {
            if (temp == m)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
            {
                //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                if (num == "")
                {
                    num = temp;
                }
                else
                {
                    num = temp + num;
                }
                num_type = "阿拉伯數字";

            }
        }
    }

    if (num == "")//沒有找到阿拉伯數字
    {
        //找漢字型數字,例如一、二、三
        WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
        temp = "";
        //從右向左,逐字擷取
        for (int j = WordleftLength; j > 0; j--)
        {
            temp = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元
            foreach (string m2 in shuzu_num_cn)//判斷這個擷取的字元是否在數字陣列中
            {
                if (temp == m2)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
                {
                    //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                    if (num == "")
                    {
                        num = temp;
                    }
                    else
                    {
                        num = temp + num;
                    }
                    num_type = "漢字型數字";
                }
            }
        }
    }

    if (num != "")
    {
        return num;
    }
    else
    {
        return "";
    }

}

//顯示最終輸出結果
void ShowResult()
{
    UnityEngine.Debug.Log("第" + dan_num + "句:" + danju[dan_num-1]);
    UnityEngine.Debug.Log("句型:" + SentenceType);

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("語態:" + yutai);
    }
    else if (SentenceType == "雙賓語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("間接賓語:" + FindJianObject);
        UnityEngine.Debug.Log("直接賓語:" + FindZhiObject);
    }
    else if (SentenceType == "賓語補足語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("賓語補足語動詞:" + FindBuVerb);
        UnityEngine.Debug.Log("賓語補足語名詞:" + FindBuNoun);
    }
    else if (SentenceType == "只有性質狀態")
    {
        UnityEngine.Debug.Log("只有性質狀態:" + dan);
    }

    UnityEngine.Debug.Log("動詞發生機率:" + VerbRate);

    //顯示名詞所有格
    if (SubjectSuoyouge != "")
    {
        UnityEngine.Debug.Log("主語的名詞所有格:" + SubjectSuoyouge);
    }
    if (ObjectSuoyouge != "")
    {
        UnityEngine.Debug.Log("賓語的名詞所有格:" + ObjectSuoyouge);
    }
    /*
    if (JianSuoyouge != "")
    {
        UnityEngine.Debug.Log("間接賓語的名詞所有格:" + JianSuoyouge);
    }
    if (ZhiSuoyouge != "")
    {
        UnityEngine.Debug.Log("直接賓語的名詞所有格:" + ZhiSuoyouge);
    }
    if (BuSuoyouge != "")
    {
        UnityEngine.Debug.Log("賓語補足語的名詞所有格:" + BuSuoyouge);
    }
    */

    //顯示形容詞
    if (SubjectAdj != "")
    {
        UnityEngine.Debug.Log("主語的形容詞:" + SubjectAdj);
    }
    if (ObjectAdj != "")
    {
        UnityEngine.Debug.Log("賓語的形容詞:" + ObjectAdj);
    }
    /*
    if (JianAdj != "")
    {
        UnityEngine.Debug.Log("間接賓語的形容詞:" + JianAdj);
    }
    if (ZhiAdj != "")
    {
        UnityEngine.Debug.Log("直接賓語的形容詞:" + ZhiAdj);
    }
    if (BuAdj != "")
    {
        UnityEngine.Debug.Log("賓語補足語的形容詞:" + BuAdj);
    }
    */

    //顯示數詞
    if (SubjectNum != "")
    {
        UnityEngine.Debug.Log("主語的數詞:" + SubjectNum);
    }
    if (ObjectNum != "")
    {
        UnityEngine.Debug.Log("賓語的數詞:" + ObjectNum);
    }
    /*
    if (JianNum != "")
    {
        UnityEngine.Debug.Log("間接賓語的形容詞:" + JianNum);
    }
    if (ZhiNum != "")
    {
        UnityEngine.Debug.Log("直接賓語的形容詞:" + ZhiNum);
    }
    if (BuNum != "")
    {
        UnityEngine.Debug.Log("賓語補足語的形容詞:" + BuNum);
    }
    */

    //顯示時間:
    /*
    string FindTime_year = "";//要找的時間:年
    string FindTime_month = "";//要找的時間:月
    string FindTime_day = "";//要找的時間:日
    string FindTime_hour = "";//要找的時間:小時
    string FindTime_minute = "";//要找的時間:分鐘
    string FindTime2 = "";//要找的時間(文字形式,例如下午、星期一)
    */
    if (FindTime_year != "")
    {
        UnityEngine.Debug.Log("年:" + FindTime_year);
    }
    if (FindTime_month != "")
    {
        UnityEngine.Debug.Log("月:" + FindTime_month);
    }
    if (FindTime_day != "")
    {
        UnityEngine.Debug.Log("日:" + FindTime_day);
    }
    if (FindTime_hour != "")
    {
        UnityEngine.Debug.Log("時(幾點):" + FindTime_hour);
    }
    if (FindTime_minute != "")
    {
        UnityEngine.Debug.Log("分(幾分):" + FindTime_minute);
    }
    if (FindTime2 != "")
    {
        UnityEngine.Debug.Log("時間:" + FindTime2);
    }

    //tmpText.text = mes;

    //清空變數
    FindSubject = "";
    FindVerb = "";
    FindObject = "";
    FindBuVerb = "";
    FindBuNoun = "";
    FindJianObject = "";
    FindZhiObject = "";
    yutai = "";
    SubjectSuoyouge = "";
    ObjectSuoyouge = "";
    /*
    JianSuoyouge = "";
    ZhiSuoyouge = "";
    BuSuoyouge = "";
    */
}

}

第六章

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//Canvas框顯示輸入框和輸出框所需
using TMPro;//Text Mesh Pro文字控制元件所需
using Mono.Data.Sqlite;//連線sqlite資料庫所需

public class sqlitecon : MonoBehaviour
{
//輸入和輸出
public TMP_InputField inputField;//輸入框物件(把層級皮膚上的輸入框控制元件拖動到此框裡)
string shuru = "";//輸入框內容
//public TMP_Text tmpText;//輸出框物件(把層級皮膚上的輸出框控制元件拖動到此框裡)
//string mes;//輸出框內容
//詞庫
string[] noun = new string[7128];//名詞陣列,名詞數量7128(資料庫增加名詞後,此處也要修改,以免造成溢位)
string[] verb = new string[5886];//動詞陣列,動詞數量5886(資料庫增加動詞後,此處也要修改,以免造成溢位)
string[] adj = new string[1777];//形容詞陣列,形容詞數量1777(資料庫增加形容詞後,此處也要修改,以免造成溢位)
//按標點符號分割句子
string dan = "";//按標點符號分割出的基本單句
string[] danju = new string[100];//單句的陣列儲存
int dan_num = 1;//第幾個單句
//單句裡,謂語動詞分割出的左右句
string LeftPart = "";//謂語動詞的左邊句
string RightPart = "";//謂語動詞的右邊句
//基本單句的語法結構
string FindSubject = "";//主語
string FindVerb = "";//謂語動詞
string FindObject = "";//賓語
string FindBuVerb = "";//賓語補足語的動詞
string FindBuNoun = "";//賓語補足語的名詞
string FindJianObject = "";//間接賓語
string FindZhiObject = "";//直接賓語
//名詞所有格(例如張三的貓,張三就是名詞所有格,“的”字就不寫了)
string SubjectSuoyouge = "";//主語的名詞所有格
string ObjectSuoyouge = "";//賓語的名詞所有格
string JianSuoyouge = "";//間接賓語的名詞所有格
string ZhiSuoyouge = "";//直接賓語的名詞所有格
string BuSuoyouge = "";//賓語補足語的名詞所有格
string TempSuoyouge = "";//臨時存放名詞所有格
//形容詞
string SubjectAdj = "";//主語的形容詞
string ObjectAdj = "";//賓語的形容詞
string JianAdj = "";//間接賓語的形容詞
string ZhiAdj = "";//直接賓語的形容詞
string BuAdj = "";//賓語補足語的形容詞
//數詞
string SubjectNum = "";//主語的數詞
string ObjectNum = "";//賓語的數詞
string JianNum = "";//間接賓語的數詞
string ZhiNum = "";//直接賓語的數詞
string BuNum = "";//賓語補足語的數詞
//語法結構的相關描述
string SentenceType = "";//句型
string yutai = "";//語態:主動語態還是被動語態
string VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
//名詞槽(名詞之間相互覆蓋時用)
string NounBox1 = "";//名詞槽1
string NounBox2 = "";//名詞槽2
string NounBox3 = "";//名詞槽3
string NounBox4 = "";//名詞槽4
//動詞槽(動詞之間相互覆蓋時用)
string VerbBox1 = "";//動詞槽1
string VerbBox2 = "";//動詞槽2
string VerbBox3 = "";//動詞槽3
string VerbBox4 = "";//動詞槽4
//數詞和時間
string FindNum = "";//要找的數詞的數字
string NumDanwei = "";//數詞單位
string FindTime_year = "";//要找的時間:年
string FindTime_month = "";//要找的時間:月
string FindTime_day = "";//要找的時間:日
string FindTime_hour = "";//要找的時間:小時
string FindTime_minute = "";//要找的時間:分鐘
string FindTime2 = "";//要找的時間(文字形式,例如下午、星期一)
string num_type = "";//數字型別:阿拉伯數字(例如1、2、3)還是漢字型數字(例如一、二、三)
//地點
string didian = "";

// Start is called before the first frame update
void Start()
{
    ciku();//填充詞庫
    inputField.onEndEdit.AddListener(OnInputEndEdit);//輸入完成後,對Enter鍵的響應(按Enter鍵傳送)
}

// Update is called once per frame
void Update()
{

}

//填充詞庫(資料庫的詞庫填充到陣列中)
void ciku()
{
    //生成遊戲後,需要把sqlite資料庫複製到生成的遊戲的資料夾裡,那個資料夾自動生成的這個資料庫是0kb,無效的,需要重新複製過去
    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    int i = 0;

    //填充名詞陣列
    //第一步:sql指令
    string sqlQuery = "SELECT word_col FROM noun";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充名詞陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();
    while (dbReader.Read())
    {
        noun[i] = dbReader.GetValue(0).ToString();//GetValue(0)表示結果集的第一列,因為只查詢了一列,所以返回的結果集就一列
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示名詞數量

    //填充動詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM verb";//sql指令
    //第二步:執行指令
    //dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        verb[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示動詞數量

    //填充形容詞陣列
    //第一步:sql指令
    sqlQuery = "SELECT word_col FROM adj";//sql指令
    //第二步:執行指令
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充動詞陣列
    dbReader = dbCommand.ExecuteReader();
    i = 0;
    while (dbReader.Read())
    {
        adj[i] = dbReader.GetValue(0).ToString();
        i++;
    }
    dbReader.Close();
    //UnityEngine.Debug.Log(i);//顯示形容詞數量

    dbConnection.Close();//關閉資料庫連線
}

//輸入完成後,按Enter鍵傳送,便開始執行此函式
void OnInputEndEdit(string value)
{
    shuru = inputField.text;//輸入框的內容
    SplitSay();//按標點符號,分割輸入內容
}

//按標點符號,分割輸入內容,分割成基本單句
void SplitSay()
{
    /*
    輸入的內容可能是一大段內容,需要分割成一個個基本單句,從而逐一處理。
    基本單句就是主語-謂語-賓語,或主語-謂語-間接賓語-直接賓語,或主語-謂語-賓語-賓語補足語,這類語法上的基本單句。
    那就需要按逗號分割句子,按句號分割句子,才能拆分成一個個這樣的基本單句。

    按逗號分割句子:
    string str = "早晨,中午,下午";
    string word = ",";
    string[] shuzu = str.Split(word);//按word指定的分隔符,分割字串,並存入陣列中
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    按逗號和句號分割句子:
    string str = "早晨,中午。下午,傍晚";
    string word = ",";
    string[] shuzu = str.Split(word);//按word指定的分隔符(逗號),分割字串,並存入陣列中
    foreach (string part in shuzu)
    {
        string word2 = "。";
        string[] shuzu2 = part.Split(word2);//按word2指定的分隔符(句號),分割字串,並存入陣列中
        foreach (string part2 in shuzu2)
        {
            UnityEngine.Debug.Log(part2);
        }
    }

    計算標點符號的數量:
    string str = "早晨,中午。下午,傍晚";
    string temp = "";

    int dou = 0;//逗號數量
    int ju = 0;//句號數量
    int str_length = str.Length;//句子長度

    temp = str.Replace(",", "");//把逗號替換為空無,就是去掉逗號
    int str_length_delete_dou = temp.Length;//去掉逗號後,句子的長度
    dou = str_length - str_length_delete_dou;//兩者相減,就是逗號的數量

    temp = str.Replace("。", "");//把句號替換為空無,就是去掉句號
    int str_length_delete_ju = temp.Length;//去掉句號後,句子的長度
    ju = str_length - str_length_delete_ju;//兩者相減,就是句號的數量

    以上註釋掉的內容,只是解釋說明,下面才是執行的程式:
    */

    //計算標點符號的數量
    string temp = "";
    int dou = 0;//逗號數量
    int ju = 0;//句號數量
    int str_length = shuru.Length;//句子長度
    //計算逗號的數量
    temp = shuru.Replace(",", "");//把逗號替換為空無,就是去掉逗號
    int str_length_delete_dou = temp.Length;//去掉逗號後,句子的長度
    dou = str_length - str_length_delete_dou;//兩者相減,就是逗號的數量
    //計算句號的數量
    temp = shuru.Replace("。", "");//把句號替換為空無,就是去掉句號
    int str_length_delete_ju = temp.Length;//去掉句號後,句子的長度
    ju = str_length - str_length_delete_ju;//兩者相減,就是句號的數量

    //按標點符號分割句子
    if (dou > 0 || ju > 0)//逗號大於0或句號大於0,就是輸入的內容有標點符號
    {
        string word = ",";//分割符:中文的逗號
        string[] shuzu = shuru.Split(word);//按word指定的分隔符(逗號),分割字串,並存入陣列中
        foreach (string part in shuzu)//逐個處理
        {
            string word2 = "。";//分割符:中文的句號
            string[] shuzu2 = part.Split(word2);//按word2指定的分隔符(句號),分割字串,並存入陣列中
            foreach (string part2 in shuzu2)//逐個處理
            {
                dan = part2;//基本單句已經分割出來了,在part2裡,並賦值給dan(基本單句)
                danju[dan_num - 1] = part2;//陣列從0開始計算,而danju從1開始計算,所以換算上要減1
                ClearData();//清除上次的變數資料
                //UnityEngine.Debug.Log("單句:" + dan);
                SearchVerb(dan);//找謂語動詞(這是單句處理的第一步)
                dan = "";
                dan_num++;
            }
        }
    }
    else//輸入的內容,沒有標點符號
    {
        if (shuru != "")//有輸入的內容
        {
            dan = shuru;//輸入的內容就是一個基本單句
            danju[0] = shuru;
            SearchVerb(dan);//找謂語動詞
            dan = "";
        }
    }

    //後面分析一句話,記著用變數dan,不要再用變數shuru了,因為變數shuru是整段話(可以是多句話組成),變數dan才是分割出的單句
}

//清除上次迴圈(基本單句處理)的變數資料
void ClearData()
{
    FindSubject = "";//主語
    FindVerb = "";//謂語動詞
    FindObject = "";//賓語
    FindBuVerb = "";//賓語補足語的動詞
    FindBuNoun = "";//賓語補足語的名詞
    FindJianObject = "";//間接賓語
    FindZhiObject = "";//直接賓語
    SubjectSuoyouge = "";//主語的名詞所有格
    ObjectSuoyouge = "";//賓語的名詞所有格
    TempSuoyouge = "";//臨時存放名詞所有格
    SubjectAdj = "";//主語的形容詞
    ObjectAdj = "";//賓語的形容詞
    SubjectNum = "";//主語的數詞
    ObjectNum = "";//賓語的數詞
    SentenceType = "";//句型
    yutai = "";//語態:主動語態還是被動語態
    VerbRate = "";//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
    NounBox1 = "";//名詞槽1
    NounBox2 = "";//名詞槽2
    NounBox3 = "";//名詞槽3
    NounBox4 = "";//名詞槽4
    VerbBox1 = "";//動詞槽1
    VerbBox2 = "";//動詞槽2
    VerbBox3 = "";//動詞槽3
    VerbBox4 = "";//動詞槽4
    FindNum = "";
    NumDanwei = "";
    num_type = "";
}

//找謂語動詞
void SearchVerb(string str)
{
    string jieguo = "不包含";//預設值是不包含動詞
    int m = verb.Length;//動詞陣列的長度,也就是有多少個動詞

    LeftPart = "";
    RightPart = "";
    VerbBox1 = "";
    VerbBox2 = "";
    VerbBox3 = "";
    VerbBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和動詞的包含關係
        就是用句子和動詞陣列的動詞,一一比對,來判斷是否包含動詞
        n的值從0逐漸增長到動詞陣列的動詞數量值,這樣陣列也就經歷了所有動詞
        */
        if (str.Contains(verb[n]))//包含動詞
        {
            if (VerbJudge(str, verb[n]) == true)//是動詞,不是名詞
            {
                jieguo = "包含";
                FindVerb = verb[n];//找到了動詞
                VerbCover(str, verb[n]);//把動詞放入動詞槽裡,看看有幾個動詞
                VerbOrder();//動詞排序
                VerbJoin();//動詞結合
            }
        }
    }

    if (jieguo == "包含")//包含動詞
    {
        VerbRateJudge();//動詞發生機率:肯定、偏向肯定、不確定、偏向否定、否定
        SentenceType = SentenceJudge();//判斷句型(僅從動詞情況來判斷句型,還不是完全清楚的判斷,之後還需進一步判斷)
        SplitSentence();//以謂語動詞為分割符,來分割句子
    }
}

//以謂語動詞為分割符,來分割句子
void SplitSentence()
{
    /*
    對於主謂賓句型,先找出動詞,然後以動詞為分割符號,分割句子。動詞左邊分割出的句子的名詞就是主語,動詞右邊分割出的句子的名詞就是賓語
    先舉個例子簡單說明一下字串分割的基本原理:
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string word = "嘲笑";//指定詞
    string res = "";//結果
    int chang = 0;//全句長度
    int index = 0;//指定詞語的起始位置
    int LastIndex = 0;//指定詞語最後一個字元在全句中的位置
    int jie = 0;//臨時變數

    //計算全句長度
    chang = str.Length;//顯示字元個數,從1開始計算
    //計算指定字元在全句中的位置
    index = str.IndexOf(word) + 1;//預設從0計算,例如第2個字元,顯示為1,而不是2。為了調整為1開始計算,所以加1
    //計算指定詞語最後一個字元在全句中的位置
    LastIndex = str.IndexOf(word) + word.Length;

    //擷取第3個字元右邊的1個字元
    Substring(開始位置, 向右擷取長度),從1開始計算,不是0
    res = str.Substring(3,1); //從第3個字元開始,向右擷取1個字元

    //擷取指定字元右邊的全部字元
    jie = chang - LastIndex;//擷取長度 = 全句長度 - 指定詞語最後一個字元的位置長度
    res = str.Substring(LastIndex, jie);
    res = str.Substring(str.IndexOf(word) + word.Length, str.Length - (str.IndexOf(word) + word.Length));//展開形式

    //擷取指定字元左邊的全部字元
    res = str.Substring(0, index);//從句子開始的0位置,擷取長度是指定字元的位置長度
    res = str.Substring(0, str.IndexOf(word));//變化形式

    //擷取兩個指定字元之間的全部字元
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式

    //陣列形式擷取字元
    //前面定義了:str = "白色的貓吃黑色的鼠"; word = "吃";
    string[] shuzu = str.Split(word);//按指定分割符分割字串,並存入陣列中
    UnityEngine.Debug.Log(shuzu[0]);//顯示:白色的貓
    UnityEngine.Debug.Log(shuzu[1]);//顯示:黑色的鼠
    //或逐一顯示陣列全部
    foreach (string part in shuzu)
    {
        UnityEngine.Debug.Log(part);
    }

    以上註釋掉的內容,只是解釋原理,下面是執行的程式:
    */

    //也可能找到一個動詞(主謂賓句型),也可能找到兩個動詞(賓語補足語句型)
    if (VerbBox1 != "" && VerbBox2 == "")//只找到1個動詞,那就是謂語動詞
    {
        FindVerb = VerbBox1;
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//找到2個動詞
    {
        FindVerb = VerbBox1;//位次在前面的動詞是謂語動詞
        FindBuVerb = VerbBox2;//位次在後面的動詞是賓語補足語動詞
    }

    //謂語動詞左邊句(LeftPart)和謂語動詞右邊句(RightPart)是一個重要的轉折,為以後的句子處理奠定了基礎
    LeftPart = dan.Substring(0, dan.IndexOf(FindVerb));
    RightPart = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.Length - (dan.IndexOf(FindVerb) + FindVerb.Length));

    /*
    例如句子(dan)是白色的貓吃黑色的鼠
    find_word:吃
    LeftPart:白色的貓
    RightPart:黑色的鼠
    UnityEngine.Debug.Log(find_verb);//謂語動詞
    UnityEngine.Debug.Log(LeftPart);//謂語動詞的左邊句
    UnityEngine.Debug.Log(RightPart);//謂語動詞的右邊句
    */

    /*
    省略主語有兩種情況:一種是主動語態省略主語,例如“跳過去”,全句指“你跳過去”。另一種是被動語態省略主語,例如“張三被打了”,沒說誰打了張三,這裡張三是賓語。如果說“李四打了張三”,李四就是主語。
    被動語態的標誌是“被”字,如果沒有“被”字,而且省略了主語,就是主動語態省略主語的情況,那麼這種情況下,主語應該填什麼呢?例如“過來”,一般指“你過來”,但“走吧”一般指“我們走吧”。所以程式要根據具體的動詞來判斷省略的主語應該填什麼。但是動詞太多,每個動詞都要設定省略的主語判斷,太麻煩。所以省略主語,按最通常情況,就預設填“你”字,作為主語。如果主語是“我們”而不是“你”字,就不該省略主語。
    被動語態應該還原為主動語態去理解,但被動語態往往沒有主語,那麼預設主語應該填什麼呢?畢竟不知道主語,那就填“事物”這個詞作為主語。
    程式分析句子時,被動語態的主語位置的詞,是賓語。例如“李四被打了”,李四在謂語動詞左邊句,程式會把李四當成主語,但在被動語態句裡,李四不是主語,所以有“被”字的時候,主語要挪動到賓語位置,然後在主語位置補充“事物”這個詞,作為主語。
    但是有些時候,被動語態的主語是說明了的,例如“李四被張三打了”就還原為主動語態“張三打了李四”,張三做主語,而不是填“事物”做主語。
    簡而言之,被動語態裡,主語放到了賓語位置,賓語放到了主語位置,所以變為主動語態時,要把賓語挪回主語位置,主語挪回賓語位置。
    如果被動語態有主語,例如“李四被張三打了”,那麼主語(張三)位於“被”字與謂語動詞之間。
    那麼謂語動詞左邊句中,又分為“被”字左邊句和“被”字右邊句,被字左邊句裡的名詞是賓語,被字右邊句裡的名詞是主語。
    */
    yutai = "主動";//預設主動語態
    if (SentenceType == "主謂賓" && dan.Contains("被"))//語句中包含“被”字
    {
        if (dan.Contains("被子") == false && dan.Contains("被褥") == false)//語句中包含“被”字,但不是“被子”這個名詞,才能指被動語態的“被”字
        {
            yutai = "被動";//被動語態
        }
        else
        {
            yutai = "主動";//主動語態
        }
    }
    else//語句中沒有包含“被”字
    {
        yutai = "主動";//主動語態
    }

    //對謂語動詞左邊句(LeftPart)的處理
    if (LeftPart != "")//謂語動詞左邊句有內容
    {
        if (yutai == "主動")//主動語態
        {
            //找名詞(主語)和名詞所有格
            FindSubject = SearchNoun(LeftPart);//在謂語動詞左邊句找名詞(主語)
            if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
            {
                SubjectSuoyouge = TempSuoyouge;//是主語的名詞所有格
                TempSuoyouge = "";//置空
            }
            //找形容詞(主語的形容詞)
            SubjectAdj = SearchAdj(LeftPart);
            //找數詞
            FindNum = "";
            NumDanwei = "";
            num_type = "";
            SearchNum(LeftPart);
            SubjectNum = FindNum + NumDanwei;
            //找時間
            SearchTime1(LeftPart);//找時間:文字形式,例如今天、星期一
            SearchTime2(LeftPart);//找時間:年月日時分
        }
        else if (yutai == "被動")//被動語態
        {
            string bei = "被";
            string BeiLeft = "";
            string BeiRight = "";

            //被字左邊句
            BeiLeft = LeftPart.Substring(0, LeftPart.IndexOf(bei));
            if (BeiLeft != "")
            {
                FindObject = SearchNoun(BeiLeft);//被字左邊句的名詞是賓語
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
                    TempSuoyouge = "";//置空
                }
                //找形容詞(賓語的形容詞)
                ObjectAdj = SearchAdj(BeiLeft);
                //找數詞
                FindNum = "";
                NumDanwei = "";
                num_type = "";
                SearchNum(BeiLeft);
                ObjectNum = FindNum + NumDanwei;
                //找時間
                SearchTime1(BeiLeft);//找時間:文字形式,例如今天、星期一
                SearchTime2(BeiLeft);//找時間:年月日時分
            }

            //被字右邊句
            BeiRight = LeftPart.Substring(LeftPart.IndexOf(bei) + bei.Length, LeftPart.Length - (LeftPart.IndexOf(bei) + bei.Length));
            
            if (BeiRight != "")
            {
                FindSubject = SearchNoun(BeiRight);//被字右邊句的名詞是主語
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    SubjectSuoyouge = TempSuoyouge;//是主語的名詞所有格
                    TempSuoyouge = "";//置空
                }
                //找形容詞(主語的形容詞)
                SubjectAdj = SearchAdj(BeiRight);
                //找數詞
                FindNum = "";
                NumDanwei = "";
                num_type = "";
                SearchNum(BeiRight);
                SubjectNum = FindNum + NumDanwei;
            }
            //如果沒有主語,就填補“事物”這個詞作為主語,畢竟被動語態經常沒有主語
            if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
            {
                FindSubject = "事物";
            }
        }
    }

    //如果省略主語,則填補省略的主語
    if (yutai == "主動")
    {
        if (FindSubject == "" || FindSubject == null)//主語為空或主語不存在
        {
            FindSubject = "你";//預設填補“你”字做主語
        }
    }

    //對謂語動詞右邊句(RightPart)的處理
    if (SentenceType == "雙賓語")//雙賓語句型
    {
        FindObject = SearchNoun(RightPart);//找名詞
        if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
        {
            ZhiSuoyouge = TempSuoyouge;//是直接賓語的名詞所有格(暫且這樣設定)
            TempSuoyouge = "";//置空
        }

        //謂語動詞右邊句裡,沒有第二個賓語名詞,那就不是雙賓語
        //例如雖然有雙賓語句的標誌動詞“教”字,但他教我數學,是雙賓語句,而他教書,是主謂賓句型
        if (NounBox2 == "")
        {
            SentenceType = "主謂賓";
            ZhiSuoyouge = "";//既然不作為雙賓語句型了,原來的直接賓語所有格也就要清空了
        }
        else
        {
            //直接賓語的定語(形容詞、數詞、名詞所有格),在間接賓語和直接賓語之間
            //例如張三給李四紅色的蘋果,李四是間接賓語,蘋果是直接賓語,紅色的是形容詞
            if (FindJianObject != "" && FindZhiObject != "")//間接賓語和直接賓語不為空
            {
                string BewteenPart = "";
                BewteenPart = RightPart.Substring(RightPart.IndexOf(FindJianObject) + FindJianObject.Length, RightPart.IndexOf(FindZhiObject) - (RightPart.IndexOf(FindJianObject) + FindJianObject.Length));
                if (BewteenPart != "")
                {
                    //找形容詞
                    ZhiAdj = SearchAdj(BewteenPart);
                    //找數詞
                    FindNum = "";
                    NumDanwei = "";
                    num_type = "";
                    SearchNum(BewteenPart);
                    ZhiNum = FindNum + NumDanwei;
                }
            }
            //間接賓語的定語在謂語動詞和間接賓語之間,對於謂語動詞右邊句,也就是句子開始到間接賓語之間
            //例如張三給美麗的李四蘋果,李四是間接賓語,美麗的是形容詞
            if (FindJianObject != "")//間接賓語不為空
            {
                string PartLeft = "";
                PartLeft = RightPart.Substring(0, RightPart.IndexOf(FindJianObject));
                if (PartLeft != "")
                {
                    //找形容詞
                    JianAdj = SearchAdj(PartLeft);
                    //找數詞
                    FindNum = "";
                    NumDanwei = "";
                    num_type = "";
                    SearchNum(PartLeft);
                    JianNum = FindNum + NumDanwei;
                }
            }

            ShowResult();//顯示最終輸出結果
        }
    }

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        if (RightPart != "")
        {
            if (yutai == "主動")
            {
                //找名詞和名詞所有格
                FindObject = SearchNoun(RightPart);//在謂語動詞右邊句找名詞(賓語)
                if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
                {
                    ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
                    TempSuoyouge = "";//置空
                }

                //找形容詞(賓語的形容詞)
                ObjectAdj = SearchAdj(RightPart);
                //找數詞
                FindNum = "";
                NumDanwei = "";
                num_type = "";
                SearchNum(RightPart);
                ObjectNum = FindNum + NumDanwei;
            }
        }

        ShowResult();//顯示最終輸出結果
    }

    if (SentenceType == "賓語補足語")//賓語補足語句型
    {
        //謂語動詞到賓語補足語動詞之間的部分裡的名詞,是賓語名詞
        string temp = "";
        //擷取謂語動詞FindVerb和賓語補足語動詞FindBuVerb之間的部分
        temp = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.IndexOf(FindBuVerb) - (dan.IndexOf(FindVerb) + FindVerb.Length));
        FindObject = SearchNoun(temp);//找名詞
        if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
        {
            ObjectSuoyouge = TempSuoyouge;//是賓語的名詞所有格
            TempSuoyouge = "";//置空
        }
        //賓語補足語右邊句的名詞,是賓語補足語名詞,而不是賓語名詞
        int WordLastChar = dan.IndexOf(FindBuVerb) + FindBuVerb.Length;//賓語補足語動詞最後一個字元的位置
        if (WordLastChar < dan.Length)//賓語補足語動詞最後一個字元的位置沒有到全句末尾,就是說賓語補足語動詞後面還有內容,那就是賓語補足語名詞
        {
            //擷取賓語補足語動詞右邊的內容
            string BuRight = dan.Substring(dan.IndexOf(FindBuVerb) + FindBuVerb.Length, dan.Length - (dan.IndexOf(FindBuVerb) + FindBuVerb.Length));
            FindBuNoun = SearchNoun(BuRight);//找名詞(上次寫錯了,寫成temp了,那就把賓語也當要找的名詞了)
            if (TempSuoyouge != "")//找名詞時,順便還找到了名詞所有格
            {
                BuSuoyouge = TempSuoyouge;//是賓語補足語的名詞所有格
                TempSuoyouge = "";//置空
            }
            //賓語補足語名詞的定語(形容詞、數詞、名詞所有格)在賓語補足語動詞的右邊(BuRight)
            //例如張三讓李四打掃藍色的房間,打掃是賓語補足語的動詞,房間是賓語補足語的名詞,藍色的是形容詞
            //找形容詞
            BuAdj = SearchAdj(BuRight);
            //找數詞
            FindNum = "";
            NumDanwei = "";
            num_type = "";
            SearchNum(BuRight);
            BuNum = FindNum + NumDanwei;
        }

        ShowResult();//顯示最終輸出結果
    }

    /*
    靠句子包含的詞直接與詞庫的詞對比,來找主語(名詞)、謂語(動詞)、賓語(名詞),會有問題:

    第一個問題:熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    所以建立一個函式:WordCover(覆蓋)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。

    第二個問題:熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    對於第二個問題的解決方法:
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    所以建立一個de函式。

    第三個問題:“學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。“壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。
    所以建立一個VerbJudge函式。
    */
}

//找名詞(也包括找名詞所有格)
string SearchNoun(string PartSentence)
{
    string jieguo = "不包含";//預設值是不包含
    int m = noun.Length;//名詞陣列的長度,也就是有多少個名詞

    //for迴圈前,先把詞語槽清空,因為for迴圈時,呼叫的函式WordCover要用詞語槽,來完成詞語的覆蓋和吸收
    NounBox1 = "";
    NounBox2 = "";
    NounBox3 = "";
    NounBox4 = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和名詞的包含關係
        就是用句子和名詞陣列的名詞,一一比對,來判斷是否包含名詞
        n的值從0逐漸增長到名詞陣列的名詞數量值,這樣陣列也就經歷了所有名詞
        */
        if (PartSentence.Contains(noun[n]))//句子包含名詞
        {
            jieguo = "包含";
            //找到的名詞不是名詞所有格,也不是地點,才是主語或賓語的名詞
            if (de(PartSentence, noun[n]) == false)//找到的名詞右邊的第一個字元不是“的”字,才算是名詞,否則是名詞所有格
            {
                if (difang(PartSentence, noun[n]) == false)//找到的名詞左邊的第一個字元,不是地點動詞
                {
                    NounCover(noun[n]);
                }
                else//名詞左邊第一個字是“在”或“到”或“去”或“來”,那麼這個名詞就是地點,而不是作為主語名詞
                {
                    didian = noun[n];//找到的地點
                }
            }
            else//名詞右邊的第一個字是“的”字,就意味著是名詞所有格
            {
                TempSuoyouge = noun[n];//找到的名詞所有格
            }
        }
    }

    if (jieguo == "包含")//找到了名詞
    {
        NounOrder();//名詞排序
        //名詞要先排序,才能合併名詞,否則“足球”和“學校”的順序如果變成“學校”和“足球”,那就合併成“學校足球”這個詞了,而不是“足球學校”

        //如果雙賓語句型進行名詞合併,就可能會把間接賓語名詞和直接賓語名詞合併到一起,成為一個名詞,就不對了
        if (SentenceType != "雙賓語")//不是雙賓語句型
        {
            NounJoin();//名詞合併,例如把“足球”和“學校”合併成“足球學校”這一個名詞
        }
        else if (SentenceType == "雙賓語")//是雙賓語句型
        {
            //但是如果現在處理的是雙賓語結構的謂語動詞左邊句,也就是處理主語,還是可以名詞合併的
            if (dan.IndexOf(NounBox1) < dan.IndexOf(FindVerb))
            {
                NounJoin();//名詞合併
            }
        }

        return NounBox1;
    }
    else
    {
        return "";
    }
}

//名詞之間的覆蓋
void NounCover(string FindWord)
{
    /*
    熊貓吃竹子,這句話裡你感覺有感覺有兩個名詞:熊貓、竹子,但是電腦會找出四個名詞:熊貓、熊、貓、竹子。
    對於第一個問題的解決方法:
    新找到的長詞(熊貓)覆蓋已找到的短詞(熊、貓)。
    已找到的長詞(熊貓)吸收新找到的短詞(熊、貓)。
    詞語槽(NounBox)存放這些找到詞,以實現覆蓋和吸收。
    做了4個詞語槽(NounBox),為了以後適應複雜的句子,但簡單的主謂賓句型,一個詞語槽就夠了。
    */
    if (NounBox1 == "" && FindWord != "")//詞語槽還是空的,說明這是找到的第一個詞
    {
        NounBox1 = FindWord;//找到的第1個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽2了
    }
    else if (NounBox1 != "" && FindWord != "")//詞語槽1已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox1))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽1(NounBox1)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽2了
        }
        else if (NounBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽1(NounBox1)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,不要這個詞了,免得填到詞語槽2了
        }
    }

    if (NounBox2 == "" && FindWord != "")//詞語槽2是空的,FindWord經過詞語槽1,沒有覆蓋或吸收,說明FindWord和詞語槽1的詞無關,例如FindWord是竹子
    {
        NounBox2 = FindWord;//找到的第2個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽3了
    }
    else if (NounBox2 != "" && FindWord != "")//詞語槽2已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox2))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽2(NounBox2)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (NounBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽2(NounBox2)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (NounBox3 == "" && FindWord != "")//詞語槽3是空的,FindWord經過詞語槽2,沒有覆蓋或吸收,說明FindWord和詞語槽2的詞無關,例如FindWord是竹子
    {
        NounBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (NounBox3 != "" && FindWord != "")//詞語槽3已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox3))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽3(NounBox3)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (NounBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽3(NounBox3)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (NounBox4 == "" && FindWord != "")//詞語槽4是空的,FindWord經過詞語槽3,沒有覆蓋或吸收,說明FindWord和詞語槽3的詞無關,例如FindWord是竹子
    {
        NounBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (NounBox4 != "" && FindWord != "")//詞語槽4已經有找到的詞了,例如已經放入熊或貓或熊貓,而現在又找到詞熊或貓或熊貓
    {
        if (FindWord.Contains(NounBox4))//覆蓋:例如找到的詞(FindWord)是熊貓,詞語槽4(NounBox4)的詞是熊,“熊貓”包含(Contain)“熊”字
        {
            NounBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (NounBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是熊,詞語槽4(NounBox4)的詞是熊貓,“熊”字屬於“熊貓”
        {
            FindWord = "";//置空
        }
    }

    /*
    “足球”這個詞,會找到三個名詞:足、球、足球。
    先找到第一個詞:足,放入NounBox1。
    再找到第二個詞:球,放入NounBox2。
    再找到第三個詞:足球,會覆蓋NounBox1的“足”字,但卻無法覆蓋NounBox2的球字。
    因此程式做一些改進。

    但如果幸運的:
    先找到第一個詞:足球,放入NounBox1。
    再找到第二個詞:足,被NounBox1“足球”這個詞吸收,不會進入到NounBox2。
    再找到第三個詞:球,被NounBox1“足球”這個詞吸收,也不會進入到NounBox2。
    那麼就不用執行下面這段程式了。
    先找到那個詞是不確定的,詞庫詞語可能按筆畫排序,也可能按首字母排序,就不知道先找到那個詞了。

    如果輸入的是“皮球”這個詞,而詞庫裡沒有“皮球”這個詞,但有“皮”字和“球”字這兩個詞。
    那麼,NounBox1是“皮”字,NounBox2是“球”字,或NounBox1是“球”字,NounBox2是“皮”字,沒有覆蓋和吸收。
    */
    if (NounBox1.Contains(NounBox2))//NounBox1包含了NounBox2,例如“足球”包含“球”字
    {
        NounBox2 = "";
        if (NounBox3 != "")
        {
            NounBox2 = NounBox3;
            NounBox3 = "";
        }
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox2.Contains(NounBox3))//NounBox2包含了NounBox3
    {
        NounBox3 = "";
        if (NounBox4 != "")
        {
            NounBox3 = NounBox4;
            NounBox4 = "";
        }
    }
    if (NounBox3.Contains(NounBox4))//NounBox3包含了NounBox4
    {
        NounBox4 = "";
    }
}

//動詞之間的覆蓋
void VerbCover(string str,string FindWord)
{
    if (VerbBox1 == "" && FindWord != "")//動詞槽還是空的,說明這是找到的第一個詞
    {
        VerbBox1 = FindWord;//找到的第1個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽2了
    }
    else if (VerbBox1 != "" && FindWord != "")//動詞槽1已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox1))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽1(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox1 = FindWord;//詞語槽1的詞:長詞覆蓋短詞,例如“敲打”覆蓋“打”
            FindWord = "";//置空,免得填到動詞槽2了
        }
        else if (VerbBox1.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽1(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,不要這個詞了,免得填到動詞槽2了
        }
    }

    if (VerbBox2 == "" && FindWord != "")//動詞槽2是空的,FindWord經過動詞槽1,沒有覆蓋或吸收,說明FindWord和動詞槽1的詞無關,例如FindWord是喜歡
    {
        VerbBox2 = FindWord;//找到的第2個詞,放入動詞槽
        FindWord = "";//置空,免得填到動詞槽3了
    }
    else if (VerbBox2 != "" && FindWord != "")//動詞槽2已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox2))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽2(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox2 = FindWord;//詞語槽2的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽3了
        }
        else if (VerbBox2.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽2(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽3了
        }
    }

    if (VerbBox3 == "" && FindWord != "")//動詞槽3是空的,FindWord經過動詞槽1和2,沒有覆蓋或吸收,說明FindWord和動詞槽1、2的詞無關,例如FindWord是喜歡
    {
        VerbBox3 = FindWord;//找到的第3個詞,放入詞語槽
        FindWord = "";//置空,免得填到詞語槽4了
    }
    else if (VerbBox3 != "" && FindWord != "")//動詞槽3已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox3))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽3(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox3 = FindWord;//詞語槽3的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空,免得填到詞語槽4了
        }
        else if (VerbBox3.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽3(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空,免得填到詞語槽4了
        }
    }

    if (VerbBox4 == "" && FindWord != "")//動詞槽4是空的,FindWord經過動詞槽1、2、3,沒有覆蓋或吸收,說明FindWord和動詞槽1、2、3的詞無關,例如FindWord是喜歡
    {
        VerbBox4 = FindWord;//找到的第4個詞,放入詞語槽
        FindWord = "";//置空
    }
    else if (VerbBox4 != "" && FindWord != "")//動詞槽4已經有找到的詞了,例如已經放入敲打或敲或打,而現在又找到詞敲打或敲或打
    {
        if (FindWord.Contains(VerbBox4))//覆蓋:例如找到的詞(FindWord)是敲打,動詞槽4(VerbBox1)的詞是打,“敲打”包含(Contain)“打”字
        {
            VerbBox4 = FindWord;//詞語槽4的詞:長詞覆蓋短詞,例如“熊貓”覆蓋“熊”
            FindWord = "";//置空
        }
        else if (VerbBox4.Contains(FindWord))//吸收:例如找到的詞(FindWord)是打,動詞槽4(VerbBox1)的詞是敲打,“打”字屬於“敲打”
        {
            FindWord = "";//置空
        }
    }

    /*
    “敲打”這個詞,會找到三個動詞:敲、打、敲打
    先找到第一個詞:敲,放入VerbBox1
    再找到第二個詞:打,放入VerbBox2
    再找到第三個詞:敲打,會覆蓋VerbBox1的“敲”字,但卻無法覆蓋VerbBox2的“打”字
    因此程式做一些改進。 
    */
    if (VerbBox1.Contains(VerbBox2))//VerbBox1包含了VerbBox2
    {
        VerbBox2 = "";
        if (VerbBox3 != "")
        {
            VerbBox2 = VerbBox3;
            VerbBox3 = "";
        }
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox2.Contains(VerbBox3))//VerbBox2包含了VerbBox3
    {
        VerbBox3 = "";
        if (VerbBox4 != "")
        {
            VerbBox3 = VerbBox4;
            VerbBox4 = "";
        }
    }
    if (VerbBox3.Contains(VerbBox4))//VerbBox3包含了VerbBox4
    {
        VerbBox4 = "";
    }
}

//名詞後面是否包含“的”字
bool de(string str,string word)
{
    /*
    熊貓喜歡森林的竹子,這句話動詞右邊句有兩個名詞,竹子是賓語,而森林不是賓語,因為森林後邊有個“的”字,是名詞所有格。
    找到的名詞右邊的第一個字元,看它是不是“的”字,如果是“的”字,那麼這個名詞就不是賓語,找主語也是同理。
    
    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }
    UnityEngine.Debug.Log(res);//顯示:的
    以上註釋掉的內容只是解釋原理,下面是執行程式:
    */

    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果
    WordLastChar = str.IndexOf(word) + word.Length;
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
    }

    if (res == "的")
    {
        return true;
    }
    else
    {
        return false;
    }
}

//判斷一個字是動詞還是名詞
bool VerbJudge(string str,string word)
{
    /*
    “學”字是動詞,但是在“學生”這個詞裡,“學”字就變成名詞了,還當動詞理解,就會錯。
    對於第三個問題的解決方法:
    建立詞性辨析表:verb_judge
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   學     |   r1    |      生      |
    +----------+---------+--------------+
    |   壓     |   l1    |      氣      |
    +----------+---------+--------------+
    word_col:判斷這個字是動詞還是名詞,也就是辨析字。
    type_col:r1表示right1,就是指content_col的字是word_col的那個字的右邊那1個字,也就是“學生”的“生”字。
    l1表示left1,就是指content_col的字是word_col的那個字的左邊那1個字,也就是“氣壓”的“氣”字。
    “壓”是本身是動詞,但左邊那個字是“氣”字時,“壓”字就變為名詞了,也就是名詞“氣壓”的“壓”。
    l是字母L的小寫,不是數字1。l1是兩個不同的字元。

    不容易理解的一處:
    +----------+----------+-------------+
    | word_col | type_col | content_col |
    +----------+---------+--------------+
    |   吹     |   l1    |      電      |
    +----------+---------+--------------+
    “吹”字本身做動詞,但在“電吹風”這個詞裡做名詞,但我不用把“電吹風”這個三個字都判斷,我只要判斷“電吹”兩個字就可以了。

    遇到單字動詞的時候,先看這個字是否在詞性辨析表裡,
    如果在,type_col要求是r1(right1,就是要辨析的字的右邊1個字元),那就看句子中要辨析的字的右邊1個字元是不是符合詞性表中的字,
    如果符合,要辨析的字就是名詞,而不是動詞了。
    例如學生看書,這句話先找到了動詞“學”,在詞性辨析表裡,“學”字的type_col是r1,content_col是“生”字,
    那就在句子中,看“學”字右邊的1個字元是不是“生”字,如果是,“學”字就不做動詞,而做名詞了。

    一個要辨析的字,type_col有四種可能:r1、r2、l1、l2,也就是右邊1個字,右邊2個字,左邊1個字,左邊2個字,那就要會四個方法:
    符合r1:找辨析字右邊1個字元:res = str.Substring(str.IndexOf(word) + word.Length, 1);
    符合r2:找辨析字右邊2個字元:res = str.Substring(str.IndexOf(word) + word.Length, 2);
    符合l1:找辨析字左邊1個字元:res = str.Substring(str.IndexOf(word) - 1, 1);
    符合l2:找辨析字左邊2個字元:res = str.Substring(str.IndexOf(word) - 2, 1);

    擷取指定字元右邊1個字元的基本原理:
    string str = "白色的貓吃黑色的鼠";//全句
    string word = "黑色";//指定詞
    int index = 0;//指定詞的位置(索引)
    int WordLength = 0;//詞語長度
    int WordLastChar = 0;//詞語最後一個字元的位置
    string res = "";//結果

    WordLength = word.Length;
    index = str.IndexOf(word);

    //指定詞語右邊1個字元
    WordLastChar = index + WordLength;
    WordLastChar = str.IndexOf(word) + word.Length;//變化形式
    if (WordLastChar < str.Length)
    {
        res = str.Substring(WordLastChar, 1);
        res = str.Substring(str.IndexOf(word) + word.Length, 1);//變化形式

    }
    UnityEngine.Debug.Log(res);//顯示:的

    //指定詞語左邊1個字元
    res = str.Substring(index - 1, 1);
    res = str.Substring(str.IndexOf(word) - 1, 1);//變化形式
    UnityEngine.Debug.Log(res);//顯示:吃
    以上註釋掉的內容,只是解釋原理,下面是執行程式:
    */

    string[] TypeCol = new string[100];//把詞性辨析表的辨析字對應的type_col值填充此陣列
    string[] ContentCol = new string[100];//把詞性辨析表的辨析字對應的content_col值填充此陣列
    string res = "";//擷取的字元
    bool shima = true;//預設判斷是動詞

    //連線資料庫
    string connectionString = @"Data Source=garden.db;Version=3;";
    SqliteConnection dbConnection;
    dbConnection = new SqliteConnection(connectionString);
    dbConnection.Open();

    //填充名詞陣列
    //第一步:sql指令
    //字元型變數要有引號,數字型變數不需要引號
    //word是變數,動態的,不能直接放到sql語句裡面
    string sqlQuery = "select type_col,content_col from verb_judge where word_col = '" + word + "'";
    //第二步:執行指令
    SqliteCommand dbCommand;
    dbCommand = dbConnection.CreateCommand();
    dbCommand.CommandText = sqlQuery;
    dbCommand.ExecuteNonQuery();
    //第三步:填充詞性辨析陣列
    SqliteDataReader dbReader;
    dbReader = dbCommand.ExecuteReader();

    int i = 0;
    while (dbReader.Read())
    {
        //查詢了2列(type_col和content_col),所以返回的結果集有2列,分別用GetValue(0)和GetValue(1)
        TypeCol[i] = dbReader.GetValue(0).ToString();//返回的結果集的第1列
        ContentCol[i] = dbReader.GetValue(1).ToString();//返回的結果集的第2列
        i++;//雖然定義陣列長度為10,但i不一定填滿了10
    }
    dbReader.Close();
    dbConnection.Close();
    
    if (i > 0)//在詞性辨析表裡找到內容了,否則i還是預設的0
    {
        for (int n = 0; n < i; n++)//遍歷詞性辨析表找到的各種結果
        {
            if (TypeCol[n] == "r1")//right1:右邊1個字元
            {
                if (str.IndexOf(word) + word.Length + 1 <= str.Length)//要往右判斷1個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 1);//擷取動詞右邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "r2")//right2:右邊2個字元
            {
                if (str.IndexOf(word) + word.Length + 2 <= str.Length)//要往右判斷2個字元,但不能超出陣列界限
                {
                    res = str.Substring(str.IndexOf(word) + word.Length, 2);//擷取動詞右邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
            else if (TypeCol[n] == "l1")//left1:左邊1個字元
            {
                if (str.IndexOf(word) - 1 >= 0)//要往左判斷1個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 1, 1);//擷取動詞左邊1個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }

                }
            }
            else if (TypeCol[n] == "l2")//left2:左邊2個字元
            {
                if (str.IndexOf(word) - 2 >= 0)//要往左判斷2個字元,但不能低於陣列界限0
                {
                    res = str.Substring(str.IndexOf(word) - 2, 2);//擷取動詞左邊2個字元
                    if (res == ContentCol[n])//擷取的字元符合詞性辨析表對應的字元
                    {
                        shima = false;//不是動詞
                    }
                }
            }
        }
    }
    i = 0;
    return shima;
}

//判斷句型
string SentenceJudge()
{
    /*
    基本單句有六種句型:
    只有性質狀態(表語):真漂亮、對啊、太好了。句子裡沒有謂語動詞,其餘五種句型裡,都有謂語動詞。
    主語(動作執行者)-謂語(動作):張三摔倒。
    主語(動作執行者)-謂語(動作)-賓語(動作物件):貓吃鼠。
    主語-謂語(是)-表語(表明主語的身份和性質狀態):張三是老師,太陽是美麗的。
    雙賓語句型:主語(傳輸的人)-謂語(傳輸動作)-間接賓語(傳輸物件)-直接賓語(傳輸的事物):張三給李四蘋果,張三教李四數學。
    賓語補足語句型:主語-謂語(例如把、使、讓)-賓語-賓語補足語(做什麼):張三讓李四跳舞,張三把房間弄髒了。
    前面只說了主謂賓句型,還要處理其它句型。

    雙賓語句型:
    雙賓語句型的謂語動詞後面有兩個名詞,例如張三給李四蘋果,李四是間接賓語(名詞),蘋果是直接賓語(名詞)。
    但是有兩個名詞的就是雙賓語句型嗎?不是的。例如張三喜歡足球學校。謂語動詞後面有兩個名詞:足球、學校,但顯然足球學校是一個整體名詞,也就是主謂賓句型,而不是雙賓語句型。因此判斷雙賓語句型,還要看謂語動詞是不是適合雙賓語句型的。
    雙賓語句型的謂語動詞主要是傳輸事物的動詞:給、送給、教。
    那麼謂語動詞是雙賓語句型的動詞(例如給、教),且謂語動詞後面有兩個名詞(體現為謂語動詞右邊的語句處理時,名詞槽NounBox有兩個名詞,NounBox1和NounBox2都有值),就可以判斷為雙賓語句型。
    還有,像“足球學校”這樣兩個名詞連在一起,就要合併成一個名詞,作為主語或賓語。
    僅從雙賓語句型的標誌動詞“教”判斷雙賓語句型,不一定準確,例如“他教我數學”是雙賓語句型,但“他教書”就不是雙賓語句型,所以還要根據賓語名詞的數量,來判斷到底是不是雙賓語句型,如果動詞右邊只有一個名詞,例如“他教書”的“書”,句子就不是雙賓語句型。所以透過謂語動詞判斷一個句子是雙賓語句型後,根據找到的名詞數量,例如只有一個賓語名詞,那麼就要把雙賓語句型,修正回主謂賓句型。
    名詞次序:間接賓語在直接賓語之前,所以找到兩個名詞,次序在前面的那個名詞,是間接賓語,次序在後面的那個名詞是直接賓語。

    賓語補足語句型:
    和主謂賓句型不同,賓語補足語句型含有主謂賓句型的部分,但賓語後面還有個動作(動詞),也就是賓語補足語。
    因此看賓語後面是否還有動詞,是判斷賓語補足語句型的方法。
    但是有兩個動詞就麻煩了,如何判斷這個動詞是謂語動詞還是賓語補足語動詞呢?那就需要先把所有動詞找出來,如果是賓語補足語動詞,那麼這個動詞在謂語動詞的後面,如果是謂語動詞,則在前面。
    既然要存放多個動詞進行判斷,就要有動詞槽(VerbBox)。
    動詞次序:謂語動詞在賓語補足語動詞之前,所以找到兩個動詞,詞語次序在前面的是謂語動詞,詞語次序在後面的是賓語補足語動詞。
    賓語補足語動詞後面還有個名詞,賓語補足語動詞和這個名詞合併在一起,作為賓語補足語。例如他讓我打掃教室。如果賓語補足語只是“打掃”,話就說不清楚了。但是有些賓語補足語,就只有動詞,後面沒有名詞,例如“他讓我跳舞”就只有“跳舞”這一個動詞,“跳舞”這個詞後面沒有名詞,因為“跳舞”是不及物動詞。

    雙賓語句型和賓語補足語句型,都是由主謂賓句型擴充而成的。雙賓語句型在主謂賓句型的基礎上,多加了一個賓語。賓語補足語句型在主謂賓句型的基礎上,多加了一個動詞(賓語補足語)。所以先完成主謂賓句型,再根據是否有擴充,來判斷是不是雙賓語句型或賓語補足語句型。

    在主謂賓句型的基礎上,如果沒有賓語,就是主謂句型。如果沒有主語,就是省略主語,例如對一個人喊“過來”,這句話的全句顯然是“你過來”。
    */

    if (VerbBox1 == "")//沒有動詞
    {
        return "只有性質狀態";//只有性質狀態的句型
    }
    else if (VerbBox1 != "" && VerbBox2 == "")//有1個動詞
    {
        if (VerbBox1 == "給" || VerbBox1 == "送" || VerbBox1 == "送給" || VerbBox1 == "教")//雙賓語句型的常見動詞(標誌詞)
        {
            return "雙賓語";//雙賓語句型
        }
        else
        {
            return "主謂賓";//主謂賓句型
        }
    }
    else if (VerbBox1 != "" && VerbBox2 != "")//有2個動詞
    {
        return "賓語補足語";//賓語補足語句型
    }
    else
    {
        return "其它";
    }
}

//名詞排序
void NounOrder()
{
    if (NounBox1 != "" && NounBox2 != "")//招到了2個名詞,放在NounBox1和NounBox2
    {
        string temp = "";//臨時變數
        if (dan.IndexOf(NounBox1) > dan.IndexOf(NounBox2))//如果NounBox1的名詞在句子中的位置大於NounBox2的名詞在句子中的位置
        {
            //交換位置,在句子中位置小的名詞放前面,從而確保雙賓語句型時,NounBox1放的是間接賓語,NounBox2放的是直接賓語,畢竟間接賓語在直接賓語前面
            temp = NounBox1;
            NounBox1 = NounBox2;
            NounBox2 = temp;
        }
        FindJianObject = NounBox1;
        FindZhiObject = NounBox2;
        //間接賓語和直接賓語的名詞所有格,之後再做
    }
}

//名詞結合成名詞片語
void NounJoin()
{
    /*
    名詞合併:例如“足球學校”這個詞,會被當成兩個名詞“足球”和“學校”。但實際中,要把它們合併成一個組合名詞,作為主語或賓語。
    前面說了判斷兩個字元之間的內容,如果兩個字元(詞語)是連續的,那麼這兩個詞語之間的內容為空。
    示例:
    //擷取兩個指定字元之間的全部字元
    string str = "白色的貓嘲笑黑色的鼠";//全句
    string res = "";//結果
    string word1 = "的貓";
    string word2 = "的鼠";
    int Word1LastIndex = str.IndexOf(word1) + word1.Length;
    int Word2StartIndex = str.IndexOf(word2);
    res = str.Substring(Word1LastIndex, Word2StartIndex - Word1LastIndex);
    res = str.Substring(str.IndexOf(word1) + word1.Length, str.IndexOf(word2) - (str.IndexOf(word1) + word1.Length));//展開形式
    if (res == "")
    {
        UnityEngine.Debug.Log("連續");
    }
    else
    {
        UnityEngine.Debug.Log("不連續");
    }
    */
    
    string res;
    //判斷NounBox1和NounBox2的名詞是否需要合併
    if (NounBox1 != "" && NounBox2 != "")
    {
        res = "";
        //判斷NounBox1和NounBox2之間是否有內容,如果沒內容(res為空),就說明NounBox1和NounBox2是連續的名詞(中間沒有字元間隔),需要合併
        res = dan.Substring(dan.IndexOf(NounBox1) + NounBox1.Length, dan.IndexOf(NounBox2) - (dan.IndexOf(NounBox1) + NounBox1.Length));
        if (res == "")
        {
            NounBox1 = NounBox1 + NounBox2;//名詞合併
            NounBox2 = "";//合併後,置空
            if (NounBox3 != "")
            {
                NounBox2 = NounBox3;//填補置空的值,否則NounBox1有值,NounBox2為空,NounBox3又有值,就間隔了
                NounBox3 = "";//合併後,置空
                if (NounBox4 != "")
                {
                    NounBox3 = NounBox4;
                    NounBox4 = "";//合併後,置空
                }
            }
        }
    }

    /*
    //判斷NounBox2和NounBox3的名詞是否需要合併
    if (NounBox2 != "" && NounBox3 != "")
    {
        res = "";
        //判斷NounBox2和NounBox3之間是否有內容,如果沒內容(res為空),就說明NounBox2和NounBox3是連續的名詞,需要合併
        res = dan.Substring(dan.IndexOf(NounBox2) + NounBox2.Length, dan.IndexOf(NounBox3) - (dan.IndexOf(NounBox2) + NounBox2.Length));
        if (res == "")
        {
            NounBox2 = NounBox2 + NounBox3;//名詞合併
            NounBox3 = "";//合併後,置空
            if (NounBox4 != "")
            {
                NounBox3 = NounBox4;//填補置空的值
                NounBox4 = "";//合併後,置空
            }
        }
    }

    //判斷NounBox3和NounBox4的名詞是否需要合併
    if (NounBox3 != "" && NounBox4 != "")
    {
        res = "";
        //判斷NounBox3和NounBox4之間是否有內容,如果沒內容(res為空),就說明NounBox3和NounBox4是連續的名詞,需要合併
        res = dan.Substring(dan.IndexOf(NounBox3) + NounBox3.Length, dan.IndexOf(NounBox4) - (dan.IndexOf(NounBox3) + NounBox3.Length));
        if (res == "")
        {
            NounBox3 = NounBox3 + NounBox4;//名詞合併
            NounBox4 = "";//合併後,置空
        }
    }
    */
}

//動詞排序
void VerbOrder()
{
    /*
    如果不排序會怎樣?句子中找到的第一個動詞,可能不是謂語動詞,而是賓語補足語動詞,以賓語補足語動詞分割句子,就錯了。
    謂語動詞和賓語補足語動詞,先找到哪個,取決於這兩個詞,誰在動詞表前面排序,而動詞的排序是不可知的,或許按筆劃排序,或者按首字母排序
    */
    string temp = "";//臨時變數
    if (VerbBox1 != "" && VerbBox2 != "")//招到了個動詞,放在VerbBox1和VerbBox2
    {
        if (dan.IndexOf(VerbBox1) > dan.IndexOf(VerbBox2))//如果VerbBox1的動詞在句子中的位置大於VerbBox2的動詞在句子中的位置
        {
            //交換位置,在句子中位置小動詞的放前面,從而確保VerbBox1放的是謂語動詞,而賓語補足語動詞放到VerbBox2
            temp = VerbBox1;
            VerbBox1 = VerbBox2;
            VerbBox2 = temp;
        }

    }
    if (VerbBox3 != "")
    {
        if (dan.IndexOf(VerbBox1) > dan.IndexOf(VerbBox3))
        {
            temp = VerbBox1;
            VerbBox1 = VerbBox3;
            VerbBox3 = temp;
        }
        if (dan.IndexOf(VerbBox2) > dan.IndexOf(VerbBox3))
        {
            temp = VerbBox2;
            VerbBox2 = VerbBox3;
            VerbBox3 = temp;
        }
    }
    FindVerb = VerbBox1;
}

//動詞結合成動詞片語
void VerbJoin()
{
    //動詞合併:例如“應該愛”是兩個動詞:情態動詞“應該”和普通動詞“愛”,應該合併成一個動詞
    string res;
    //判斷VerbBox1和VerbBox2的動詞是否需要合併
    if (VerbBox1 != "" && VerbBox2 != "")
    {
        res = "";
        //判斷VerbBox1和VerbBox2之間是否有內容,如果沒內容(res為空),就說明VerbBox1和VerbBox2是連續的動詞(中間沒有字元間隔),需要合併
        res = dan.Substring(dan.IndexOf(VerbBox1) + VerbBox1.Length, dan.IndexOf(VerbBox2) - (dan.IndexOf(VerbBox1) + VerbBox1.Length));
        if (res == "")
        {
            VerbBox1 = VerbBox1 + VerbBox2;//名詞合併
            FindVerb = VerbBox1;
            VerbBox2 = "";//合併後,置空
            if (VerbBox3 != "")
            {
                VerbBox2 = VerbBox3;//填補置空的值,否則VerbBox1有值,VerbBox2為空,VerbBox3又有值,就間隔了
                VerbBox3 = "";//合併後,置空
                if (VerbBox4 != "")
                {
                    VerbBox3 = VerbBox4;
                    VerbBox4 = "";//合併後,置空
                }
            }
        }
    }

}

//謂語動詞的發生機率
void VerbRateJudge()
{
    /*
    動詞前面是否有否定詞,也很重要。
    例如“他愛貓”和“他不愛貓”,雖然謂語動詞都是“愛”字,但前面加個“不”字,意義就相反了。所以看謂語動詞前面是否有否定詞,是很重要的事。
    謂語動詞前面的否定詞,一般有不、不要、不可以、不應該、不能、別。
    還有不確定肯定還是否定動詞,例如“他不一定去”,“去”字是動詞,但是動詞前的“不一定”,並不像是“不”字那樣對動詞進行否定,而是對動詞既不像是肯定,也不像是否定,而是不確定。
    因此對每句話的謂語動詞,都要加一個性質:肯定、否定、不確定。
    但不確定,有時候偏向於肯定,例如“他可能去”。有時候不確定偏向於否定,例如“他不太可能去”以及“他或許不去”。
    那麼動詞發生機率分為五種:肯定、偏向肯定、不確定、偏向否定、否定。
    這其實就是在分析事情(謂語動詞)發生的機率,這在機率分析上有用。
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 1, 1);
    指定詞語左邊1個字元:str.Substring(str.IndexOf(word) - 2, 1);
    */

    VerbRate = "肯定";//預設值:肯定
    string temp = "";//臨時變數

    //先判斷謂語動詞左邊的1個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不"))
    {
        VerbRate = "否定";
    }
    else if(temp.Contains("別"))
    {
        VerbRate = "否定";
    }

    //判斷謂語動詞左邊的2個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不要"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不能"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("可能"))
    {
        VerbRate = "不確定";
    }
    else if (temp.Contains("或許"))
    {
        VerbRate = "不確定";
    }

    //判斷謂語動詞左邊的3個字元,是否是否定詞
    temp = dan.Substring(dan.IndexOf(FindVerb) - 1, 1);
    if (temp.Contains("不可以"))
    {
        VerbRate = "否定";
    }
    else if (temp.Contains("不應該"))
    {
        VerbRate = "否定";
    }
}

//找形容詞
string SearchAdj(string str)
{
    string jieguo = "不包含";//預設值是不包含
    int m = adj.Length;//形容詞陣列的長度,也就是有多少個形容詞
    string temp  = "";

    for (int n = 0; n < m; n++)
    {
        /*Contains函式用於判斷包含關係,例如句子和形容詞的包含關係
        就是用句子和形容詞陣列的形容詞,一一比對,來判斷是否包含形容詞
        n的值從0逐漸增長到形容詞陣列的形容詞數量值,這樣陣列也就經歷了所有形容詞
        */
        if (str.Contains(adj[n]))//包含
        {
            jieguo = "包含";
            temp = adj[n];
        }
    }

    if (jieguo == "包含")//找到了形容詞
    {
        return temp;
    }
    else
    {
        return "";
    }
}

//找數詞
void SearchNum(string str)
{
    //先確定數詞單位
    int StrLength = str.Length;//全句長度
    string temp = "";
    string NumDanwei_type = "";//數字單位型別

    string[] shuzu_danwei_mignci = new string[] { "個", "名", "位", "只", "頭", "匹", "條", "棵", "朵", "片", "根", "座", "棟", "臺", "部", "本", "塊", "件", "盞", "把", "所", "輛", "艘", "架", "扇", "間", "包", "盒", "袋", "箱", "桶", "雙" };
    string[] shuzu_danwei_jiliang = new string[] { "米", "釐米", "毫米", "分米", "公里", "裡", "微米", "奈米", "克", "斤", "公斤", "噸", "毫克", "升" };

    //字串從右向左,每次讀取一個字元進行處理
    for (int n = StrLength; n > 0; n--)
    {
        temp = str.Substring(n - 1, 1);//每次擷取的一個字元,例如“年”字

        if (NumDanwei_type == "")
        {
            //名詞單位陣列
            foreach (string m in shuzu_danwei_mignci)//判斷這個擷取的字元是否在名詞陣列中
            {
                if (temp == m)//擷取的字元屬於名詞陣列(shuzu_danwei_mignci)中的字元,例如“個”字屬於名詞陣列
                {
                    NumDanwei = m;
                    NumDanwei_type = "名詞單位";
                    SearchNum2(str, NumDanwei, NumDanwei_type);

                    if (num_type == "漢字型數字")
                    {
                        FindNum = SearchNum3(FindNum);
                    }
                    break;
                }
            }
        }

        if (NumDanwei_type == "")
        {
            //計量陣列
            foreach (string m in shuzu_danwei_jiliang)//判斷這個擷取的字元是否在計量陣列中
            {
                if (temp == m)//擷取的字元屬於計量陣列(shuzu_danwei_jiliang)中的字元,例如“米”字屬於計量陣列
                {
                    NumDanwei = m;
                    if (str.Contains("釐"))
                    {
                        NumDanwei = "釐" + NumDanwei;
                    }
                    else if (str.Contains("毫"))
                    {
                        NumDanwei = "毫" + NumDanwei;
                    }
                    else if (str.Contains("公"))
                    {
                        NumDanwei = "公" + NumDanwei;
                    }
                    NumDanwei_type = "計量單位";
                    SearchNum2(str, NumDanwei, NumDanwei_type);
                    if (num_type == "漢字型數字")
                    {
                        FindNum = SearchNum3(FindNum);
                    }
                    break;
                }
            }
        }
    }

    /*
    找數字的其它方法:正規表示式。
    需要using System.Text.RegularExpressions;//正規表示式找出數字所需
    replace函式把不是數字的部分變為空無,這樣就只剩下數字部分。
    string res = "";
    res = Regex.Replace(str, @"[^0-9]+", "");
    return res;
    */
}

void SearchNum2(string str, string temp, string NumDanwei_type)
{
    //找數字
    string[] shuzu_num = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
    string[] shuzu_num_cn = new string[] { "一", "二", "兩", "三", "四", "五", "六", "七", "八", "九", "零", "十", "百", "千", "萬" };

    //數量單位字元左邊的字串
    string WordLeft = str.Substring(0, str.IndexOf(temp));//例如“有6米”的“有6”

    //找阿拉伯數字,例如1、2、3這類數字
    //逐一處理該字元左邊的每個字元
    int WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
    string temp2 = "";
    //從右向左,逐字擷取
    for (int j = WordleftLength; j > 0; j--)
    {
        temp2 = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元
                                             //從右到左,遇到不是數字的時候,就退出迴圈
        if (temp2 != "1" && temp2 != "2" && temp2 != "3" && temp2 != "4" && temp2 != "5" && temp2 != "6" && temp2 != "7" && temp2 != "8" && temp2 != "9" && temp2 != "0")
        {
            break;
        }
        foreach (string m2 in shuzu_num)//判斷這個擷取的字元是否在數字陣列中
        {
            if (temp2 == m2)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
            {
                if (NumDanwei_type == "名詞單位" || NumDanwei_type == "計量單位")
                {
                    //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                    if (FindNum == "")
                    {
                        FindNum = temp2;
                    }
                    else
                    {
                        FindNum = temp2 + FindNum;
                    }
                    num_type = "阿拉伯數字";
                }
            }
        }
    }

    if (NumDanwei_type == "名詞單位" || NumDanwei_type == "計量單位")
    {
        if (FindNum == "")//沒有找到阿拉伯數字
        {
            //找漢字型數字,例如一、二、三
            WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
            temp2 = "";
            //從右向左,逐字擷取
            for (int j = WordleftLength; j > 0; j--)
            {
                temp2 = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元
                foreach (string m2 in shuzu_num_cn)//判斷這個擷取的字元是否在數字陣列中
                {
                    if (temp2 == m2)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
                    {
                        //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                        if (FindNum == "")
                        {
                            FindNum = temp2;
                        }
                        else
                        {
                            FindNum = temp2 + FindNum;
                        }
                        num_type = "漢字型數字";
                    }
                }
            }
        }
    }
}

string SearchNum3(string find_num)
{
    //漢字型數字轉化為阿拉伯數字,例如“二十”轉化為“20”
    //這個轉化有時候不準確
    int old = 1;
    int result = 0;
    string temp = "";
    int temp_num = 0;

    //old(上一位數字)需要初始化為1,不能初始化為0,也不能不賦值
    //因為如果數字開始(從左到右)第一個字元就是翻倍數(例如十),那麼翻倍的上一位數(old)不能預設0或NULL
    //如果翻倍數沒有上一位數,拿預設1當上一位數(old初始化為1),翻倍數乘以1,就等於翻倍數翻倍自身,這樣才正確

    for (int n = 1; n <= find_num.Length; n++)
    {
        temp = find_num.Substring(n - 1, 1);//每次擷取的一個字元
        switch (temp)
        {
            case "一":
                temp_num = 1;
                break;
            case "二":
                temp_num = 2;
                break;
            case "兩":
                temp_num = 2;
                break;
            case "三":
                temp_num = 3;
                break;
            case "四":
                temp_num = 4;
                break;
            case "五":
                temp_num = 5;
                break;
            case "六":
                temp_num = 6;
                break;
            case "七":
                temp_num = 7;
                break;
            case "八":
                temp_num = 8;
                break;
            case "九":
                temp_num = 9;
                break;
            case "零":
                temp_num = 0;
                break;
            case "十":
                temp_num = 10;
                break;
            case "百":
                temp_num = 100;
                break;
            case "千":
                temp_num = 1000;
                break;
            case "萬":
                temp_num = 10000;
                break;
            default:
                break;
        }

        if (temp_num != 10 && temp_num != 100 && temp_num != 1000 && temp_num != 10000)//不是翻倍字元(十、百、千、萬),而是0到9的數字
        {
            old = temp_num;//把數字存起來,下一次迴圈時,被下一位翻倍數所翻倍
            if (n == find_num.Length)//當i的長度等於總數字的長度,也就是到了最後一位數(個位數),不用翻倍了
            {
                result = result + temp_num;//個位數不用翻倍,直接加
            }
        }
        else//不是0到9的數字字元,而是翻倍字元,就要翻倍
        {
            //翻倍物件是上一位數字,就是old裡存的數字。因為這次迴圈走else路線,所以temp_num沒有賦值給old,因此old裡還是上一位的數字
            result = result + (old * temp_num);//此時的temp_num是翻倍單位(十、百、千、萬),不是0到9的數字,翻倍上一位數字(old)
        }
    }

    if (result != 0)
    {
        find_num = result.ToString();
        return find_num;
    }
    else
    {
        return "";
    }
}

//找時間(文字形式)
void SearchTime1(string str)
{
    string[] shuzu_danwei_time1 = new string[] { "今天", "明天", "後天", "昨天", "前天", "這個月", "下個月", "上個月", "今年", "明年", "去年" };
    string[] shuzu_danwei_time2 = new string[] { "早晨", "上午", "中午", "下午", "傍晚", "晚上", "傍晚", "夜晚", "半夜", "黎明", "黃昏", "清晨" };
    string[] shuzu_danwei_time3 = new string[] { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日", "禮拜一", "禮拜二", "禮拜三", "禮拜四", "禮拜五", "禮拜六", "禮拜天" };
    string[] shuzu_danwei_time4 = new string[] { "春天", "夏天", "秋天", "冬天", "春季", "夏季", "秋季", "冬季" };
    string[] shuzu_danwei_time5 = new string[] { "元旦", "大年三十", "除夕", "春節", "大年初一", "大年初二", "大年初三", "正月十五", "寒假", "清明節", "五一節", "勞動節", "兒童節", "暑假", "中秋節", "國慶節", "聖誕節", "假期", "休息日" };

    foreach (string m in shuzu_danwei_time1)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time2)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time3)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time4)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }

    foreach (string m in shuzu_danwei_time5)
    {
        if (str.Contains(m))
        {
            FindTime2 = m;
        }
    }
}

//找時間(年月日時分,佈置框架)
void SearchTime2(string str)
{
    //找年月日時分
    string TimeDanwei = "";

    if (str.Contains("年"))
    {
        TimeDanwei = "年";
        FindTime_year = SearchTime3(str, TimeDanwei);
    }
    if (str.Contains("月"))
    {
        TimeDanwei = "月";
        FindTime_month = SearchTime3(str, TimeDanwei);
        if (num_type == "漢字型數字")
        {
            FindTime_month = SearchNum3(FindTime_month);
        }
    }
    if (str.Contains("日"))
    {
        TimeDanwei = "日";
        FindTime_day = SearchTime3(str, TimeDanwei);
    }
    if (str.Contains("點"))
    {
        TimeDanwei = "點";
        FindTime_day = SearchTime3(str, TimeDanwei);
    }
    if (str.Contains("分"))
    {
        TimeDanwei = "分";
        FindTime_day = SearchTime3(str, TimeDanwei);
    }
}

//找時間(年月日時分,具體找)
string SearchTime3(string str, string TimeDanwei)
{
    //找數字
    string num = "";
    string[] shuzu_num = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
    string[] shuzu_num_cn = new string[] { "一", "二", "兩", "三", "四", "五", "六", "七", "八", "九", "零", "十", "百", "千", "萬" };

    //數量單位字元左邊的字串
    string WordLeft = str.Substring(0, str.IndexOf(TimeDanwei));
    //找阿拉伯數字,例如1、2、3這類數字
    //逐一處理該字元左邊的每個字元
    int WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
    string temp = "";
    //從右向左,逐字擷取
    for (int j = WordleftLength; j > 0; j--)
    {
        temp = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元

        //從右到左,遇到不是數字的時候,就退出迴圈
        if (temp != "1" && temp != "2" && temp != "3" && temp != "4" && temp != "5" && temp != "6" && temp != "7" && temp != "8" && temp != "9" && temp != "0")
        {
            break;
        }

        foreach (string m in shuzu_num)//判斷這個擷取的字元是否在數字陣列中
        {
            if (temp == m)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
            {
                //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                if (num == "")
                {
                    num = temp;
                }
                else
                {
                    num = temp + num;
                }
                num_type = "阿拉伯數字";

            }
        }
    }

    if (num == "")//沒有找到阿拉伯數字
    {
        //找漢字型數字,例如一、二、三
        WordleftLength = WordLeft.Length;//例如“有6”這個字串的長度
        temp = "";
        //從右向左,逐字擷取
        for (int j = WordleftLength; j > 0; j--)
        {
            temp = WordLeft.Substring(j - 1, 1);//每次擷取的一個字元
            foreach (string m2 in shuzu_num_cn)//判斷這個擷取的字元是否在數字陣列中
            {
                if (temp == m2)//擷取的字元屬於數字陣列(shuzu_num)中的字元,例如“1”字屬於數字陣列
                {
                    //現在找出來的都是數字,但是都是倒序,需要拼接在一起
                    if (num == "")
                    {
                        num = temp;
                    }
                    else
                    {
                        num = temp + num;
                    }
                    num_type = "漢字型數字";
                }
            }
        }
    }

    if (num != "")
    {
        return num;
    }
    else
    {
        return "";
    }

}

//地點
bool difang(string str, string word)
{
    if (str.IndexOf(word) > 0)
    {
        string temp = str.Substring(str.IndexOf(word) - 1, 1);
        if (temp == "在" || temp == "到" || temp == "去" || temp == "來")
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

//顯示最終輸出結果
void ShowResult()
{
    UnityEngine.Debug.Log("第" + dan_num + "句:" + danju[dan_num-1]);
    UnityEngine.Debug.Log("句型:" + SentenceType);

    if (SentenceType == "主謂賓")//主謂賓句型
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("語態:" + yutai);
    }
    else if (SentenceType == "雙賓語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("間接賓語:" + FindJianObject);
        UnityEngine.Debug.Log("直接賓語:" + FindZhiObject);
    }
    else if (SentenceType == "賓語補足語")
    {
        UnityEngine.Debug.Log("主語:" + FindSubject);
        UnityEngine.Debug.Log("謂語:" + FindVerb);
        UnityEngine.Debug.Log("賓語:" + FindObject);
        UnityEngine.Debug.Log("賓語補足語動詞:" + FindBuVerb);
        UnityEngine.Debug.Log("賓語補足語名詞:" + FindBuNoun);
    }
    else if (SentenceType == "只有性質狀態")
    {
        UnityEngine.Debug.Log("只有性質狀態:" + dan);
    }

    UnityEngine.Debug.Log("動詞發生機率:" + VerbRate);

    //顯示名詞所有格
    if (SubjectSuoyouge != "")
    {
        UnityEngine.Debug.Log("主語的名詞所有格:" + SubjectSuoyouge);
    }
    if (ObjectSuoyouge != "")
    {
        UnityEngine.Debug.Log("賓語的名詞所有格:" + ObjectSuoyouge);
    }
    if (JianSuoyouge != "")
    {
        UnityEngine.Debug.Log("間接賓語的名詞所有格:" + JianSuoyouge);
    }
    if (ZhiSuoyouge != "")
    {
        UnityEngine.Debug.Log("直接賓語的名詞所有格:" + ZhiSuoyouge);
    }
    if (BuSuoyouge != "")
    {
        UnityEngine.Debug.Log("賓語補足語的名詞所有格:" + BuSuoyouge);
    }

    //顯示形容詞
    if (SubjectAdj != "")
    {
        UnityEngine.Debug.Log("主語的形容詞:" + SubjectAdj);
    }
    if (ObjectAdj != "")
    {
        UnityEngine.Debug.Log("賓語的形容詞:" + ObjectAdj);
    }
    if (JianAdj != "")
    {
        UnityEngine.Debug.Log("間接賓語的形容詞:" + JianAdj);
    }
    if (ZhiAdj != "")
    {
        UnityEngine.Debug.Log("直接賓語的形容詞:" + ZhiAdj);
    }
    if (BuAdj != "")
    {
        UnityEngine.Debug.Log("賓語補足語的形容詞:" + BuAdj);
    }

    //顯示數詞
    if (SubjectNum != "")
    {
        UnityEngine.Debug.Log("主語的數詞:" + SubjectNum);
    }
    if (ObjectNum != "")
    {
        UnityEngine.Debug.Log("賓語的數詞:" + ObjectNum);
    }
    if (JianNum != "")
    {
        UnityEngine.Debug.Log("間接賓語的數詞:" + JianNum);
    }
    if (ZhiNum != "")
    {
        UnityEngine.Debug.Log("直接賓語的數詞:" + ZhiNum);
    }
    if (BuNum != "")
    {
        UnityEngine.Debug.Log("賓語補足語的數詞:" + BuNum);
    }

    //顯示時間
    if (FindTime_year != "")
    {
        UnityEngine.Debug.Log("年:" + FindTime_year);
    }
    if (FindTime_month != "")
    {
        UnityEngine.Debug.Log("月:" + FindTime_month);
    }
    if (FindTime_day != "")
    {
        UnityEngine.Debug.Log("日:" + FindTime_day);
    }
    if (FindTime_hour != "")
    {
        UnityEngine.Debug.Log("時(幾點):" + FindTime_hour);
    }
    if (FindTime_minute != "")
    {
        UnityEngine.Debug.Log("分(幾分):" + FindTime_minute);
    }
    if (FindTime2 != "")
    {
        UnityEngine.Debug.Log("時間:" + FindTime2);
    }

    //顯示地點
    if (didian != "")
    {
        UnityEngine.Debug.Log("地點:" + didian);
    }

    GuessWord();//猜測詞語

    //tmpText.text = mes;

    //清空變數
    FindSubject = "";
    FindVerb = "";
    FindObject = "";
    FindBuVerb = "";
    FindBuNoun = "";
    FindJianObject = "";
    FindZhiObject = "";

    yutai = "";

    SubjectSuoyouge = "";
    ObjectSuoyouge = "";
    JianSuoyouge = "";
    ZhiSuoyouge = "";
    BuSuoyouge = "";

    SubjectAdj = "";
    ObjectAdj = "";
    JianAdj = "";
    ZhiAdj = "";
    BuAdj = "";

    SubjectNum = "";
    ObjectNum = "";
    JianNum = "";
    ZhiNum = "";
    BuNum = "";
}

//猜測詞語
void GuessWord()
{
    /*
    不建議用猜測詞語,因為如果一個詞語,詞庫裡沒有,要靠程式猜測,那麼遊戲劇情肯定對這個詞語沒做任何準備,就算猜測出這個詞,也沒用。
    例如張三愛雅娜,名詞詞庫肯定沒有“雅娜”這個詞,但是謂語動詞“愛”字右邊的句子的兩個字,顯然是賓語名詞,所以猜測詞語是很容易猜測的。
    就算猜測出賓語是雅娜,又怎樣了呢,對雅娜的資訊和屬性,什麼都沒有設定,程式沒法分析。甚至連雅娜到底是一個人還是一塊石頭,都沒法分析。
    那麼張三帶著雅娜去海邊,到底是張三帶著女人雅娜去海邊,還是張三帶著石頭雅娜去海邊,準備扔石頭玩水漂。計算機分析程式一頭霧水,所以猜測詞語會降低計算機的分析能力。
    還是勤快點吧,把詞語錄入詞庫,並給詞語設定資訊和屬性。什麼時候用猜測詞語呢?詞庫詞彙量還不夠多的時候,只能靠猜詞來補償,但這不是長遠的辦法。
    這就好比程式設計強調“對變數,要先定義,後使用”,猜測詞語就好比不定義就直接使用。

    猜測詞語的原理:抽取掉已知的詞語(詞庫裡有的詞語),剩下的未知的詞語(詞庫裡沒有的詞語),就是要猜測的詞。
    例如“張三喜歡美麗的雅娜”,謂語動詞右邊句是“美麗的雅娜”,詞庫已有的形容詞是“美麗的”,抽取掉形容詞“美麗的”,剩下的詞語“雅娜”就是要猜測的賓語。
    */

    string GuessObject = "";//猜測賓語
    string GuessBuNoun = "";//猜測賓語補足語的名詞
    string GuessJian = "";//猜測間接賓語
    string GuessZhi = "";//猜測直接賓語
    string temp = "";//臨時變數

    //猜測主謂賓句型的賓語
    if (SentenceType == "主謂賓")
    {
        if (FindObject == "")
        {
            temp = RightPart;//謂語動詞右邊句
            if (ObjectSuoyouge != "")
            {
                temp = RightPart.Replace("ObjectSuoyouge", "");//把名詞所有格變為空無,就是抽取掉
            }
            if (ObjectAdj != "")
            {
                temp = RightPart.Replace("ObjectAdj", "");//把形容詞變為空無,就是抽取掉
            }
            if (ObjectNum != "")
            {
                temp = RightPart.Replace("ObjectNum", "");//把數詞變為空無,就是抽取掉
            }
            if (temp != "")
            {
                GuessObject = temp;
            }
        }
    }

    //賓語補足語句型,猜測名詞
    //謂語動詞和賓語補足語名詞之間的字串,就是要猜測的賓語名詞
    if (SentenceType == "賓語補足語")
    {
        if (FindObject == "")
        {
            temp = dan;
            temp = dan.Substring(dan.IndexOf(FindVerb) + FindVerb.Length, dan.IndexOf(FindVerb) - (dan.IndexOf(FindVerb) + FindVerb.Length));
            GuessObject = temp;
        }
        //賓語補足語句型,猜測賓語補足語名詞
        if (FindBuNoun == "")
        {
            temp = "";
            temp = dan.Substring(dan.IndexOf(FindBuVerb) + FindBuVerb.Length, dan.Length - (dan.IndexOf(FindBuVerb) + FindBuVerb.Length));
            if (temp != "")
            {
                GuessBuNoun = temp;
            }
        }
    }

    /*
    猜測雙賓語句型的直接賓語。
    例如“張三給李四一個雅娜”,李四是間接賓語,也是詞庫已有的名詞,雅娜是直接賓語,詞庫沒有這個名詞,只能靠猜測詞語。
    間接賓語和直接賓語之間,有一個定語(數詞:一個),這個定語右邊的詞語,就是直接賓語,左邊的名詞就是間接賓語。
    前面的程式裡,如果雙賓語句型,只找到一個賓語名詞(直接賓語或間接賓語),那就轉化為主謂賓句型了,因為主謂賓句型只有一個賓語。但實際上可能是雙賓語句型中,有個賓語不屬於詞庫,所以沒找到。
    如果謂語動詞是給、給予,這是雙賓語句型的標誌動詞,確實很可能是雙賓語句型,那麼就當雙賓語句型去猜詞吧。
    */

    //猜測主謂賓句型的賓語
    if (SentenceType == "主謂賓")//假如之前把雙賓語句型誤當主謂賓句型
    {
        if (FindVerb == "給" || FindVerb == "給予" || FindVerb == "送給" || FindVerb == "教")//雙賓語句的標誌動詞
        {
            if (ObjectAdj != "")
            {
                //謂語動詞右邊句裡,賓語形容詞(ObjectAdj)的左邊句
                string temp_left = RightPart.Substring(0, RightPart.IndexOf(ObjectAdj));
                //謂語動詞右邊句裡,賓語形容詞(ObjectAdj)的右邊句
                string temp_right = RightPart.Substring(RightPart.IndexOf(ObjectAdj) + ObjectAdj.Length, RightPart.Length - (RightPart.IndexOf(ObjectAdj) + ObjectAdj.Length));
                if (temp_left != "")
                {
                    GuessJian = temp_left;
                }
                if (temp_right != "")
                {
                    GuessZhi = temp_right;
                }
            }
            if (ObjectNum != "")
            {
                //謂語動詞右邊句裡,賓語數詞(ObjectNum)的左邊句
                string temp_left = RightPart.Substring(0, RightPart.IndexOf(ObjectNum));
                //謂語動詞右邊句裡,賓語數詞(ObjectNum)的右邊句
                string temp_right = RightPart.Substring(RightPart.IndexOf(ObjectNum) + ObjectNum.Length, RightPart.Length - (RightPart.IndexOf(ObjectNum) + ObjectNum.Length));
                if (temp_left != "")
                {
                    GuessJian = temp_left;
                }
                if (temp_right != "")
                {
                    GuessZhi = temp_right;
                }
            }
            if (ObjectSuoyouge != "")
            {
                //謂語動詞右邊句裡,賓語的名詞所有格(ObjectSuoyouge)的左邊句
                string temp_left = RightPart.Substring(0, RightPart.IndexOf(ObjectSuoyouge));
                //謂語動詞右邊句裡,賓語的名詞所有格(ObjectSuoyouge)的右邊句
                string temp_right = RightPart.Substring(RightPart.IndexOf(ObjectSuoyouge) + ObjectSuoyouge.Length, RightPart.Length - (RightPart.IndexOf(ObjectSuoyouge) + ObjectSuoyouge.Length));
                if (temp_left != "")
                {
                    GuessJian = temp_left;
                }
                if (temp_right != "")
                {
                    GuessZhi = temp_right;
                }
            }
        }
    }

    //顯示結果
    if (GuessObject != "")
    {
        UnityEngine.Debug.Log("猜測賓語:" + GuessObject);
    }
    if (GuessBuNoun != "")
    {
        UnityEngine.Debug.Log("猜測賓語補足語的名詞:" + GuessBuNoun);
    }
    if (GuessJian != "")
    {
        UnityEngine.Debug.Log("猜測間接賓語:" + GuessJian);
    }
    if (GuessZhi != "")
    {
        UnityEngine.Debug.Log("猜測直接賓語:" + GuessZhi);
    }

    //清空變數
    GuessObject = "";
    GuessBuNoun = "";
    GuessJian = "";
    GuessZhi = "";
}

}

相關文章