Browse Source

添加项目文件。

luocaiyang 11 tháng trước cách đây
mục cha
commit
b3a5d5d75f

+ 9 - 0
IPRS.xiaoshi.sz.com/IPRS.xiaoshi.sz.com.csproj

@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+</Project>

+ 41 - 0
IPRS.xiaoshi.sz.com/Parser.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+
+namespace IPRS.xiaoshi.sz.com
+{
+    public class Parser
+    {
+        public Patent ParserFulltext(string fulltextXml)
+        {
+            Patent ret = new Patent();
+            XDocument doc = XDocument.Parse(fulltextXml);
+
+            XElement BiblioElement = doc.Root.Element("{http://www.sipo.gov.cn/XMLSchema/business}BibliographicData");
+            XElement pubElement = BiblioElement.Elements("{http://www.sipo.gov.cn/XMLSchema/business}PublicationReference").FirstOrDefault(e=>e.Attribute("dataFormat")?.Value  == "original");
+            XElement DocIdElement = pubElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}DocumentID");
+            var WIPOST3Code = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}WIPOST3Code").Value;
+            var DocNumber = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}DocNumber").Value;
+            var Kind = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}Kind").Value;
+            var Date = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}Date").Value;
+            ret.PubNo = $"{WIPOST3Code}{DocNumber}{Kind}";
+            ret.PubDate = DateTime.ParseExact(Date.ToString(), "yyyyMMdd", null);
+
+            XElement appElement = BiblioElement.Elements("{http://www.sipo.gov.cn/XMLSchema/business}ApplicationReference").FirstOrDefault(e => e.Attribute("dataFormat")?.Value == "original");
+            DocIdElement = pubElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}DocumentID");
+            WIPOST3Code = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}WIPOST3Code").Value;
+            DocNumber = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}DocNumber").Value;
+            Kind = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}Kind").Value;
+            Date = DocIdElement.Element("{http://www.sipo.gov.cn/XMLSchema/base}Date").Value;
+            ret.AppNo = $"{WIPOST3Code}{DocNumber}{Kind}";
+            ret.AppDate  = DateTime.ParseExact(Date.ToString(), "yyyyMMdd", null);
+
+
+            return ret;
+        }
+    }
+}

+ 29 - 0
IPRS.xiaoshi.sz.com/Patent.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IPRS.xiaoshi.sz.com
+{
+    public class Patent
+    {
+        public string AppNo { get; set; }
+        public string Title { get; set; }
+        public DateTime AppDate { get; set; }
+        public string PubNo {  get; set; }
+        public DateTime PubDate { get; set; }
+        public string IssueNo {  get; set; }
+        public DateTime IssueDate { get; set; }
+        public string Abstract {  get; set; }
+        public string Claim {  get; set; }  
+        public string FullText { get; set; }
+        public List<string> IPCs { get; set; }
+        public List<string> Applicants { get; set; }
+        public List<string> Inventors { get; set; }
+        public string Agency {  get; set; }
+        public List<string> Agents { get; set; }
+
+
+    }
+}

+ 226 - 0
IPRS.xiaoshi.sz.com/Searcher.cs

