View previous topic :: View next topic |
Author |
Message |
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Sun Oct 09, 2016 1:56 am Post subject: Reverse order a string? |
|
|
Before I reinvent the wheel, is there a function or other easy way to reverse the order of a string?
(BASCOM-AVR version : 2.0.7.9 , Latest : 2.0.7.8 ) |
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Sun Oct 09, 2016 4:40 pm Post subject: |
|
|
well I think you have to reinvent the wheel
do two arrays , and sort them.
JP |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Sun Oct 09, 2016 6:00 pm Post subject: |
|
|
Well... I ended up writing a simple function that does the job:
Code: | Function RevString(ByVal Number As String) As String
Local A As Byte
Local TempChar As String * 1
Local ByteString As String * 32
'the following block reverses the string so MSB becomes LSB
ByteString = ""
For A = 1 to 32
TempChar = Mid(Number , A , 1 )
ByteString = TempChar + ByteString
Next
RevString = ByteString
End Function |
|
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Sun Oct 09, 2016 11:04 pm Post subject: |
|
|
Certainly works, but the string concatenation function is pretty slow, mostly because it has to find the last character in the extended string, and add a null on the end there.
The MID function can be used to do this bit too,
from the Help:
The MID function returns part of a string (a sub string).
The MID statement replaces part of a string variable with another string.
Syntax
var = MID(var1 ,st [, l] )
MID(var ,st [, l] ) = var1
Even better, is that the tempchar can be defined as a byte, rather than a string, so it too does not need to have a null tacked on its end each time.
So you can do:
Code: |
dim tempchar as byte
dim btemp as byte
btemp = 32
For A = 1 to 32
TempChar = Mid(Number , A , 1 )
Mid(Bytestring,btemp,1) = TempChar
decr btemp 'faster than btemp = btemp - 1
Next
|
Probably one should check in the simulator how much it helps in processor cycles. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Sun Oct 09, 2016 11:22 pm Post subject: |
|
|
Dim TempChar As Byte? Wouldn't that give me the ASCII value? |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Sun Oct 09, 2016 11:28 pm Post subject: |
|
|
No, it does not seem to. At least I know it works when using Mid as a statement. Must admit I have not directly tried it as a function. Easy to test. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Sun Oct 09, 2016 11:51 pm Post subject: |
|
|
Since I learn about Overlay I use them very often
Code: | $regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 64
$sim
Config Lcd = 20x4
Config Submode = New
Dim Number As String * 20
Dim Buff(21) As Byte At Number Overlay
Dim Rev_buff(21) As Byte
Dim N As Byte
Number = "12345678901234567890"
Function Revstring(byval Number As String) As String
Local A As Byte
Local TempChar As String * 1
Local ByteString As String * 32
'the following block reverses the string so MSB becomes LSB
ByteString = ""
For A = 1 to 32
TempChar = Mid(Number , A , 1 )
Bytestring = Tempchar + Bytestring
Next
RevString = ByteString
End Function
Function Revstring2(byval Number As String) As String
Local A As Byte
Local TempChar As String * 1
Local ByteString As String * 32
Dim Tempchar As Byte
Dim Btemp As Byte
Btemp = 32
For A = 1 To 32
Tempchar = Mid(number , A , 1 )
Mid(Bytestring,btemp,1) = TempChar
Decr Btemp 'faster than btemp = btemp - 1
Next
Revstring2 = Bytestring
End Function
Sub Rev_string()
Local Lenght As Byte
Local Rev_count As Byte
Lenght = Len(number)
Rev_count = Lenght
For N = 1 To Lenght
Rev_buff(n) = Buff(rev_count)
Decr Rev_count
Next
N = Memcopy(rev_buff(1) , Buff(1) , Lenght)
End Sub
Cls : Lcd Number
Call Rev_string '1828 cycles 0,2285ms
'Number = Revstring(number) '15114 cycles 1,88925ms
'Number = Revstring2(number) '7714 cycles '0,96425ms
Lowerline : Lcd Number
End |
|
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Mon Oct 10, 2016 12:07 am Post subject: |
|
|
Looks like you cant assign a byte as the result of the mid function.
Interesting that you can use a byte as the result of the mid statement.
But you can do both mid parts in one line:
[code]
For A = 1 to 32
Mid(Bytestring,btemp,1) = Mid(Number , A , 1 )
decr btemp 'faster than btemp = btemp - 1
Next
I checked this on a 6 character string.
Doing it the original way was 1280 cycles, doing it as above 870 cycles ( just the for-next loop ).
And yes, using an overlay like EDC showed allows to freely access a string as either bytes or characters. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
Visovian
Joined: 31 Oct 2007 Posts: 584 Location: Czech
|
Posted: Mon Oct 10, 2016 7:26 am Post subject: |
|
|
From
http://www.developerfusion.com/code/2196/reverse-string/
Adapted.
Code: | Function Reversestring(stext As String) As String
Dim Lentext As Byte
Dim Lpos As Byte
Dim Btemp As Byte
If Len(stext) = 0 Then Exit Function
Lentext = Len(stext)
Reversestring = Space(lentext)
For Lpos = Lentext To 1 Step -1
Btemp = Lentext - Lpos
Btemp = Btemp + 1
Mid(reversestring , Btemp , 1) = Mid(stext , Lpos , 1)
Next Lpos
End Function |
|
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
|
Back to top |
|
|
i.dobson
Joined: 05 Jan 2006 Posts: 1570 Location: Basel, Switzerland
|
Posted: Mon Oct 10, 2016 3:03 pm Post subject: |
|
|
Hi,
Or this:-
Code: |
Function Reversestring1(byval stext As String) As String
Dim Instring As String * 40
Dim Outstring As String * 40
Dim Instring_array(40) As Byte At Instring Overlay
Dim Outstring_array(40) As Byte At Outstring Overlay
If Len(stext) = 0 Then Exit Function
Instring = Stext
Lentext = Len(stext)
For Lpos = 1 to Lentext
Btemp = Lentext - Lpos
Btemp = Btemp + 1
Outstring_array(btemp) = Instring_array(lpos)
Next Lpos
Outstring_array(lpos) = 0
Reversestring1 = Outstring
End Function
|
Using overlay to map a byte array over the string, then just copying bytes from one array to the other.
Using the string version costs 4500 cpu cycles to reverse "Hello World 12345", the byte array version only needs about 1500 cpu cycles.
You just need to make sure the In/Out strings are large enough to hold the strings you want to reverse and the in/out strings&arrays ned to be defined as global (local won't work).
Regards
Ian Dobson _________________ Walking on water and writing software to specification is easy if they're frozen. |
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Mon Oct 10, 2016 4:31 pm Post subject: |
|
|
Quote: | strings&arrays ned to be defined as global (local won't work). |
Yes for arrays but for String it is possible to be local.
from help :
" There can be only LOCAL variables of the type BYTE, INTEGER, WORD, DWORD, LONG, SINGLE, DOUBLE or STRING.
The AT , ERAM, SRAM, XRAM directives can not be used with a local DIM statement. Also local arrays are not possible."
and arrays of string are global only, of course
JP |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Mon Oct 10, 2016 8:39 pm Post subject: |
|
|
Just a tad faster.
Code: | $Regfile = "m328pdef.dat"
$Crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 64 ' frame must be big enough to hold locals!
Declare Sub RevStr(src_str As String)
Const str_size = 32
Dim S As String * str_size
S = "0123456789ABCDEF0123456789ABCDEF"
' S = "012345"
RevStr S
Print S
End
Sub RevStr(src_str As String)
Local local_str As String * str_size
LoadAdr src_str , X
LoadAdr local_str , Z
!LD R22, X ' test for empty string
!TST R22
!BREQ StrEnd
!SeekEOS: ' seek end of string while copying chars into local string
!LD R22, X+
!ST Z+, R22
!TST R22
!BRNE SeekEOS
!SBIW XL, 1
LoadAdr local_str , Z
!LD R22, Z+
!StrRev: ' reverse chars, get from local and copy into source string
!ST -X, R22
!LD R22, Z+
!TST R22
!BRNE StrRev
!StrEnd:
End Sub |
Edit: Code simplified, made slightly faster and more straightforward.
Last edited by MWS on Mon Oct 10, 2016 10:13 pm; edited 1 time in total |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Mon Oct 10, 2016 10:11 pm Post subject: |
|
|
Sorry guys but I must show You this
In maybe in couple of days remove this video because Im listening radio with this and adversites maybe incomming.
This means "tad".. no comment
https://youtu.be/el2JnEQetsw |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Tue Oct 11, 2016 9:39 pm Post subject: |
|
|
Thanks for all the ideas and suggestions, they're very useful! |
|
Back to top |
|
|
|