[英]Find all combinations
我的老師問一個找到所有組合的算法。 我有一組數據,長度可以變化。 所以組合應該是這樣的:
a
b
c
aa
ab
ac
...
ccbc
ccca
cccb
cccc
它們將存儲在包含單個varchar字段的“單詞”表中。 我這樣做是因為循環,因為我不喜歡遞歸並且jt的性能更好:
DROP PROCEDURE combi;
CREATE PROCEDURE combi
AS
BEGIN
DELETE FROM word
DECLARE @i BIGINT
DECLARE @j INT
DECLARE @word NVARCHAR(24)
DECLARE @str NVARCHAR(62)
DECLARE @combinations BIGINT
DECLARE @currentlength TINYINT
DECLARE @maxcurrentlength TINYINT
SET @maxcurrentlength=4
SET @str='azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789' -- length=62
SET @currentlength=1
-- loop on the length of the text
WHILE @currentlength<=@maxcurrentlength BEGIN
SET @combinations=POWER(62,@currentlength)
SET @i=0
-- get all combinations
WHILE i<@combinations BEGIN
SET @word=''
SET @j=0
-- generate word
WHILE @j<@currentlength BEGIN
SET @word=@word+SUBSTRING(@str, (FLOOR(@i / POWER(62,@currentlength-@j-1) ) % 62) +1, 1)
SET @j=@j+1
END
INSERT INTO word VALUES (@word)
SET @i=@i+1
END
SET @currentlength=@currentlength+1
END
END;
EXEC combi;
問題是當我使用長度為8的服務器時,服務器崩潰了:似乎是POWER(62,@currentlength-@j-1)
了問題。
我對你如何問這個問題有些困惑。 您要求“查找所有組合”,這可以使用CROSS JOIN輕松完成。 如果您需要獲得4的長度,則將具有可用值的表自身連接4次,您已經完成了很多工作。 如果需要在1字段中獲取字符串,則可以在選擇中將它們連接起來。 像這樣:
declare @values table (
value nvarchar(100))
insert @values values ('a'),('b'),('c')
select v1.value+v2.value+v3.value+v4.value
from @values v1 cross join
@values v2 cross join
@values v3 cross join
@values v4
order by v1.value+v2.value+v3.value+v4.value
這是使用遞歸CTE的通用解決方案 :
CREATE TABLE t (i nchar(1))
INSERT INTO t VALUES ('a'),('b'),('c')
;WITH cte AS (
SELECT cast(i AS nvarchar(4000)) AS combo, 1 AS ct
FROM t
UNION ALL
SELECT cte.combo + t.i, ct + 1
FROM cte
CROSS JOIN t
WHERE ct <= 4 -- your maximum length
)
SELECT combo
FROM cte
ORDER BY ct, combo
您必須注意,結果數隨着最大長度的增加而呈指數增長 ,因此,隨着最大長度的增加,性能會迅速下降。
如果需要對其進行參數化,以便可以設置所需的長度,則此算法可以實現,並且它更面向關系數據庫。
declare @characters table (character nchar(1))
declare @words table (word nvarchar(100))
insert @characters values ('a'),('b'),('c')
INSERT @words (word ) VALUEs ('')
DECLARE @Required_length int
DECLARE @length int
SET @Required_length = 4
SET @length = 0
WHILE @length <= @Required_length
BEGIN
SET @length = @length+1
INSERT @words (word )
SELECT w.word + c.character
FROM @words w JOIN @characters c ON LEN(w.word) = @length-1
END
SELECT word from @words where len(word) = @Required_length
您可以通過將長度作為單詞表中的一列包括在內來使其更有效地運行,從而在您按長度進行過濾時無需計算長度,但是由於這是您的老師設置的,我不會為你做所有的工作
首先插入所有字符
SET NOCOUNT ON;
create table ##chars (col char(1))
declare @i int
set @i=65
while @i<=90 /* A-Z */
begin
insert into ##chars values( CHAR(@i))
set @i=@i+1
end
set @i=97
while @i<=122 /* a-z */
begin
insert into ##chars values( CHAR(@i))
set @i=@i+1
end
set @i=48
while @i<=57 /* 0-9 */
begin
insert into ##chars values( CHAR(@i))
set @i=@i+1
end
現在,設置組合編號
create table ##result(word varchar(10))
declare @wide int
set @wide=4 /* set how many combinations are calculated */
insert into ##result select * from ##chars
while @wide>1
begin
begin tran w
insert into ##result select a.word+b.col from ##result a, ##chars b
commit tran w
set @wide=@wide-1
end
select * from ##result
/*
drop table ##chars
drop table ##result
*/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.