@@ -0,0 +1,226 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Security.Cryptography;
+using System.Text.Json;
+
+namespace IPRS.xiaoshi.sz.com
+{
+    public class IPRSSearcher
+    {
+        private static string SearchAppId = "K8FFB741E163BE6536";
+        private static string SearchAppKey = "FNYJD7902206FFB741E163BE6536C3689D55";
+
+        string appId = "1000046";
+        string appKey = "6AE6D4DC6AF94F26862501EDEE9E27A2";
+        public string? GetPatents(string strCondtion,int page,int size)
+        {
+            int tryCount = 0;
+            begin:
+            string strSearchUrl = "http://s.patentstar.com.cn/SearchAPI/PatentSearch/ResultGet";
+            string stamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
+            string queryJson = "{\"CurrentQuery\":\"" + strCondtion + "\",\"DBType\":\"CN\",\"PageNum\":" +page.ToString() + ",\"RowCount\":" + size.ToString() + ",\"OrderBy\":\"ID\",\"OrderByType\":\"ASC\"}";
+
+            string sign = EncryptStringToMD5( SearchAppKey + stamp);
+
+            var content = new FormUrlEncodedContent(new[]
+            {
+                new KeyValuePair<string, string>("AppID", SearchAppId),
+                new KeyValuePair<string, string>("Stamp", stamp),
+                new KeyValuePair<string, string>("Sign", sign),
+                new KeyValuePair<string, string>("QueryJson", queryJson)
+            });
+
+
+
+            using (HttpClient client = new HttpClient())
+            {
+                try
+                {
+                    var retTask = client.PostAsync(strSearchUrl, content);
+                    retTask.Wait();
+                    return retTask.Result.Content.ReadAsStringAsync().Result;
+                }
+                catch(Exception ex)
+                {
+                    tryCount ++;
+                    if(tryCount < 3)
+                    {
+                        System.Threading.Thread.Sleep(1000);
+                        goto begin;
+                    }
+                    Console.WriteLine(ex.Message);
+                }
+            }
+
+            return null;
+        }
+
+        private string GetIPRSData(string url)
+        {
+            int iTryCount = 0;
+            tryAgain:
+            long currentTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+            string sign = appId + appKey + currentTimeMillis.ToString();
+            string signMd5 = EncryptStringToMD5(sign);
+
+            try
+            {
+                using (HttpClient client = new HttpClient())
+                {
+                    client.DefaultRequestHeaders.Add("_appid", appId);
+                    client.DefaultRequestHeaders.Add("_timestamp", currentTimeMillis.ToString());
+                    client.DefaultRequestHeaders.Add("_sign", signMd5);
+
+                    var resTask = client.GetAsync(url);
+                    resTask.Wait();
+
+                    HttpResponseMessage response = resTask.Result;
+                    response.EnsureSuccessStatusCode();
+                    string responseBody = response.Content.ReadAsStringAsync().Result;
+                    //Console.WriteLine(responseBody);
+                    return responseBody;
+                }
+            }
+            catch (Exception ex)
+            {
+                iTryCount ++;
+                if(iTryCount < 3)
+                {
+                    goto tryAgain;
+                }
+
+                return null;
+            }
+        }
+
+        public string GetPatentCNBiblio(string appNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/CnBibo/{appNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentFullTxtInfo(string appNo)
+        {
+            //string url = $"https://api.patentstar.com.cn/api/Patent/CnBibo/{appNo}";
+            string url = $"https://api.patentstar.com.cn/api/Patent/CnFullXml/{appNo}";
+
+            return GetIPRSData (url) ;
+        }
+
+        public string GetPatentCnMainPic(string appNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/CnMainImage/{appNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentCNWGImage(string appNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/CnWGImage/{appNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentCNLegal(string appNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/CnLegal/{appNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentCNPdf(string appNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/CnPdf/{appNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentENPdf(string pubNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/EnPdf/{pubNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentENBiblio(string pubNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/EnBib/{pubNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentFamilys(string pubNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/FamilyByPubNo/{pubNo}";
+            return GetIPRSData(url);
+        }
+
+        public string GetPatentCitedNum(string pubNo)
+        {
+            string url = $"https://api.patentstar.com.cn/api/Patent/CitedNumByPubNo/{pubNo}";
+            return GetIPRSData(url);
+        }
+
+
+        /// <summary>
+        /// MD5加密
+        /// </summary>
+        /// <param name="encryptString">_appid + appkey + _timestamp</param>
+        /// <returns>_sign</returns>
+        private string EncryptStringToMD5(string input)
+        {
+            // 创建一个MD5实例
+            using (MD5 md5 = MD5.Create())
+            {
+                // 将输入字符串转换为字节数组并计算哈希值
+                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
+                byte[] hashBytes = md5.ComputeHash(inputBytes);
+
+                // 将字节数组转换为十六进制字符串
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < hashBytes.Length; i++)
+                {
+                    sb.Append(hashBytes[i].ToString("X2"));
+                }
+                return sb.ToString();
+            }
+        }
+
+        public List<string> splitCondition(string condition,DateTime startDate,DateTime endDate)
+        {
+            string temCond = $"{condition}*{startDate.ToString("yyyyMMdd")}>{endDate.ToString("yyyyMMdd")}/AD";
+            string? strRet = GetPatents(temCond, 1, 1);
+            int TotalPatents = 0;
+            using (JsonDocument document = JsonDocument.Parse(strRet))
+            {
+                var retCode = document.RootElement.GetProperty("Ret").GetInt32();
+                TotalPatents = document.RootElement.GetProperty("Data").GetProperty("HitCount").GetInt32();
+            }
+
+            if (TotalPatents > 10000)
+            {
+                DateTime midDate = endDate.Subtract((endDate - startDate)/2);
+                
+                List<string> list = new List<string>();
+
+                List<string> lst1 = splitCondition(condition,startDate,midDate);
+                List<string> lst2 = splitCondition(condition,midDate,endDate );
+
+                list.AddRange(lst1);
+                list.AddRange(lst2);
+
+                return list;
+
+            }
+            else
+            {
+                if (TotalPatents > 0)
+                {
+                    return new List<string>() { temCond };
+                }
+                else
+                {
+                    return new List<string>();
+                }
+            }
+        }
+
+    }
+}

+ 7 - 0
IPRS/Class1.cs

@@ -0,0 +1,7 @@
+namespace IPRS
+{
+    public class Class1
+    {
+
+    }
+}

+ 9 - 0
IPRS/IPRS.csproj

@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+</Project>

+ 304 - 0
testtrieTree/Program.cs

@@ -0,0 +1,304 @@
+using IPRS.xiaoshi.sz.com;
+using Microsoft.VisualBasic;
+using System;
+using System.IO;
+using System.Reflection.Metadata;
+using System.Runtime.CompilerServices;
+using System.Text.Json;
+using testtrieTree;
+using trieTree.xiaoshi.sz.com;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+
+
+// See https://aka.ms/new-console-template for more information
+
+Console.WriteLine("请选择:");
+Console.WriteLine("1、手动输入地址解析;");
+Console.WriteLine("2、从文件中读取地址批量解析;");
+Console.WriteLine("3、测试IPRS检索;");
+Console.WriteLine("4、测试IPRS获取中国专利全文文本;");
+Console.WriteLine("5、测试IPRS获取中国专利PDF;");
+Console.WriteLine("6、测试IPRS获取中国专利著录项目;");
+
+string? key = Console.ReadLine();
+
+switch (key)
+{
+    
+    case "4":
+        Console.Write("请输入专利申请号:");
+        string strAppNo = Console.ReadLine();
+        IPRSSearcher searcher = new IPRSSearcher();
+        var ret =searcher.GetPatentFullTxtInfo(strAppNo);
+        Console.WriteLine(ret.ToString());
+        
+        Parser paser = new Parser();
+        var p = paser.ParserFulltext(ret.ToString());
+        break;
+    case "5":
+        Console.Write("请输入专利申请号:");
+        strAppNo = Console.ReadLine();
+        searcher = new IPRSSearcher();
+        ret = searcher.GetPatentCNPdf(strAppNo);
+        Console.WriteLine(ret.ToString());
+        break;
+    case "6":
+        Console.Write("请输入专利申请号:");
+        strAppNo = Console.ReadLine();
+        searcher = new IPRSSearcher();
+        ret = searcher.GetPatentCNBiblio(strAppNo);
+        Console.WriteLine(ret.ToString());
+        break;
+    case "1":
+        Console.WriteLine(DateTime.Now.ToString());
+        AddressUtility parser = new AddressUtility();
+
+        Console.WriteLine(DateTime.Now.ToString());
+
+        while (true)
+        {
+            Console.Write("请输入解析的地址:");
+            string strAddress = Console.ReadLine();
+
+            if (strAddress != "exit")
+            {
+                List<string>? result = parser.Paser(strAddress);
+
+                if (result != null)
+                {
+                    foreach (string s in result)
+                    {
+                        Console.Write($"{s}\t");
+                    }
+                    Console.WriteLine();
+                }
+
+                Console.WriteLine(DateTime.Now);
+            }
+            else
+            {
+                Console.WriteLine("bye!");
+                break;
+            }
+
+        }
+        break;
+    case "2":
+        Console.WriteLine(DateTime.Now.ToString());
+        parser = new AddressUtility();
+
+        Console.WriteLine(DateTime.Now.ToString());
+        string csvFile = "c:/temp/地址.txt";
+        List<string> strings = new List<string>();
+        using (StreamReader sr = new StreamReader(csvFile))
+        {
+            while (!sr.EndOfStream)
+            {
+                string line = sr.ReadLine();
+
+                List<string> retList = parser.Paser(line);
+                string str = "\"" + line.Trim() + "\"";
+                string ssqx = "";
+                string sszq = "";
+                int i = 0;
+                foreach (var s in retList)
+                {
+                    if (i < 2)
+                    {
+                        if (s != "市辖区" && s != "省直辖县级行政区划")
+                            sszq += s;
+                    }
+
+                    if (i < 3)
+                    {
+                        if (s != "市辖区" && s != "省直辖县级行政区划")
+                            ssqx += s;
+
+                    }
+                    str += "," + s;
+                    i++;
+                }
+
+                for (int j = i; j < 5; j++)
+                {
+                    str += ",";
+                }
+                str = str + "," + line.Contains(ssqx).ToString() + "," + line.Contains(sszq).ToString();
+                Console.WriteLine(str);
+                strings.Add(str);
+            }
+        }
+
+        string strPath = $"c:/temp/address_{DateTime.Now.ToString("hhmmss")}.csv";
+        using (StreamWriter streamWriter = new StreamWriter(strPath, true, System.Text.Encoding.UTF8))
+        {
+            streamWriter.WriteLine("地址,省,市,区县,乡镇,村级,区县正确,市正确,省正确");
+            foreach (var s in strings)
+            {
+                streamWriter.WriteLine(s);
+            }
+        }
+
+        Console.WriteLine(DateTime.Now);
+        break;
+    case "3":
+        string savePath = "e:/CNWGPatents/";
+        DateTime start = DateTime.Parse("2021-06-08");
+        DateTime end = DateTime.Parse("2021-12-31");
+        while(start.CompareTo(end) < 0)
+        {
+            //Console.WriteLine("请输入下载的日期(yyyymmdd):");
+            string strPubDate = start.ToString("yyyyMMdd");
+            string strCondition = $"F XX {strPubDate}/GD*3/PT";
+
+            string strRet = new IPRSSearcher().GetPatents(strCondition, 1, 1);
+            int TotalPatents = 0;
+            using (JsonDocument document = JsonDocument.Parse(strRet))
+            {
+                var retCode = document.RootElement.GetProperty("Ret").GetInt32();
+                TotalPatents = document.RootElement.GetProperty("Data").GetProperty("HitCount").GetInt32();
+            }
+
+            List<string> list = new List<string>();
+            string temSavePath = $"{savePath}{strPubDate}";
+            if (TotalPatents > 0)
+            {
+                
+                if (!System.IO.Directory.Exists(temSavePath))
+                {
+                    System.IO.Directory.CreateDirectory(temSavePath);
+                }
+
+                if (TotalPatents > 10000)
+                {
+                    list = new IPRSSearcher().splitCondition(strCondition,DateTime.Now.AddYears(-15),DateTime.Now);
+                }
+                else
+                {
+                    list.Add(strCondition);
+                }
+            }
+            
+
+            foreach (string c in list)
+            {
+                string strRet1 = new IPRSSearcher().GetPatents(c, 1, 1);
+                int TotalPatents1 = 0;
+                using (JsonDocument document = JsonDocument.Parse(strRet1))
+                {
+                    var retCode1 = document.RootElement.GetProperty("Ret").GetInt32();
+                    TotalPatents1 = document.RootElement.GetProperty("Data").GetProperty("HitCount").GetInt32();
+                }
+
+                if (TotalPatents1 > 0)
+                {
+
+                    
+                    int totalPages = (TotalPatents1 % 50 == 0) ? TotalPatents1 / 50 : TotalPatents1 / 50 + 1;
+
+                    for (int page = 1; page <= totalPages; page++)
+                    {
+                        strRet1 = new IPRSSearcher().GetPatents(c, page, 50);
+                        using (JsonDocument document = JsonDocument.Parse(strRet1))
+                        {
+                            var retCode = document.RootElement.GetProperty("Ret").GetInt32();
+                            //TotalPatents = document.RootElement.GetProperty("Data").GetProperty("HitCount").GetInt32();
+                            var Datas = document.RootElement.GetProperty("Data").GetProperty("List");
+
+                            for (int i = 0; i < Datas.GetArrayLength(); i++)
+                            {
+                                string appNo = Datas[i].GetProperty("AN").GetString().Replace(".", "");
+
+                                if (!System.IO.File.Exists($"{temSavePath}/{appNo}.json"))
+                                {
+
+                                    using (StreamWriter writer = new StreamWriter($"{temSavePath}/{appNo}.json"))
+                                    {
+                                        writer.WriteLine(Datas[i].ToString());
+                                    }
+                                    var searcher1 = new IPRSSearcher();
+                                    int iGetMPic = 0;
+                                TryGetMainPic:
+                                    try
+                                    {
+                                        string mpicUrl = searcher1.GetPatentCnMainPic(appNo);
+                                        byte[] data = new HttpClient().GetByteArrayAsync(mpicUrl).Result;
+                                        using (FileStream fileStream = new FileStream($"{temSavePath}/{appNo}_abs.jpeg", FileMode.Create))
+                                        {
+                                            fileStream.Write(data, 0, data.Length);
+                                        }
+                                    }
+                                    catch (Exception ex)
+                                    {
+                                        iGetMPic++;
+                                        if (iGetMPic < 3)
+                                        {
+                                            goto TryGetMainPic;
+                                        }
+                                    }
+
+                                    string strWGImagesUrl = searcher1.GetPatentCNWGImage(appNo);
+
+                                    if (!string.IsNullOrEmpty(strWGImagesUrl))
+                                    {
+                                        string[] img_urls = strWGImagesUrl.Split('|');
+
+
+                                        for (int idx = 0; idx < img_urls.Length; idx++)
+                                        {
+                                            int iTryGetPic = 0;
+                                        TryGetPic:
+                                            try
+                                            {
+                                                byte[] data = new HttpClient().GetByteArrayAsync(img_urls[idx]).Result;
+                                                using (FileStream fileStream = new FileStream($"{temSavePath}/{appNo}_img{idx + 1}.jpeg", FileMode.Create))
+                                                {
+                                                    fileStream.Write(data, 0, data.Length);
+                                                }
+                                            }
+                                            catch
+                                            {
+                                                iTryGetPic++;
+
+                                                if (iTryGetPic < 3)
+                                                {
+                                                    goto TryGetPic;
+                                                }
+                                            }
+
+                                        }
+                                    }
+
+                                }
+                                Console.WriteLine($"{(page - 1) * 50 + i + 1}/{TotalPatents}\t{appNo}\t{DateTime.Now}\t{start.ToString("yyyMMdd")}");
+
+                            }
+
+                        }
+
+
+                    }
+                }
+            }
+            start = start.AddDays(1);
+            while ((start.DayOfWeek != DayOfWeek.Friday ) && (start.DayOfWeek != DayOfWeek.Tuesday))
+            {
+                start = start.AddDays(1);
+            }
+                
+        }
+        
+
+            //return;
+        break;
+    default:
+        break;
+}
+
+
+
+
+
+
+
+

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 665650 - 0
testtrieTree/data/area_code_2024.csv


+ 21 - 0
testtrieTree/testtrieTree.csproj

@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\IPRS.xiaoshi.sz.com\IPRS.xiaoshi.sz.com.csproj" />
+    <ProjectReference Include="..\trieTree\trieTree.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="data\area_code_2024.csv">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+</Project>

+ 503 - 0
testtrieTree/utility.cs

@@ -0,0 +1,503 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+using trieTree.xiaoshi.sz.com;
+
+namespace testtrieTree
+{
+    public class AddressUtility
+    {
+        trieTree.xiaoshi.sz.com.trieTree tree = new trieTree.xiaoshi.sz.com.trieTree();
+        private Hashtable keyAddress = new Hashtable();
+        public AddressUtility() {
+
+            string filePath = "data/tree.bin";
+
+            if (File.Exists(filePath))
+            {
+                tree.Load(filePath);
+            }
+            else
+            {
+                string csvFile = "data/area_code_2024.csv";
+                using (StreamReader sr = new StreamReader(csvFile))
+                {
+                    while (!sr.EndOfStream)
+                    {
+                        string line = sr.ReadLine();
+                        string[] values = line.Split(',');
+
+                        //if (!keyAddress.ContainsKey(values[0]))
+                        //{
+                        //    keyAddress.Add(values[0], values[1]);
+                        //}
+
+                        switch (values[2])
+                        {
+                            case "1":
+                                tree.AddWord(values[1], values[0] + values[1]);
+
+                                if (values[1].EndsWith("市") || values[1].EndsWith("省"))
+                                    tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
+
+                                if (values[1].EndsWith("自治区"))
+                                    tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+
+                                break;
+                            case "2":
+                                if (values[1] != "市辖区"
+                                    && values[1] != "省直辖县级行政区划"
+                                    && values[1] != "县"
+                                    && values[1] != "自治区直辖县级行政区划")
+                                {
+                                    tree.AddWord(values[1], values[0] + values[1]);
+                                    if (values[1].EndsWith("市") || values[1].EndsWith("盟"))
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
+                                    }
+
+                                    if (values[1].EndsWith("地区"))
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
+                                    }
+                                    #region 特殊市级名称
+                                    //朝鲜族自治州 
+                                    //阿坝藏族羌族自治州 
+                                    //甘孜藏族自治州
+                                    //凉山彝族自治州
+                                    //黔西南布依族苗族自治州
+                                    //黔东南苗族侗族自治州
+                                    //黔南布依族苗族自治州
+                                    //楚雄彝族自治州
+                                    //红河哈尼族彝族自治州
+                                    //文山壮族苗族自治州
+                                    //西双版纳傣族自治州
+                                    //大理白族自治州
+                                    //德宏傣族景颇族自治州
+                                    //怒江傈僳族自治州
+                                    //临夏回族自治州
+                                    //甘南藏族自治州
+                                    //海北藏族自治州
+                                    //黄南藏族自治州
+                                    //海南藏族自治州
+                                    //果洛藏族自治州
+                                    //玉树藏族自治州
+                                    //海西蒙古族藏族自治州
+                                    //昌吉回族自治州
+                                    //博尔塔拉蒙古自治州
+                                    //巴音郭楞蒙古自治州
+                                    //克孜勒苏柯尔克孜自治州
+                                    //伊犁哈萨克自治州
+                                    #endregion
+
+                                }
+                                break;
+
+                            case "3":
+
+                                tree.AddWord(values[1], values[0] + values[1]);
+                                if (values[1].EndsWith("旗") || values[1].EndsWith("市") || (values[1].EndsWith("区") && !values[1].EndsWith("地区")) || (values[1].EndsWith("县") && !values[1].EndsWith("自治县")))
+                                {
+                                    if (values[1].Length > 2)
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
+                                    }
+
+                                }
+
+                                if (values[1].EndsWith("地区"))
+                                {
+                                    if (values[1].Length > 3)
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
+                                }
+
+                                if (values[1].EndsWith("自治县"))
+                                {
+                                    if (values[1].Length > 4)
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+                                }
+                                #region 特殊区县级名称
+                                //和布克赛尔蒙古自治县
+                                //察布查尔锡伯自治县
+                                //塔什库尔干塔吉克自治县
+                                //焉耆回族自治县
+                                //木垒哈萨克自治县
+                                #endregion
+
+                                break;
+
+                            case "4":
+                                if (!values[1].Contains("直辖"))
+                                {
+                                    tree.AddWord(values[1], values[0] + values[1]);
+
+                                }
+                                break;
+
+                            case "5":
+                                //break;
+                                tree.AddWord(values[1], values[0] + values[1]);
+
+                                if (values[1].EndsWith("居委会") || values[1].EndsWith("生活区"))
+                                {
+                                    if (values[1].Length > 4)
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+                                    }
+                                }
+
+                                if (values[1].EndsWith("村委会"))
+                                {
+                                    //if (values[1].Length > 4)
+                                    //{
+                                    //    tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+                                    //}
+                                    tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
+
+                                }
+
+                                if (values[1].EndsWith("居民委员会"))
+                                {
+                                    //if (values[1].Length > 6)
+                                    //{
+                                    //    tree.AddWord(values[1].Substring(0, values[1].Length - 5), values[0] + values[1]);
+                                    //}
+                                }
+
+                                break;
+                            default:
+                                break;
+                        }
+                        //tree.AddWord(values[1],values[0]);
+                    }
+                }
+
+                tree.AddWord("工业园区", "320576000000苏州工业园区");
+                tree.AddWord("高新区", "320505000000虎丘区");
+                tree.AddWord("科技城", "320505000000虎丘区");
+                tree.AddWord("芙蓉村", "320412106003芙蓉社区居委会(含芙蓉村村委)");
+                tree.AddWord("芙蓉社区", "320412106003芙蓉社区居委会(含芙蓉村村委)");
+                tree.AddWord("襄樊", "420600000000襄阳市");
+                tree.AddWord("襄樊市", "420600000000襄阳市");
+                tree.AddWord("四方区", "370203000000市北区");
+
+                Console.WriteLine(DateTime.Now);
+                tree.Save(filePath);
+            }
+
+            
+
+        }
+        public List<string>? Paser(string address)
+        {
+            List<List<string>> list = new List<List<string>>();
+            int i = 0;
+            bool shenAdded = false;
+            bool shiAdded = false;
+            bool quxianAdded = false;
+            
+            while (i < address.Length)
+            {
+                int temIndex = 0;
+                treeNode treeNode = tree.maxPrif(address.Substring(i), out temIndex);
+                if (treeNode != null)
+                {
+                    //list.Add(treeNode.EndValues);
+                    //Console.WriteLine($"{address.Substring(i,temIndex)},{i},{temIndex + i}");
+                    foreach (string key in treeNode.EndValues)
+                    {
+                        string strId = key.Substring(0,12);
+                        if (strId.EndsWith("0000000000"))
+                        {
+                            if (!shenAdded)
+                            {
+                                addkeyToResult(key, list);
+                                shenAdded = true;
+                            }
+                            continue;
+                        }
+
+                        if (strId.EndsWith("00000000") )
+                        {
+                            if (!shiAdded)
+                            {
+                                addkeyToResult(key, list);
+                                shiAdded = true;
+                            }
+                            continue;
+                        }
+
+                        //if (strId.EndsWith("000000"))
+                        //{
+                        //    if (!quxianAdded)
+                        //    {
+                        //        addkeyToResult(key, list);
+                        //        quxianAdded = true;
+                        //    }
+                        //    continue;
+                        //}
+
+                        addkeyToResult(key, list);
+
+                        //Console.WriteLine($"\t{key}");
+                    }
+                    i = i+ temIndex;
+                }
+
+                i++;
+            }
+
+            
+            List<string>? retList = null;
+
+            //int maxLength =0;
+            //foreach (List<string> strings in list)
+            //{
+            //    if(strings.Count > maxLength && IncludeShenShi(strings))
+            //    {
+            //        maxLength = strings.Count; 
+
+            //        retList = strings;
+            //    }
+            //}
+
+
+
+
+            double maxResult =0;
+            foreach (List<string> strings in list)
+            {
+                double temResult = CalResult(strings);
+                if(temResult > maxResult)
+                {
+                    maxResult = temResult;
+                    retList = strings;
+                }
+            }
+
+            if (retList != null)
+            {
+                retList.Sort();
+            }
+
+
+            return tree.formatAddress(retList);
+        }
+
+        private double CalResult(List<string> list)
+        {
+            double result = 0;
+            foreach (string str in list)
+            {
+                string value = str.Substring(0, 12);
+                if (value.EndsWith("0000000000"))
+                {
+                    result += 1.2;
+                }
+                else
+                {
+                    if (value.EndsWith("00000000"))
+                    {
+                        result += 1.1;
+                    }
+                    else
+                    {
+                        if (value.EndsWith("000000"))
+                        {
+                            result += 0.9;
+                        }
+                        else
+                        {
+                            if (value.EndsWith("000"))
+                            {
+                                result += 0.6;
+                            }
+                            else
+                            {
+                                result += 0.4;
+                            }
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+
+        private bool IncludeShenShi(List<string> strings)
+        {
+            foreach (string key in strings)
+            {
+                string value = key.Substring(0, 12);
+                if(value.EndsWith("0000000000") || value.EndsWith("00000000"))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        
+        public bool Search(string str)
+        {
+            return tree.Search(str, out _);
+        }
+
+        private void addkeyToResult(string key, List<List<string>> list)
+        {
+            if(list != null)
+            {
+                if (list.Count > 0) { 
+                    bool isAdded = false;
+                    List<List<string>> strings1 = new List<List<string>>();
+                    
+                    foreach (List<string> item in list)
+                    {
+                        List<string> tempList = new List<string>();
+                        foreach (string key2 in item)
+                        {
+                            if(isSub(key2, key))
+                            {
+                                if (!tempList.Contains(key2))
+                                {
+                                    tempList.Add(key2);
+                                }
+                            }
+                        }
+
+                        if (tempList.Count > 0)
+                        {
+                            if (tempList.Count == item.Count)
+                            {
+                                if (!item.Contains(key))
+                                {
+                                    item.Add(key);
+                                }
+
+                                isAdded = true;
+                                break;
+
+                            }
+                            else
+                            {
+                                tempList.Add(key);
+                                strings1.Add(tempList);
+                                //isAdded = true;
+                            }
+
+                            
+                        }
+                        
+
+                    }
+
+                    if (!isAdded)
+                    {
+                        if (strings1.Count > 0)
+                        {
+                            List<string> strings2 = new List<string>();
+                            int lstLength = 0;
+                            foreach(List<string> lst in strings1)
+                            {
+                                if (lstLength < lst.Count)
+                                {
+                                    lstLength = lst.Count;
+                                    strings2 = lst;
+                                }
+                            }
+
+                            list.Add(strings2);
+                        }
+                        else
+                        {
+                            List<string> strings = new List<string>() { key };
+                            list.Add(strings);
+                        }
+                            
+                    }
+                }
+                else
+                {
+                    List<string> strings = new List<string>() { key};
+                    list.Add(strings);
+                }
+            }
+            else
+            {
+                throw new Exception("list不能未空!");
+            }
+        }
+
+        private bool isSub(string key2, string key)
+        {
+            if (key2 != null && key != null)
+            {
+                string s1 = TrimRightZero(key2.Substring(0, 12));
+                string s2 = TrimRightZero(key.Substring(0, 12));
+
+                return (s1.StartsWith(s2) || s2.StartsWith(s1));
+            }
+
+            return false;
+        }
+
+        private string TrimRightZero(string str)
+        {
+            if (string.IsNullOrEmpty(str))
+            {
+                return str;
+            }
+            else
+            {
+                string str1= str.Substring(0, 2);
+                string str2 = str.Substring(2, 2);
+                string str3 = str.Substring(4, 2);
+                string str4 = str.Substring(6, 3); 
+                string str5 = str.Substring(9, 3);
+
+                if (str5 != "000")
+                {
+                    return str1 + str2 +str3 +str4 + str5;
+                }
+                else
+                {
+                    if(str4 != "000")
+                    {
+                        return str1+str2 +str3 +str4 ;
+                    }
+                    else
+                    {
+                        if(str3 != "00")
+                        {
+                            return str1 + str2 + str3 ;
+                        }
+                        else
+                        {
+                            if(str2 != "00")
+                            {
+                                return str1 + str2 ;
+                            }
+                            else
+                            {
+                                return str1 ;
+                            }
+                        }
+                    }
+                }
+                //for (int i = str.Length - 1; i >= 0; i--)
+                //{
+                //    if (str[i] != '0')
+                //    {
+                //        return str.Substring(0, i+1);
+                //    }
+                //}
+
+                //return "";
+            }
+        }
+    }
+}

+ 37 - 0
trieTree.xiaoshi.sz.com.sln

@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35013.160
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "testtrieTree", "testtrieTree\testtrieTree.csproj", "{15149D47-A288-4211-84D2-963F1967B55E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "trieTree", "trieTree\trieTree.csproj", "{1BF5913A-0217-44E0-8B6E-7A30687FEBF2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPRS.xiaoshi.sz.com", "IPRS.xiaoshi.sz.com\IPRS.xiaoshi.sz.com.csproj", "{3728188A-69C0-47FB-A97F-E64774AC9A05}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{15149D47-A288-4211-84D2-963F1967B55E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{15149D47-A288-4211-84D2-963F1967B55E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{15149D47-A288-4211-84D2-963F1967B55E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{15149D47-A288-4211-84D2-963F1967B55E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1BF5913A-0217-44E0-8B6E-7A30687FEBF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1BF5913A-0217-44E0-8B6E-7A30687FEBF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1BF5913A-0217-44E0-8B6E-7A30687FEBF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1BF5913A-0217-44E0-8B6E-7A30687FEBF2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {15068A00-C0C8-4C86-8A55-E833A1B37A6B}
+	EndGlobalSection
+EndGlobal

+ 213 - 0
trieTree/CompressHelper.cs

@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Compression;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace trieTree.xiaoshi.sz.com
+{
+    public class MemoryStreamStack
+    {
+        private Stack<MemoryStream>? _streams = null;
+
+        public MemoryStreamStack() : this(100)
+        {
+
+        }
+
+        public MemoryStreamStack(int capacity)
+        {
+            _streams = new Stack<MemoryStream>(capacity);
+        }
+
+        public MemoryStream GetMemoryStream()
+        {
+            MemoryStream? stream = null;
+            if (_streams.Count > 0)
+            {
+                lock (_streams)
+                {
+                    if (_streams.Count > 0)
+                    {
+                        stream = (MemoryStream)_streams.Pop();
+                    }
+                }
+            }
+            if (stream == null)
+            {
+                stream = new MemoryStream(0x800);
+            }
+            return stream;
+        }
+
+
+        public void ReleaseMemoryStream(MemoryStream stream)
+        {
+            if (stream == null)
+            {
+                return;
+            }
+            stream.Position = 0L;
+            stream.SetLength(0L);
+            lock (_streams)
+            {
+                _streams.Push(stream);
+            }
+        }
+
+        ~MemoryStreamStack()
+        {
+            foreach (MemoryStream memory in _streams)
+            {
+                memory.Dispose();
+            }
+            _streams.Clear();
+            _streams = null;
+        }
+
+
+
+    }
+
+    public static class CompressHelper
+    {
+        private readonly static MemoryStreamStack MemoryStreamStacker = new MemoryStreamStack();
+        public static string CompressBytesToBase64String(byte[] buffer)
+        {
+            if (buffer == null || buffer.Length == 0)
+            {
+                return "";
+            }
+            byte[] compressedData = CompressBytes(buffer);
+            return System.Convert.ToBase64String(compressedData, 0, compressedData.Length);
+        }
+
+        public static string ConvertBytesToBase64String(byte[] buffer)
+        {
+            if (buffer == null || buffer.Length == 0)
+            {
+                return "";
+            }
+            return System.Convert.ToBase64String(buffer, 0, buffer.Length);
+        }
+
+        public static byte[] ConvertBase64StringToBytes(string deCompressString)
+        {
+            if (string.IsNullOrEmpty(deCompressString))
+            {
+                return new byte[0];
+            }
+            byte[] buffer = System.Convert.FromBase64String(deCompressString);
+            return buffer;
+        }
+
+
+        public static byte[] DeCompressBase64StringToBytes(string deCompressString)
+        {
+            if (string.IsNullOrEmpty(deCompressString))
+            {
+                return new byte[0];
+            }
+            byte[] buffer = System.Convert.FromBase64String(deCompressString);
+
+            byte[] ret = DeCompressBytes(buffer);
+            return ret;
+        }
+
+
+        public static byte[] CompressBytes(byte[] buffer)
+        {
+            if (buffer == null || buffer.Length == 0)
+            {
+                return buffer;
+            }
+            byte[] compressedData;
+            MemoryStream ms = MemoryStreamStacker.GetMemoryStream();
+            try
+            {
+                using (DeflateStream compressedzipStream = new DeflateStream(ms, CompressionMode.Compress, true))
+                {
+                    compressedzipStream.Write(buffer, 0, buffer.Length);
+                }
+                ms.SetLength(ms.Position);
+                //如果得到的结果长度比原来还大,则不需要压宿,返回原来的,并带上一位标识数据是否已压宿过
+                if (ms.Length >= buffer.Length)
+                {
+                    compressedData = new byte[buffer.Length + 1];
+                    buffer.CopyTo(compressedData, 0);
+                    compressedData[compressedData.Length - 1] = 0;
+                }
+                else
+                {
+                    compressedData = new byte[ms.Length + 1];
+                    ms.ToArray().CopyTo(compressedData, 0);
+                    compressedData[compressedData.Length - 1] = 1;
+                }
+                //ms.Close();
+            }
+            finally
+            {
+                MemoryStreamStacker.ReleaseMemoryStream(ms);
+            }
+            return compressedData;
+        }
+
+
+
+        private static MemoryStream DeCompressMemoryToMemory(MemoryStream ms)
+        {
+            MemoryStream data = MemoryStreamStacker.GetMemoryStream();
+            using (DeflateStream zipStream = new DeflateStream(ms, CompressionMode.Decompress))
+            {
+                byte[] writeData = new byte[8192];
+                // Use the ReadAllBytesFromStream to read the stream.
+                while (true)
+                {
+                    int size = zipStream.Read(writeData, 0, writeData.Length);
+                    if (size > 0)
+                    {
+                        data.Write(writeData, 0, size);
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+            }
+            return data;
+        }
+
+
+        public static byte[] DeCompressBytes(byte[] buffer)
+        {
+            if (buffer == null || buffer.Length <= 0)
+            {
+                return buffer;
+            }
+            byte[] bytes = new byte[buffer.Length - 1];
+            Array.Copy(buffer, bytes, bytes.Length);
+
+            //如果最后一位是0,说明没有被压宿,那么也不需要解压速
+            if (buffer[buffer.Length - 1] == 0)
+            {
+                return bytes;
+            }
+            using (MemoryStream ms = new MemoryStream(buffer))
+            {
+                MemoryStream stream = null;
+                try
+                {
+                    stream = DeCompressMemoryToMemory(ms);
+                    stream.SetLength(stream.Position);
+                    bytes = stream.ToArray();
+                }
+                finally
+                {
+                    MemoryStreamStacker.ReleaseMemoryStream(stream);
+                }
+            }
+            return bytes;
+        }
+    }
+}

+ 75 - 0
trieTree/DataContractFormatSerializer.cs

@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace trieTree.xiaoshi.sz.com
+{
+    public static class DataContractFormatSerializer
+    {
+        public static string SerializeToBase64String<T>(T obj, bool compress)
+        {
+            byte[] ret = Serialize<T>(obj, compress);
+            return Convert.ToBase64String(ret);
+        }
+
+
+        public static byte[]? Serialize<T>(T obj, bool compress)
+        {
+            if (obj == null)
+            {
+                return null;
+            }
+            byte[] info;
+            using (MemoryStream stream = new MemoryStream())
+            {
+                DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
+                using (XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(stream))
+                {
+                    serializer.WriteObject(binaryDictionaryWriter, obj);
+                    binaryDictionaryWriter.Flush();
+                }
+                info = stream.ToArray();
+                if (compress)
+                {
+                    info = CompressHelper.CompressBytes(info);
+                }
+            }
+            return info;
+        }
+
+        public static T DeserializeFromBase64String<T>(string baseString, bool decompress)
+        {
+            if (String.IsNullOrEmpty(baseString))
+                return default(T);
+
+            byte[] buffer = Convert.FromBase64String(baseString);
+            return Deserialize<T>(buffer, decompress);
+        }
+
+        public static T Deserialize<T>(byte[] info, bool decompress)
+        {
+            T ret = default(T);
+            if (info == null || info.Length <= 0)
+            {
+                return ret;
+            }
+            if (decompress)
+            {
+                info = CompressHelper.DeCompressBytes(info);
+            }
+            using (MemoryStream stream = new MemoryStream(info))
+            {
+                DataContractSerializer serializer = new DataContractSerializer(typeof(T));
+                using (XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
+                {
+                    ret = (T)serializer.ReadObject(binaryDictionaryReader);
+                }
+            }
+            return ret;
+        }
+    }
+}

+ 35 - 0
trieTree/treeNode.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace trieTree.xiaoshi.sz.com
+{
+    [DataContract]
+    public class treeNode
+    {
+        public treeNode() {
+            children = new Hashtable();
+        }
+
+        public treeNode(char v) {
+            value = v;
+            children = new Hashtable();
+        }
+
+        [DataMember]
+        public char value { get; set; }
+
+        [DataMember]
+        public Hashtable children { get; set; }
+
+        [DataMember]
+        public bool isEnd { get; set; }
+
+        [DataMember]
+        public List<String> EndValues { get; set; }
+    }
+}

+ 184 - 0
trieTree/trieTree.cs

@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Text.Json;
+using System.Threading.Tasks;
+using System.Collections;
+
+namespace trieTree.xiaoshi.sz.com
+{
+    public class trieTree
+    {
+        treeNode root = new treeNode();
+        Hashtable keyAddress = new Hashtable();
+
+        public void AddWord(string word,string Key)
+        {
+            treeNode temNode = root;
+            for (int i = 0; i < word.Length; i++)
+            {
+                if (temNode != null && temNode.children.ContainsKey(word[i]))
+                {
+                    temNode = (treeNode)temNode.children[word[i]];
+                }
+                else
+                {
+                    treeNode treeNode = new treeNode(word[i]);
+                    temNode.children.Add(word[i], treeNode);
+                    temNode = treeNode;
+                }
+            }
+
+            temNode.isEnd = true;
+            if (temNode.EndValues == null)
+            {
+                temNode.EndValues = new List<string>();
+            }
+
+            if (!temNode.EndValues.Contains(Key))
+            {
+                temNode.EndValues.Add(Key);
+            }
+
+            if (!keyAddress.ContainsKey(Key.Substring(0,12)))
+            {
+                keyAddress.Add(Key.Substring(0,12),word);
+            }
+        }
+
+        public bool Search(string word,out List<string> key)
+        {
+            key = null;
+            treeNode temNode = root;
+            for (int i = 0; i < word.Length; i++)
+            {
+                if (temNode != null && temNode.children.ContainsKey(word[i]))
+                {
+                    temNode = (treeNode)temNode.children[word[i]];
+                }
+                else
+                {
+                    return false;
+                }
+            }
+
+            if (temNode != null)
+            {
+                if (temNode.isEnd)
+                {
+                    key = temNode.EndValues;
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                return false ;
+            }
+        }
+
+        /// <summary>
+        /// 词库中最长匹配
+        /// </summary>
+        /// <param name="word"></param>
+        /// <returns></returns>
+        public treeNode maxPrif(string word,out int index)
+        {
+            treeNode retNode = null;
+            index = -1;
+            treeNode temNode = root;
+            for (int i = 0; i < word.Length; i++)
+            {
+                if (temNode != null && temNode.children.ContainsKey(word[i]))
+                {
+                    temNode = (treeNode)temNode.children[word[i]];
+                    if(temNode.isEnd)
+                    {
+                        retNode = temNode;
+                        index = i;
+                    }
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            return retNode;
+
+
+        }
+
+        public void Save(string filePath)
+        {
+            
+            using (FileStream stream = new FileStream(filePath, FileMode.Create))
+            {
+                stream.Write(DataContractFormatSerializer.Serialize<treeNode>(root, true));
+            }
+
+            using (FileStream stream = new FileStream(filePath+".key", FileMode.Create))
+            {
+                stream.Write(DataContractFormatSerializer.Serialize<Hashtable>(keyAddress, true));
+            }
+        }
+
+        public void Load(string filePath)
+        {
+            using (FileStream stream = new FileStream(filePath, FileMode.Open))
+            {
+                byte[] bytes = new byte[stream.Length];
+                stream.Read(bytes, 0, bytes.Length);
+                root = (treeNode)DataContractFormatSerializer.Deserialize<treeNode>(bytes,true);
+            }
+
+            using (FileStream stream = new FileStream(filePath + ".key", FileMode.Open))
+            {
+                byte[] bytes = new byte[stream.Length];
+                stream.Read(bytes, 0, bytes.Length);
+                keyAddress  = (Hashtable)DataContractFormatSerializer.Deserialize<Hashtable>(bytes, true);
+            }
+        }
+
+        public List<string> formatAddress(List<string> list)
+        {
+            List<string> retList = new List<string>();
+
+            if (list != null && list.Count > 0)
+            {
+                string strAddress = list[list.Count - 1];
+                String strKey = strAddress.Substring(0, 12);
+                retList.Add((String)keyAddress[strKey.Substring(0, 2) + "0000000000"]);
+                if (!strKey.EndsWith("0000000000"))
+                {
+                    if (!retList.Contains((String)keyAddress[strKey.Substring(0, 4) + "00000000"]))
+                        retList.Add((String)keyAddress[strKey.Substring(0, 4) + "00000000"]);
+                }
+
+                if (!strKey.EndsWith("00000000")) 
+                {
+                    if (!retList.Contains((String)keyAddress[strKey.Substring(0, 6) + "000000"]))
+                        retList.Add((String)keyAddress[strKey.Substring(0, 6) + "000000"]);
+                }
+
+                if (!strKey.EndsWith("000000"))
+                {
+                    if (!retList.Contains((String)keyAddress[strKey.Substring(0, 9) + "000"]))
+                        retList.Add((String)keyAddress[strKey.Substring(0, 9) + "000"]);
+                }
+
+                if (!strKey.EndsWith("000"))
+                    retList.Add((String)keyAddress[strKey]);
+            }
+            return retList;
+        }
+
+    }
+}

+ 9 - 0
trieTree/trieTree.csproj

@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+</Project>