程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#中使用指針實現高效比較字符串的小技巧

C#中使用指針實現高效比較字符串的小技巧

編輯:關於C#

判斷隨機字符串之間的是否相等是程序設計中常用的技巧,再C++時代,我們可以通過把字符串中每四個字節轉換為一個int對象,通過int對象一次比較四個字符,從而實現相對高效的字符串比較工作。那麼,這個思路在C#中能否是實現呢?答案是肯定的。

在C#中使用上述思想,必須要解決兩個問題,其一是在C#中使用指針,並且指針指向的托管變量位置不能被GC重新分配。其二,托管字符串在內存中與int或long之間的對應關系。

很多文章中已經詳細描述了在C#中使用指針的方法,本文不再詳細敘述,開啟unsafe開關的方式為,右鍵單擊解決方案目錄——選擇屬性——再Build對話框中選中“允許unsafe代碼”選項, 這樣再C#中就可通過unsafe關鍵字標記可以使用指針的區域了。我們知道,被托管的變量由系統隨機分配、回收和調整在內存中的位置,因此,指向托管變量的指針可能會由於托管變量被隨機調整而指向錯誤區域。為了保證指針自始至終都能指向同一個托管變量,C#中提供了fixed語句來完成該任務。被標記了fixed的指針,在fixed所標志的區域中回自始至終的指向改變量,而系統不會對該托管變量進行調整和再分配。代碼如下:

string str="Hello World!";
unsafe
{
fixed (char* ps = str)
{
//該區域中ps始終指向托管字符串str
}
}

使用sizeof可以測出,C#中long占用8個字節,那麼在上面代碼中如果將ps的前8個字節強轉為long型,得到的結果是什麼呢?我們利用如下代碼進行測試:

long n=0;
long nLow = 0, nHigh = 0;
string str = "Hello World!";
unsafe
{
fixed (char* ps = str)
{
char* psTemp = ps;
n=*(long*)psTemp;
nLow = n & 0xFFFF; //取最後兩個字節
nHigh = (n >> 16) & 0xFFFF; //取第3,4個字節
MessageBox.Show(((char)nLow).ToString() + " " + ((char)nHigh).ToString());
nLow = (n >> 32) & 0xFFFF; //取第5,6個字節
nHigh = (n >> 48) & 0xFFFF; //取第7,8個字節
MessageBox.Show(((char)nLow).ToString() + " " + ((char)nHigh).ToString());
}
}

可以看出,上面MessageBox中的輸出分別為H,e和l,l共4個字符,並非我們直觀上認為的8個字符,這是由於在轉換的過程中,每個字符從byte被轉成為一個2個字節的短整型short而造成的,因此,將字符串指針強轉為long以後,該long型變量的值可以表示4個字符,那麼,比較兩個long型對象的值實際上就是在比較這4個字符的值,采用這個思路,實際上實現了做一次比較操作就能同時比較4個字符。

比較兩字符串是否相等的代碼如下:

protected bool IsEquals(string str1, string str2)
{
bool bRet = true;
int nC1 = 0, nC2 = 0, nLen = 0;
int i = 0;
if (str1.Length != str2.Length) //長度不相等則字符串不相等
{
return false;
}
//長度不是4的倍數則補位
nC1 = ((str1.Length % 4) != 0) ? (4 - str1.Length%4) : 0; //計算補償位
nC2 = ((str2.Length % 4) != 0) ? (4 - str1.Length%4) : 0; //計算補償位
nLen = (nC1 > nC2) ? nC1 : nC2;
for (i = 0; i {
if (i < nC1)
{
str1 += " ";
}
if (i < nC2)
{
str2 += " ";
}
}
unsafe
{
fixed (char* psStr1 = str1) fixed (char* psStr2 = str2)
{
char* psTemp1 = psStr1;
char* psTemp2 = psStr2;
while (i < str1.Length)
{
if (*(long*)psTemp1 != (*(long*)psTemp2)) //一次比較4個字符
{
bRet = false;
break;
}
i += 4;
psTemp1 += 4;
psTemp2 += 4;
}
}
}
return bRet;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved