|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Friday, February 18, 2011 10:54 AM
Points: 54,
Visits: 154
|
|
Hello all. I am trying to write a function which reverses passed string WITHOUT using any built-in functions
So if 'abc' is passed, it returns 'cba'
I want to use recursion. Here is what I got:
create function StringReverse ( @InString varchar(20) ) returns varchar(20) AS begin declare @RevString varchar(20)
IF len(@InString) in (0,1) set @RevString = @InString
ELSE set @RevString = ( dbo.StringReverse(substring(@InString, len(@InString)/2+1, len(@InString)) + dbo.StringReverse(substring(@InString, 1, len(@InString)/2))) ) return @RevString end
It compiles fine, but when I call it, it throws an exception: select dbo.StringReverse('abc')
Msg 217, Level 16, State 1, Line 1 Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
Why? Function calls itself at most 5 times: Pass1 - RevString('c') + RevString('ab') Pass2 - 'c' + (RevString(RevString('b') + RevString('a')) Pass3 - 'cba'
Should I use a loop?
Thanks in advance for your help! Pit
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Today @ 7:44 AM
Points: 11,631,
Visits: 27,699
|
|
yeah, i think you'll need to use a loop from 1 to datalength(@inputstring), and appending the char in reverse order.
recursively calling a string that fiddles with one or two chars is going to hit the issue you already identified, max number of nesting levels.
Lowell
--There is no spoon, and there's no default ORDER BY in sql server either. Actually, Common Sense is so rare, it should be considered a Superpower. --my son
|
|
|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Friday, February 18, 2011 10:54 AM
Points: 54,
Visits: 154
|
|
Hmmm... Does it mean that recursion cannot be used in this example? Or it should be implemented differently?
Thanks, Pit
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Today @ 7:44 AM
Points: 11,631,
Visits: 27,699
|
|
pshvets (4/14/2009) Hmmm... Does it mean that recursion cannot be used in this example? Or it should be implemented differently?
Thanks, Pit
recursion has it's place, of course, but it does not serve string manipulation very well.
without using a tally table, i'd do it like this: just a simple loop and string concatenation:
ALTER function CharReversal(@inputstring varchar(max)) returns varchar(max) WITH SCHEMABINDING AS BEGIN DECLARE @i int, @Results varchar(max) SET @Results='' SET @i = 1 WHILE @i <= DATALENGTH(@inputstring) BEGIN SET @Results = SUBSTRING(@inputstring,@i,1) + @Results SET @i=@i + 1 END RETURN @Results END
select dbo.CharReversal('abc123xyz') --Results:zyx321cba
Lowell
--There is no spoon, and there's no default ORDER BY in sql server either. Actually, Common Sense is so rare, it should be considered a Superpower. --my son
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Saturday, May 04, 2013 11:13 AM
Points: 9,855,
Visits: 9,374
|
|
Here's the code that I sent to Jacob Sebastian's challenge last month. Minus the two syntax errors that probably eliminated me from consideration (gawd, I need a vacation!):
/* TSQL Challenge #3 Tested on SQL Server 2008 By RBarryYoung, March 28, 2009 */ DECLARE @t TABLE( ID INT IDENTITY, data VARCHAR(MAX)) INSERT INTO @t(data) SELECT 'Jacob' INSERT INTO @t(data) SELECT 'Sebastian'
;WITH cteReverseRecur as ( Select ID , RIGHT( data, 1 ) as RevStr , LEFT( data, LEN([data])-1 ) as RemStr From @t UNION ALL Select ID , RevStr + RIGHT( RemStr, 1 ) , Left( RemStr, LEN(RemStr)-1 ) From cteReverseRecur Where RemStr > '') SELECT ID, RevStr as data From cteReverseRecur Where RemStr = '';
-- RBarryYoung, (302)375-0451 blog: MovingSQL.com, Twitter: @RBarryYoung Proactive Performance Solutions, Inc. "Performance is our middle name."
|
|
|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Friday, February 18, 2011 10:54 AM
Points: 54,
Visits: 154
|
|
Lowell (4/14/2009)
pshvets (4/14/2009) Hmmm... Does it mean that recursion cannot be used in this example? Or it should be implemented differently?
Thanks, Pitrecursion has it's place, of course, but it does not serve string manipulation very well. without using a tally table, i'd do it like this: just a simple loop and string concatenation: ALTER function CharReversal(@inputstring varchar(max)) returns varchar(max) WITH SCHEMABINDING AS BEGIN DECLARE @i int, @Results varchar(max) SET @Results='' SET @i = 1 WHILE @i <= DATALENGTH(@inputstring) BEGIN SET @Results = SUBSTRING(@inputstring,@i,1) + @Results SET @i=@i + 1 END RETURN @Results END
select dbo.CharReversal('abc123xyz') --Results:zyx321cba
Thank you for suggestion. I am still trying to figure out how to use recursion in this example. I am reading Joe Celko's book "Trees and Hierarchies in SQL for Smarties" and trying to write in T-SQL what he wrote for Oracle sql.
Thanks, Pit.
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Saturday, May 04, 2013 11:13 AM
Points: 9,855,
Visits: 9,374
|
|
|
|
|
|
SSCoach
         
Group: General Forum Members
Last Login: Yesterday @ 1:55 PM
Points: 15,442,
Visits: 9,571
|
|
Here's the sampe I came up with.
declare @Str varchar(100), @StrRev varchar(100);
select @Str = 'able was I ere I saw elba';
select @StrRev = coalesce(@StrRev + substring(@Str, number, 1), substring(@Str, number, 1)) from dbo.Numbers where number between 1 and len(@Str) order by number desc;
select @Str, @StrRev;
- Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC Property of The Thread
"Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Today @ 8:17 AM
Points: 2,944,
Visits: 10,506
|
|
pshvets (4/14/2009) Hello all. I am trying to write a function which reverses passed string WITHOUT using any built-in functions
So if 'abc' is passed, it returns 'cba'
I want to use recursion. Here is what I got:
create function StringReverse ( @InString varchar(20) ) returns varchar(20) AS begin declare @RevString varchar(20)
IF len(@InString) in (0,1) set @RevString = @InString
ELSE set @RevString = ( dbo.StringReverse(substring(@InString, len(@InString)/2+1, len(@InString)) + dbo.StringReverse(substring(@InString, 1, len(@InString)/2))) ) return @RevString end
It compiles fine, but when I call it, it throws an exception: select dbo.StringReverse('abc')
Msg 217, Level 16, State 1, Line 1 Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
Why? Function calls itself at most 5 times: Pass1 - RevString('c') + RevString('ab') Pass2 - 'c' + (RevString(RevString('b') + RevString('a')) Pass3 - 'cba'
Should I use a loop?
Thanks in advance for your help! Pit
The requirement of “Reverse string without built in functions” doesn’t make any sense, especially since all of the solutions posted, including yours, use built in functions.
If it’s OK to use the built in DATALENGTH, SUBSTRING, RIGHT, LEFT, or LEN functions, why can’t you just use the built in REVERSE function?
|
|
|
|
|
SSCoach
         
Group: General Forum Members
Last Login: Yesterday @ 1:55 PM
Points: 15,442,
Visits: 9,571
|
|
I had that same point in my original post, but it got lost when my browser crashed mid-post. I think it's just a game to not use Reverse. Quite possibly a homework question, since they are often written with that kind of arbitrary rule.
- Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC Property of The Thread
"Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon
|
|
|
|