Technical Article

Show solving arithmetic expression step by step

,

I had a script to randomly generate arithmetic expressions for my 9-year old daughter's exercise (only +-*/ involved). Now she is asking for the step-by-step answers, mainly for showing how to handle the parenthesis, like the following:

2-(2-(-3)-(-2+5*(4-2)-2)*2-(4-2)*2+1)-(5*4-(6/3-1)+77/11)+22

=2-(2+3-(-2+5*2-2)*2-2*2+1)-(5*4-1+77/11)+22

=2-(2+3-6*2-2*2+1)-26+22

=2+10-26+22

=8

I create a script for this using  a recursion procedure, and assuming that the input are always valid expressions. The script includes a helper function which is always in my toolbox (to split a string into list table), and a procedure to return the answer as the output parameter. Example is alos provided at the end of the script. Hope you enjoy.

Create function [dbo].[sp_split] (@ListString nvarchar(max), @Delimiter nvarchar(10), @IncludeEmpty int)

Returns @ListTable TABLE (ID int, ListValue nvarchar(max))
AS
BEGIN
    Declare @CurrentPosition int, @NextPosition int, @Item nvarchar(max), @ID int, @L int
    Select @ID = 1,
   @L = len(replace(@Delimiter,' ','^')),
            @ListString = @ListString + @Delimiter,
            @CurrentPosition = 1

    Select @NextPosition = Charindex(@Delimiter, @ListString, @CurrentPosition)
   While @NextPosition > 0 Begin

   Set  @Item = LTRIM(RTRIM(SUBSTRING(@ListString, @CurrentPosition, @NextPosition-@CurrentPosition)))
   If      @IncludeEmpty=1 or LEN(@Item)>0 Begin 
     Insert Into @ListTable (ID, ListValue) Values (@ID, @Item)
     Set @ID = @ID+1
   End
   Set  @CurrentPosition = @NextPosition+@L
   Set  @NextPosition = Charindex(@Delimiter, @ListString, @CurrentPosition)

  End
    RETURN
END
go
Create procedure ShowSteps ( 
@ex varchar(1000), 
@isDecimal int,
@result varchar(2000)  OUTPUT ) 
as begin
set nocount on
declare @ex1 varchar(1000), @sql varchar(max), @r varchar(2000)
if @isDecimal = 1 select@ex = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@ex, '-','-1.00~'), '+','+1.00~'), '*','*1.00~'),'/','/1.00/'), '~','*')
select@ex = REPLACE(REPLACE(REPLACE(@ex,' ',''), '(','#('),')',')#')
select @result = ISNULL(@result, ''), @sql ='', @r=''
create table #t (id int, s varchar(1000))
insert into #t select * from dbo.sp_split(@ex,'#',0)
select @sql=@sql+';update #t set s = convert(varchar(1000), '+s+') where ID ='+convert(varchar, id) from #t where s like '(%)'
if len(@sql)<1 begin
select @sql = ';update #t set s = convert(varchar(1000), '+s+') where ID = 1' from #t 
end
exec (@sql)
select @ex = ''
select @ex = @ex+ convert(varchar(1000), s) from #t order by ID
select @ex = REPLACE(@ex, '--','+')
drop table #t
select @result = @result+'='+ @ex+CHAR(13)+CHAR(10)
if CHARINDEX('-',REPLACE(REPLACE(REPLACE(@ex, '+','-'),'*','-'),'/','-'),2)>0 Begin
exec ShowSteps  @ex, @isDecimal,@r OUTPUT
end
select @result = @result +@r
end

go 

declare @ex varchar(1000), @r nvarchar(max)
select @ex = '2-(2-(-3)-(-2+5*(4-2)-2)*2-(4-2)*2+1)-(5*4-(6/3-1)+77/10)+22'
exec ShowSteps @ex,0,@r output 
select @ex+char(13)+char(10)+@r

Rate

4.4 (5)

You rated this post out of 5. Change rating

Share

Share

Rate

4.4 (5)

You rated this post out of 5. Change rating