導言
由於sql server本身沒提供計算乙個字串在另乙個字串重複次數的函式,大家按照自己的思路使用自定義函式實現了該功能,並在網上傳播。我閱讀了同事從網上獲取的該函式的乙個版本後,便發現該函式存在乙個明顯的邏輯錯誤。為了進一步確認這個問題,我在google上搜尋相關關鍵字,發現該功能多數的實現思路一致,但大多數都存在這個共同的邏輯錯誤。可見從網路上獲取的一些資源,可以作為參考,但要在實際需求中能夠應用,是需要仔細檢查的。
功能實現
常見方法
set ansi_nulls on
goset quoted_identifier on
go --描述:利用迴圈得到乙個字串在另乙個字串中出現的次數
--demo:
-- select dbo.f_getcharcount_false('df ththth','tht')
create function [dbo].[f_getcharcount_false](
@str varchar(8000),
@chr varchar(8000)
) returns int
asbegin
declare @re int,@i int
select @re=0,@i=charindex(@chr,@str)+1
while @i>1
select @re=@re+1
,@str=substring(@str,@i,8000)
,@i=charindex(@chr,@str)+1
return(@re)
end上面的函式設計思路是迴圈截斷源字串,通過計算截斷的次數來獲取子字串出現的重複數。思路當然是可行的,但是在它截斷的時候,起點是@i=charindex(@chr,@str)+1,這裡就是錯誤的起因。以我給出的demo來講,**如下:
select dbo.f_getcharcount_false('df ththth','tht')
結果為2,其實明顯,正確的結果是1。因為上述函式的截斷內容只有「t」,而後面的「ht」會被繼續使用,導致「t」與後面的「ht」組合,結果計數多了一次。正確的擷取位置應該從子串的位置結束處開始,就是從「tht」後面開始。
既然思路正確,那麼我們就修改上述**中的錯誤,修改後的**如下:第1頁:null 第2頁:null 第3頁:null 。
set ansi_nulls on
goset quoted_identifier on
go --描述:利用迴圈得到乙個字串在另乙個字串中出現的次數
--demo:
-- select dbo.f_getcharcount_true('df ththth','tht')
create function [dbo].[f_getcharcount_true](
@str varchar(8000),
@chr varchar(8000)
) returns int
asbegin
declare @re int,@i int
select @re=0,@i=charindex(@chr,@str)+1
while @i>1
select @re=@re+1
,@str=substring(@str,@i-1+len(@chr),8000)
,@i=charindex(@chr,@str)+1
return(@re)
end當然,截斷字串很多人喜歡用stuff填充空字元,但網上流傳的該版本,用stuff函式實現截斷操作的,多數也是存在這個截斷位置錯誤的。
優化的方法
上面講的只是在網路上流傳最廣泛的方法,那麼想要精煉**,尋找更便捷和高效的方法也是可行。下面再介紹兩種較便捷的實現方式。
《方法一》
set ansi_nulls on
goset quoted_identifier on
go /*
描述:利用字串長度計算字元出現次數
demo:
select dbo.f_get_char_repeat_count('df ththth','tht')
*/create function [dbo].[f_get_char_repeat_count]
(@str varchar(8000),
@substr varchar(8000)
)returns int
begin
return (len(@str)-len(replace(@str,@substr,'')))/len(@substr)
end第1頁:null 第2頁:null 第3頁:null 。
《方法二》
set ansi_nulls on
goset quoted_identifier on
go /*
描述:利用長度差值求重複次數
demo:
select fn_get_char_repeat_count_by_add_char('ahahaahde','ah')
*/create function [dbo].[fn_get_char_repeat_count_by_add_char](
@str varchar(8000),--父串
@chr varchar(8000) --子串
) returns int
asbegin
return(len(replace(@str,@chr,@chr+' '))-len(@str))
end上面的《方法一》是用空字元替換父字串中出現的子串,用剩餘字串的長度與子字串的長度求商;《方法二》是把為父字串中出現子字串的地方都增加個空格,用替換後的父字串長度減去原父字串的長度。
本文**:http://www.techrss.cn/html/2008/03-30/78902.htm
統計子串在主串中出現的次數
思路 定義兩個指標p,q p指向主串首位址,q指向子串首位址。如果對應的字元相等,那麼 p,q,即兩個指標都向後移乙個單位再繼續比較 p和 q,否則q回到子串的首位址,只把指標p向後移動乙個單位。依次類推,如果 q 0 說明子串已經終止,子串在主串中出現的次數加1,直到主串終止為止。includei...
java獲取子串在整串中出現的次數
方法一 這是bxdteacher的方法 package stringclass 2,乙個子串在整串 現的次數。nbaernbatynbauinbaopnba 思路 1,要找的子串是否存在,如果存在獲取其出現的位置。這個可以使用indexof完成。2,如果找到了,那麼就記錄出現的位置並在剩餘的字串中繼...
求子串在母串中最後一次出現的位址
給定程式中函式fun的功能是 求出在字串中最後一次出現的子字串的位址,通過函式值返回,在主函式中輸出從此位址開始的字串 若未找到,則函式值為null。char fun char s,char t 其中 s 和 t 是使用者傳入的引數。函式求 t 指標所指的字串在s指標所指的字串中最後一次出現的位址,...