成人欧美一区二区三区的电影,日韩一级一欧美一级国产,国产成人国拍亚洲精品,无码人妻精品一区二区三区毛片,伊人久久无码大香线蕉综合

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網站管理員

C# 拼音首字母搜索、字符串編碼、關鍵詞高亮的原理即實現考慮

freeflydom
2025年10月10日 10:24 本文熱度 477

在處理百萬量級條目(如文本名)的搜索時,每一次匹配的效率對提高總搜索時間至關重要。如果在每次檢查文件名與關鍵字時執(zhí)行復雜的操作,會對總時間產生累計影響,進而影響用戶體驗。本文將詳細分享之前 TDS 的文本搜索邏輯,希望能為大家提供一些參考。

一、拼音首字母轉換

考慮字符串“123四五六78abc”,我們的預期是匹配關鍵字[“sw”,“六”]時能分別命中子串[“四五”,“六”]。要獲取漢字的拼音首字母,需要先獲取字符的 Unicode 編碼,在不考慮多音字的情況下,可直接通過查表簡單實現。如果字符處于中文區(qū)間,可直接返回對應的首字母。

從零開始:C# 文件名搜索拼音首字母支持、搜索加速策略與關鍵詞高亮顯示

在處理百萬量級條目(如文本名)的搜索時,每一次匹配的效率對提高總搜索時間至關重要。如果在每次檢查文件名與關鍵字時執(zhí)行復雜的操作,會對總時間產生累計影響,進而影響用戶體驗。本文將詳細分享之前 TDS 的文本搜索邏輯,希望能為大家提供一些參考。

一、拼音首字母轉換

考慮字符串“123四五六78abc”,我們的預期是匹配關鍵字[“sw”,“六”]時能分別命中子串[“四五”,“六”]。要獲取漢字的拼音首字母,需要先獲取字符的 Unicode 編碼,在不考慮多音字的情況下,可直接通過查表實現。如果字符處于中文區(qū)間,可直接返回對應的首字母。具體實現如下:

return iCnChar switch
{
    >= 45217 and <= 45252 => 'A',
    >= 45253 and <= 45760 => 'B',
    >= 45761 and <= 46317 => 'C',
    >= 46318 and <= 46825 => 'D',
    >= 46826 and <= 47009 => 'E',
    >= 47010 and <= 47296 => 'F',
    >= 47297 and <= 47613 => 'G',
    >= 47614 and <= 48118 => 'H',
    >= 48119 and <= 49061 => 'J',
    >= 49062 and <= 49323 => 'K',
    >= 49324 and <= 49895 => 'L',
    >= 49896 and <= 50370 => 'M',
    >= 50371 and <= 50613 => 'N',
    >= 50614 and <= 50621 => 'O',
    >= 50622 and <= 50905 => 'P',
    >= 50906 and <= 51386 => 'Q',
    >= 51387 and <= 51445 => 'R',
    >= 51446 and <= 52217 => 'S',
    >= 52218 and <= 52697 => 'T',
    >= 52698 and <= 52979 => 'W',
    >= 52980 and <= 53688 => 'X',
    >= 53689 and <= 54480 => 'Y',
    >= 54481 and <= 65289 => 'Z',
    _ => throw new ArgumentOutOfRangeException(nameof(iCnChar), iCnChar, null)
};

經過上述轉換,字符串“123四五六78abc”將得到一個新的字符串“123swl78abc”。因此,對源文本的搜索需要對原字符串和拼音串進行兩次匹配。目前嘗試了多個方法,發(fā)現String.Contains的效率最高。StringComparison.OrdinalIgnoreCase 參數是一種快速的字符串比較方式,它忽略大小寫差異,直接比較字符的 Unicode 值,避免了額外的字符轉換操作。使用內置方法可以充分利用底層優(yōu)化,減少不必要的計算,從而提高整體性能。

二、存儲及索引輔助優(yōu)化

拼音首字母預先轉換比實時拼音轉換匹配速度要高效得多,除非存儲空間實在緊張。但多了一個字符串,也意味著多了一次字符串搜索,而字符串搜索是一個較占時間的操作。有沒有辦法繼續(xù)優(yōu)化呢?

(一)模式串

首先建立一個特定長度的char數組作為模式串,以長度為 6 的[“a”,”b”,”c”,”1”,”2”,”3”]為例,這個模式串包含了我們關心的元素。由于我們所有的中文全部映射到了字母的空間,因此這個模式串其實是有限的. 0-9共10個符號加上26個字母以及其他標點一共也不到64個,所以我們可以很方便的用一個64位長度'long'類型存儲編碼.

(二)字符串編碼

以目標文件名“apple 1”為例,我們初始化一個對應模式串長度的二進制位,0_0_0_0_0_0,逐字符掃描時,發(fā)現模式串中a1字符命中,那么我們通過二進制位記錄將得到1_0_0_1_0_0。

以目標文件名“xyz7890”為例,我們初始化一個對應模式串長度的二進制位,0_0_0_0_0_0,逐字符掃描時,發(fā)現模式串均未命中,那么我們通過二進制位記錄將得到0_0_0_0_0_0。

以目標文件名“231cbaa”為例,我們初始化一個對應模式串長度的二進制位,0_0_0_0_0_0,逐字符掃描時,發(fā)現模式串所有字符命中,那么我們通過二進制位記錄將得到1_1_1_1_1_1

有限的二進制位可以方便地用int32int64存儲,已經相當夠用了。這種二進制編碼的方式不僅節(jié)省了存儲空間,還大大提高了搜索效率。布爾運算(如或運算)的速度遠超字符串操作,因為它們直接在內存的位級別上進行操作,而字符串操作則需要逐字符比較和處理。

