상당히 많은 해결책이 있기 때문에 나는 당신의 질문의 "비평"부분으로 갈 것입니다. 몇 가지 메모 : 나는 오타를 수정하고 내가 한 곳을 지적했다. 내가 오타가되는 것에 대해 틀렸다면 의견에 언급하고 진행 상황을 설명하겠습니다. 나는 당신이 이미 알고있을 수있는 몇 가지 사항을 지적 할 것이므로, 그렇게한다면 공격하지 마십시오. 일부 의견은 까다로워 보일 수 있지만 여행 중 어디에 있는지 모르므로 처음 시작한다고 가정해야합니다.
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(...))
공백?