상당히 많은 해결책이 있기 때문에 나는 당신의 질문의 "비평"부분으로 갈 것입니다. 몇 가지 메모 : 나는 오타를 수정하고 내가 한 곳을 지적했다. 내가 오타가되는 것에 대해 틀렸다면 의견에 언급하고 진행 상황을 설명하겠습니다. 나는 당신이 이미 알고있을 수있는 몇 가지 사항을 지적 할 것이므로, 그렇게한다면 공격하지 마십시오. 일부 의견은 까다로워 보일 수 있지만 여행 중 어디에 있는지 모르므로 처음 시작한다고 가정해야합니다.
CREATE function Palindrome (
@String Char
, @StringLength Int
, @n Int
, @Palindrome BIN
, @StringLeftLength Int
항상 길이는 char또는 varchar정의를 포함합니다 . Aaron Bertrand 는 여기서 자세히 이야기합니다 . 그는 이야기하고 varchar있지만 같은 것입니다 char. varchar(255)상대적으로 짧은 문자열 만 원하거나 varchar(8000)큰 문자열 또는 심지어 는 문자열을 원할 경우 이것을 사용합니다 varchar(max). Varchar가변 길이 문자열 char은 고정 문자열 전용입니다. 사용중인 문자열의 길이를 확실하지 않기 때문에 varchar. 또한 binary아닙니다 bin.
다음으로 모든 변수를 매개 변수로 넣을 필요는 없습니다. 코드 내에서 선언하십시오. 전달할 계획 인 경우에만 매개 변수 목록에 무언가를 넣으십시오. (이것이 마지막에 어떻게 보이는지 볼 것입니다.) 또한 @StringLeftLength가 있지만 절대 사용하지 마십시오. 그래서 나는 그것을 선언하지 않을 것입니다.
다음으로해야 할 일은 몇 가지 사항을 명확하게하기 위해 조금 다시 포맷하는 것입니다.
BEGIN
SET @n=1
SET @StringLength = Len(@String) -- Missed an @
WHILE @StringLength - @n >1
IF Left(@String,@n)=Right(@String, @StringLength) -- More missing @s
SET @n = @n + 1 -- Another missing @
SET @StringLength = @StringLength - 1 -- Watch those @s :)
RETURN @Palindrome = 1 -- Assuming another typo here
ELSE
RETURN @Palindrome =0
END
들여 쓰기를 수행 한 방식을 보면 내가 이것을 가지고 있음을 알 수 있습니다.
WHILE @StringLength - @n >1
IF Left(@String,@n)=Right(@String, @StringLength)
SET @n = @n + 1
그 이유는 명령 이 첫 번째 코드 줄 WHILE과 같고 IF영향을 받기 때문 입니다. BEGIN .. END여러 명령을 원할 경우 블록 을 사용해야 합니다. 그래서 우리가 얻는 고정 :
WHILE @StringLength - @n > 1
IF Left(@String,@n)=Right(@String, @StringLength)
BEGIN
SET @n = @n + 1
SET @StringLength = @StringLength - 1
RETURN @Palindrome = 1
END
ELSE
RETURN @Palindrome = 0
에 BEGIN .. END블록 만 추가 한 것을 알 수 IF있습니다. 그이기 때문에 비록 IF문은 여전히합니다 (수행 모든 것을 포괄하는 하나의 명령문 긴 여러 줄입니다 (심지어 여러 명령을 포함) IF와 ELSE문장의 일부).
다음에 두 가지 후에 오류가 발생합니다 RETURNs. 변수 또는 리터럴을 반환 할 수 있습니다. 변수를 설정하고 동시에 반환 할 수 없습니다.
SET @Palindrome = 1
END
ELSE
SET @Palindrome = 0
RETURN @Palindrome
이제 우리는 논리에 있습니다. 먼저 사용하고있는 LEFT및 RIGHT기능이 훌륭 하다는 것을 지적 하지만 요청 된 방향에서 전달하는 문자 수를 알려줍니다. "test"라는 단어를 전달했다고 가정 해 봅시다. 첫 번째 패스에서 이것을 얻습니다 (변수 제거).
LEFT('test',1) = RIGHT('test',4)
t = test
LEFT('test',2) = RIGHT('test',3)
te = est
분명히 그것은 당신이 기대 한 것이 아닙니다. 당신은 정말로 substring대신 에 사용하고 싶을 것입니다. 부분 문자열을 사용하면 시작 지점뿐만 아니라 길이도 전달할 수 있습니다. 그래서 당신은 얻을 것입니다 :
SUBSTRING('test',1,1) = SUBSTRING('test',4,1)
t = t
SUBSTRING('test',2,1) = SUBSTRING('test',3,1)
e = s
다음으로 IF 문의 한 가지 조건에서만 루프에서 사용하는 변수를 증가시킵니다. 해당 증분에서 변수 증분을 완전히 빼냅니다. 추가 BEGIN .. END블록 이 필요 하지만 다른 블록을 제거해야합니다.
WHILE @StringLength - @n > 1
BEGIN
IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1)
SET @Palindrome = 1
ELSE
SET @Palindrome = 0
SET @n = @n + 1
SET @StringLength = @StringLength - 1
END
WHILE마지막 테스트를 위해 조건 을 변경해야합니다 .
WHILE @StringLength > @n
그리고 마지막으로, 현재 상태는 홀수 개의 문자가있는 경우 마지막 문자를 테스트하지 않습니다. 예를 들어 'ana'를 사용하면 n테스트되지 않습니다. 괜찮습니다. 단어 글자를 설명해야합니다 (긍정적 인 단어로 계산하려면). 값을 미리 설정하면됩니다.
그리고 이제 우리는 마침내 :
CREATE FUNCTION Palindrome (@String varchar(255))
RETURNS Binary
AS
BEGIN
DECLARE @StringLength Int
, @n Int
, @Palindrome binary
SET @n = 1
SET @StringLength = Len(@String)
SET @Palindrome = 1
WHILE @StringLength > @n
BEGIN
IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1)
SET @Palindrome = 1
ELSE
SET @Palindrome = 0
SET @n = @n + 1
SET @StringLength = @StringLength - 1
END
RETURN @Palindrome
END
마지막 의견. 나는 일반적인 형식의 팬입니다. 실제로 코드 작동 방식을 확인하고 실수를 지적하는 데 도움이 될 수 있습니다.
편집하다
Sphinxxx가 언급했듯이 여전히 논리에 결함이 있습니다. 일단 우리를 치고 0으로 ELSE설정 @Palindrome하면 계속할 점이 없습니다. 실제로 그 시점에서 우리는 단지 할 수있었습니다 RETURN.
IF SUBSTRING(@String,@n,1) = SUBSTRING(@String, @StringLength,1)
SET @Palindrome = 1
ELSE
RETURN 0
우리가 현재 @Palindrome"이것은 회문이다"라는 목적으로 만 사용 하고 있다는 점을 감안할 때 실제로 그것을 가질 필요는 없습니다. 변수를 제거 하고 루프를 통과하는 경우에만 논리를 단락 시 ( RETURN 0) 및 RETURN 1(긍정적 응답) 단락으로 전환 할 수 있습니다 . 이것이 실제로 우리의 논리를 다소 단순화한다는 것을 알 수 있습니다.
CREATE FUNCTION Palindrome (@String varchar(255))
RETURNS Binary
AS
BEGIN
DECLARE @StringLength Int
, @n Int
SET @n = 1
SET @StringLength = Len(@String)
WHILE @StringLength > @n
BEGIN
IF SUBSTRING(@String,@n,1) <> SUBSTRING(@String, @StringLength,1)
RETURN 0
SET @n = @n + 1
SET @StringLength = @StringLength - 1
END
RETURN 1
END
LTRIM(RTRIM(...))공백?