(三)關鍵詞初篩

以目標文件名“apple 1”為例,此時的二進制位為1_0_0_1_0_0 = 36int值表示)

  • 我們搜索關鍵詞“apel”,與模式串匹配得到關鍵詞的二進制位1_0_0_1_0_0 = 36(十進制)
  • 我們搜索關鍵詞“bpel”,與模式串匹配得到關鍵詞的二進制位0_1_0_1_0_0 = 20(十進制)

對關鍵詞與目標文件名做或運算:

int index_originTxt; // 假設已初始化
int index_keyTxt;    // 假設已初始化
if (index_originTxt | index_keyTxt != index_keyTxt) return "索引初篩失敗";

如果或運算后的值不等于原值,則表示關鍵詞與目標文件名在模式串中存在不包含的字符。

對于多個關鍵詞:

int index_originTxt;  //文件名
int index_keyTxt_1;  // 搜索關鍵字1,假設已初始化
int index_keyTxt_2;  // 搜索關鍵字2,假設已初始化
int index_keyTxt_3;  // 搜索關鍵字3,假設已初始化
int index_keyTxt_final = index_keyTxt_2 | index_keyTxt_3;
if (index_originTxt | index_keyTxt_final != index_keyTxt)
{
    return "索引初篩失敗";
}
else
{
    // ...正常文本搜索
}

intlong的或運算非常輕量,速度遠超string.Contains,且關鍵詞越多,文件名越長,過濾效果越好。這種初篩機制可以快速排除大量不匹配的文件名,從而顯著減少后續(xù)精確匹配的計算量,提高整體搜索效率。

底層技術細節(jié):

  • 初篩機制: 使用位運算進行初篩,可以快速排除大量不匹配的文件名,減少后續(xù)精確匹配的計算量。
  • 性能優(yōu)勢: 位運算的速度極快,適合大規(guī)模數據的快速篩選。

三、關鍵詞高亮(v1.1.7新增)

在 Avalonia 中,文件名的顯示通過 TextBlock 控件實現,其 Inlines 屬性綁定至一個自定義的高亮轉換器.

<TextBlock Inlines="{Binding FileName, Converter={StaticResource HighlightConverter}}" />  

該轉換器類需實現 IValueConverter 接口,由 Avalonia 依賴注入容器自動實例化。其核心方法是 Convert,負責將原始文本按匹配的關鍵詞切分,并構造高亮顯示的 InlineCollection。具體實現如下:

  • 初始化一個 InlineCollection 對象用于存放文本段;
  • 遍歷預處理后的關鍵詞匹配結果(通常需先按起始位置排序,并合并相鄰或重疊區(qū)間);
  • 對非匹配區(qū)域,添加普通 Run 對象顯示文本;
  • 對匹配區(qū)域,創(chuàng)建 Run 對象并設置高亮畫刷(如 Brushes.Yellow)以改變前景色;
  • 需注意多個關鍵詞可能引起的區(qū)間重疊與重復問題,需通過算法(如區(qū)間合并)確保每個字符只處理一次。
// 創(chuàng)建行內元素集合,用于存儲文本元素(Run)
var inlines = new InlineCollection();
// 遍歷所有排序整合后的搜索結果
foreach (var result in results)
{
    // 從原始文本中提取當前片段的子字符串
    // result.Start: 片段起始位置
    // result.Length: 片段長度
    var textSegment = nameOrigin.Substring(result.Start, result.Length);
    
    // 創(chuàng)建文本元素(Run),用于顯示文本片段
    var run = new Run(textSegment);
    // 如果當前片段是匹配項,則應用高亮樣式
    // result.IsMatch: 標識該片段是否為搜索匹配項
    if (result.IsMatch) 
    {
        // 設置前景色為高亮畫刷,突出顯示匹配文本
        run.Foreground = highlightBrush;
        
        // 可選:添加其他高亮樣式,如加粗、背景色等
        // run.FontWeight = FontWeight.Bold;
        // run.Background = Brushes.Yellow;
    }
    // 將文本運行添加到行內集合中
    inlines.Add(run);
}
// 返回構建完成的行內元素集合
// 該集合可在Avalonia TextBlock等控件中直接使用,顯示帶有高亮效果的文本
return inlines;

需要注意的是,多個關鍵詞高亮后,需要對substring的區(qū)域進行重排以及去重/結合。這種設計不僅保證了高亮顯示的準確性,還避免了重復處理同一段文本,從而提高了渲染效率。通過這種方式,用戶可以清晰地看到搜索關鍵詞在文本中的位置,提升了用戶體驗。

所有的Converter都是在虛擬模式下按需執(zhí)行的,可以較好滿足我們的性能需求.

四、最后

對于TDS搜索軟件的其他信息信息可見此公眾號的文章 https://mp.weixin.qq.com/s/inD-brKhii57UJnCYLgxKQ

目前關于TDS搜索的版本已經更新到了1.1.7, 優(yōu)化了很多細節(jié),增加了高亮,磁盤緩存索引,更多選項等一些功能. 歡迎大家拿走,分享,使用.

如果你對這款工具有任何建議或想法,歡迎隨時交流!項目已在 GitHub 完全開源.
如果你覺得有用,歡迎點個 Star ??支持一下! https://github.com/LdotJdot/TDS

?轉自https://www.cnblogs.com/luojin765/p/19100717


該文章在 2025/10/10 10:24:14 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結合碼頭的業(yè)務特點,圍繞調度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved