Reverse a string: Difference between revisions
m moved Reversing a string to Reverse a string |
Non-locals Forth version added |
||
Line 225: | Line 225: | ||
2drop ; |
2drop ; |
||
s" testing" 2dup reverse type \ gnitset</lang> |
s" testing" 2dup reverse type \ gnitset</lang> |
||
This one doesn't require locals: |
|||
<lang forth>: reverse |
|||
2dup 1- chars over + \ save string, calculate addresses |
|||
begin |
|||
over over < \ as long we didn't pass the middle |
|||
while \ swap the characters |
|||
over c@ over c@ >r over c! over r> swap c! |
|||
1- swap 1+ swap \ increment pointers |
|||
repeat 2drop \ drop the addresses |
|||
; |
|||
s" testing" reverse type</lang> |
|||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
Revision as of 21:03, 18 February 2010
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Take a string and reverse it. For example, "asdf" becomes "fdsa".
For extra credit, preserve Unicode combining characters. For example, "as⃝df̅" becomes "f̅ds⃝a", not "̅fd⃝sa".
Ada
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
procedure Reverse_String is
function Reverse_It (Item : String) return String is Result : String (Item'Range); begin for I in Item'range loop Result (Result'Last - I + Item'First) := Item (I); end loop; return Result; end Reverse_It;
begin
Put_Line (Reverse_It (Get_Line));
end Reverse_String;</lang>
ALGOL 68
<lang algol68>PROC reverse = (REF STRING s)VOID:
FOR i TO UPB s OVER 2 DO CHAR c = s[i]; s[i] := s[UPB s - i + 1]; s[UPB s - i + 1] := c OD;
main: (
STRING text := "Was it a cat I saw"; reverse(text); print((text, new line))
)</lang> Output:
was I tac a ti saW
APL
<lang apl> ⌽'asdf' fdsa</lang>
AutoHotkey
<lang AutoHotkey>MsgBox % reverse("asdf")
reverse(string) {
Loop, Parse, string reversed := A_LoopField . reversed Return reversed
}</lang>
AWK
<lang awk>function reverse(s) {
p = "" for(i=length(s); i > 0; i--) { p = p substr(s, i, 1) } return p
}
BEGIN {
print reverse("edoCattesoR")
}</lang>
BASIC
<lang qbasic>function reverse$(a$)
b$ = "" for i = 1 to len(a$) b$ = mid$(a$, i, 1) + b$ next i reverse$ = b$
end function</lang>
Brainf***
<lang bf>[-]>,+[->,+]<[.<]</lang>
C
<lang c>#include <stdio.h>
/* This function assumes the passed pointer points to a valid, zero-terminated string */ void reverse (char *s) {
char *t = s;
while (*t != '\0') t++; while (s < t) { int c = *s; *s++ = *--t; *t = c; }
}
int main () {
char text1[] = "asdf", text2[] = ""; reverse (text1); printf ("'%s'\n", text1); reverse (text2); printf ("'%s'\n", text2);
return 0;
}</lang>
C++
<lang cpp>#include <iostream>
- include <string>
- include <algorithm>
int main() {
std::string s; std::get_line(std::cin, s); std::reverse(s.begin(), s.end()); // modifies s std::cout << s << std::endl; return 0;
}</lang>
C#
C# does not have a built-in Reverse method for strings, which are immutable. One way to implement this is to convert the string to an array of characters, reverse that, and return a new string from the reversed array: <lang csharp>private static string ReverseString(string input) { char[] inputChars = input.ToCharArray(); Array.Reverse(inputChars); return new string(inputChars); }</lang>
Clojure
Basic reverse
For normal strings, the reverse function can be used to do the bulk of the work. However, it returns a character sequence, which has to be converted back to a string.
<lang lisp>(defn str-reverse [s] (apply str (reverse s)))</lang>
Supporting combining characters
Handling combining characters present a trickier task. We need to protect the relative ordering of the combining character and the character to its left. Thus, before reversing, the characters need to be grouped.
<lang lisp>(defn combining? [c]
(let [type (Character/getType c)] ;; currently hardcoded to the types taken from the sample string (or (= type 6) (= type 7))))
(defn group
"Group normal characters with their combining characters" [chars] (cond (empty? chars) chars
(empty? (next chars)) (list chars) :else (let [dres (group (next chars))] (cond (combining? (second chars)) (cons (cons (first chars) (first dres)) (rest dres)) :else (cons (list (first chars)) dres)))))
(defn str-reverse
"Unicode-safe string reverse" [s] (apply str (apply concat (reverse (group s)))))</lang>
And the test result:
user=> s "as⃝df̅" user=> (str-reverse s) "f̅ds⃝a"[ user=> (str-reverse (str-reverse s)) "as⃝df̅" user=>
ColdFusion
You can reverse anything that can be written to the document in hashmarks (i.e. strings, numbers, now( ), etc.). <lang cfm><cfset myString = "asdf" /> <cfset myString = reverse( myString ) /></lang>
Common Lisp
<lang lisp>(reverse my-string)</lang>
D
D has a built-in reverse function for array types (including string=char[]). It is an in-place function. <lang d>string s ; s.reverse ; s.dup.reverse ; // preserve original array</lang>
E
<lang e>pragma.enable("accumulator") def reverse(string) {
return accum "" for i in (0..!(string.size())).descending() { _ + string[i] }
}</lang>
Erlang
<lang erlang>1> lists:reverse("reverse!"). "!esrever"</lang>
Erlang also supports binary strings, which uses its binary format. There is no standard function to reverse a binary sequence, but the following one does the job well enough. It works by changing the endianness (from little to big or the opposite) of the whole sequence, effectively reversing the string. <lang erlang>reverse(Bin) ->
Size = size(Bin)*8, <<T:Size/integer-little>> = Bin, <<T:Size/integer-big>>.</lang>
Result:
1> test:reverse(<<"hello">>). <<"olleh">>
Factor
A string is a sequence and there is a default reverse implementation for those.
<lang factor>"hello" reverse</lang>
string-reverse
preserves graphemes:
<lang factor>"as⃝df̅" string-reverse "f̅ds⃝a" = .</lang>
Forth
<lang forth>: cexch { a1 a2 -- }
a1 c@ a2 c@ a1 c! a2 c! ;
- reverse ( caddr len -- )
1- bounds begin 2dup > while 2dup cexch 1+ swap 1- swap repeat 2drop ;
s" testing" 2dup reverse type \ gnitset</lang>
This one doesn't require locals: <lang forth>: reverse
2dup 1- chars over + \ save string, calculate addresses begin over over < \ as long we didn't pass the middle while \ swap the characters over c@ over c@ >r over c! over r> swap c! 1- swap 1+ swap \ increment pointers repeat 2drop \ drop the addresses
s" testing" reverse type</lang>
Fortran
<lang fortran>PROGRAM Example
CHARACTER(80) :: str = "This is a string" CHARACTER :: temp INTEGER :: i, length
WRITE (*,*) str length = LEN_TRIM(str) ! Ignores trailing blanks. Use LEN(str) to reverse those as well DO i = 1, length/2 temp = str(i:i) str(i:i) = str(length+1-i:length+1-i) str(length+1-i:length+1-i) = temp END DO WRITE(*,*) str
END PROGRAM Example</lang> Output:
This is a string gnirts a si sihT
Another implementation that uses a recursive not-in-place algorithm: <lang fortran>program reverse_string
implicit none character (*), parameter :: string = 'no devil lived on'
write (*, '(a)') string write (*, '(a)') reverse (string)
contains
recursive function reverse (string) result (res)
implicit none character (*), intent (in) :: string character (len (string)) :: res
if (len (string) == 0) then res = else res = string (len (string) :) // reverse (string (: len (string) - 1)) end if
end function reverse
end program reverse_string</lang> Output: <lang>no devil lived on no devil lived on</lang>
F#
<lang fsharp>let ReverseString (s:string) = new string(Array.rev (s.ToCharArray()))</lang>
Groovy
Solution: <lang groovy>println "Able was I, 'ere I saw Elba.".reverse()</lang> Output:
.ablE was I ere' ,I saw elbA
Haskell
<lang haskell>reverse = foldl (flip (:)) []</lang> This function in defined in the Haskell Prelude.
J
Reverse (|.) reverses items of any shape or type. <lang j> |.'asdf' fdsa</lang>
Java
<lang java>public static String reverseString(String s) {
return new StringBuffer(s).reverse().toString();
}</lang>
JavaScript
<lang javascript>var a = "cat".split(""); a.reverse(); print(a.join("")); // tac</lang>
Logo
REVERSE works on both words and lists. <lang logo>print reverse "cat ; tac</lang>
Lua
Built-in string.reverse(s) or s:reverse(). <lang lua>theString = theString:reverse()</lang>
M4
<lang m4>define(`invert',`ifelse(len(`$1'),0,,`invert(substr(`$1',1))'`'substr(`$1',0,1))')</lang>
Mathematica
<lang mathematica>StringReverse["asdf"]</lang>
MAXScript
<lang maxscript>fn reverseString s = (
local reversed = "" for i in s.count to 1 by -1 do reversed += s[i] reversed
)</lang>
Modula-3
<lang modula3>MODULE Reverse EXPORTS Main;
IMPORT IO, Text;
PROCEDURE String(item: TEXT): TEXT =
VAR result: TEXT := ""; BEGIN FOR i := Text.Length(item) - 1 TO 0 BY - 1 DO result := Text.Cat(result, Text.FromChar(Text.GetChar(item, i))); END; RETURN result; END String;
BEGIN
IO.Put(String("Foobarbaz") & "\n");
END Reverse.</lang> Output:
zabrabooF
Nial
<lang nial>reverse 'asdf' =fdsa</lang>
Objective-C
This extends the NSString object adding a reverseString class method.
<lang objc>#import <Foundation/Foundation.h>
@interface NSString (Extended) -(NSString *)reverseString; @end
@implementation NSString (Extended) -(NSString *)reverseString {
NSInteger l; NSMutableString *ostr = [NSMutableString stringWithCapacity:[self length] ]; for(l=[self length]-1; l>=0; l--) { [ostr appendFormat:@"%C", [self characterAtIndex:l] ]; } return ostr;
} @end</lang>
Usage example:
<lang objc>int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *test = [@"!A string to be reverted!" reverseString]; NSLog(test); [pool release]; return 0;
}</lang>
OCaml
Here a version that returns a new allocated string (preserving the original one):
<lang ocaml>let rev_string str =
let len = String.length str in let res = String.create len in let last = len - 1 in for i = 0 to last do let j = last - i in res.[i] <- str.[j]; done; (res)</lang>
and here with in place modification:
<lang ocaml>let rev_string str =
let last = String.length str - 1 in for i = 0 to last / 2 do let j = last - i in let c = str.[i] in str.[i] <- str.[j]; str.[j] <- c; done</lang>
Octave
<lang octave>s = "a string"; rev = s(length(s):-1:1)</lang>
Oz
Strings are lists. A function "Reverse" defined on lists is part of the implementation. <lang oz>{System.showInfo {Reverse "!dlroW olleH"}}</lang>
An efficient (tail-recursive) implementation could look like this: <lang oz>local
fun {DoReverse Xs Ys} case Xs of nil then Ys [] X|Xr then {DoReverse Xr X|Ys} end end
in
fun {Reverse Xs} {DoReverse Xs nil} end
end</lang>
Oz uses a single-byte encoding by default. If you decide to use a multi-byte encoding, Reverse will not work correctly.
Pascal
The following examples handle correctly only single-byte encodings.
Standard Pascal
The following only works on implementations which implement Level 1 of standard Pascal (many popular compilers don't).
Standard Pascal doesn't have a separate string type, but uses arrays of char for strings. Note that Standard Pascal doesn't allow a return type of char array, therefore the destination array is passed through a var parameter (which is more efficient anyway). <lang pascal>{ the result array must be at least as large as the original array } procedure reverse(s: array[min .. max: integer] of char, var result: array[min1 .. max1: integer] of char);
var i, len: integer; begin len := max-min+1; for i := 0 to len-1 do result[min1 + len-1 - i] := s[min + i] end;</lang>
Extended Pascal, Turbo Pascal, Delphi and compatible compilers
<lang pascal>function reverse(s : String) : String; var
i : Integer;
begin
for i := 1 to length(s) do s[i] := s[length(s)-(i-1)]; reverse := s;
end;</lang>
Perl
<lang perl>reverse $string</lang>
Perl 6
<lang perl6>flip $string</lang>
PHP
<lang php>strrev($string)</lang>
Pop11
<lang pop11>define reverse_string(s);
lvars i, l = length(s); for i from l by -1 to 1 do s(i); endfor; consstring(l);
enddefine;</lang>
PowerShell
Test string <lang powershell>$s = "asdf"</lang>
Array indexing
Creating a character array from the end to the string's start and join it together into a string again.
<lang powershell>[string]::Join(, $s[$s.Length..0])</lang>
<lang powershell>-join ($s[$s.Length..0])</lang>
Regular expressions
Creating a regular expression substitution which captures every character of the string in a capture group and uses a reverse-ordered string of references to those to construct the reversed string.
<lang powershell>$s -replace
('(.)' * $s.Length), [string]::Join(, ($s.Length..1 | ForEach-Object { "`$$_" }))</lang>
<lang powershell>$s -replace
('(.)' * $s.Length), -join ($s.Length..1 | ForEach-Object { "`$$_" } )</lang>
Python
Optimized for user input
<lang python>raw_input()[::-1]</lang>
Already known string
<lang python>string[::-1]</lang>
Unicode reversal
(See this article for more information)
<lang python>
Reverse a Unicode string with proper handling of combining characters
import unicodedata
def ureverse(ustring):
Reverse a string including unicode combining characters
Example: >>> ucode = .join( chr(int(n, 16)) for n in ['61', '73', '20dd', '64', '66', '305'] ) >>> ucoderev = ureverse(ucode) >>> ['%x' % ord(char) for char in ucoderev] ['66', '305', '64', '73', '20dd', '61'] >>> groupedchars = [] uchar = list(ustring) while uchar: if 'COMBINING' in unicodedata.name(uchar[0], ): groupedchars[-1] += uchar.pop(0) else: groupedchars.append(uchar.pop(0)) # Grouped reversal groupedchars = groupedchars[::-1]
return .join(groupedchars)
if __name__ == '__main__':
ucode = .join( chr(int(n, 16)) for n in ['61', '73', '20dd', '64', '66', '305'] ) ucoderev = ureverse(ucode) print (ucode) print (ucoderev)</lang>
R
The following code works with UTF-8 encoded strings too. <lang R>revstring <- function(stringtorev) {
return( paste( strsplit(stringtorev,"")1[nchar(stringtorev):1] ,collapse="") )
} revstring("asdf") revstring("m\u00f8\u00f8se") Encoding("m\u00f8\u00f8se") # just to check if on your system it's something
# different!</lang>
Outputs
[1] "fdsa" [1] "esøøm" [1] "UTF-8"
R can encode strings in Latin1 and UTF-8 (the default may depend on the locale); the Encoding(string) can be used to know if the string is encoded in Latin1 or UTF-8; the encoding can be forced (Encoding(x) <- "latin1"), or we can use iconv to properly translate between encodings whenever possible.
REBOL
<lang REBOL>print reverse "asdf"</lang>
Note the string is reversed in place. If you were using it anywhere else, you would find it reversed:
<lang REBOL>x: "asdf" print reverse x print x ; Now reversed.</lang>
REBOL/View 2.7.6.3.1 14-Mar-2008 does not handle Unicode strings. This is planned for REBOL 3.
Ruby
<lang ruby>str = "asdf" reversed = str.reverse</lang>
Scala
Easy way:
<lang scala>"asdf".reverse</lang>
Unicode-aware. I can't guarantee it get all the cases, but it does work with combining characters as well as supplementary characters. I did not bother to preserve the order of newline characters, and I didn't even consider directionality beyond just ruling it out.
<lang scala>def reverseString(s: String) = {
import java.lang.Character._ val combiningTypes = List(NON_SPACING_MARK, ENCLOSING_MARK, COMBINING_SPACING_MARK) def isCombiningCharacter(c: Char) = combiningTypes contains c.getType def isCombiningSurrogate(high: Char, low: Char) = combiningTypes contains getType(toCodePoint(high, low)) def isCombining(l: List[Char]) = l match { case List(a, b) => isCombiningSurrogate(a, b) case List(a) => isCombiningCharacter(a) case Nil => true case _ => throw new IllegalArgumentException("isCombining expects a list of up to two characters") } def cleanSurrogate(l: List[Char]) = l match { case List(a, b) if a.isHighSurrogate && b.isLowSurrogate => l case List(a, b) if a.isLowSurrogate => Nil case List(a, b) => List(a) case _ => throw new IllegalArgumentException("cleanSurrogate expects lists of two characters, exactly") } def splitString(string: String) = (string+" ").iterator sliding 2 map (_.toList) map cleanSurrogate toList
def recurse(fwd: List[List[Char]], rev: List[Char]): String = fwd match { case Nil => rev.mkString case c :: rest => val (combining, remaining) = rest span isCombining recurse(remaining, c ::: combining.foldLeft(List[Char]())(_ ::: _) ::: rev) } recurse(splitString(s), Nil)
}</lang>
REPL on Windows doesn't handle Unicode, so I'll show the bytes instead:
scala> res71 map ("\\u%04x" format _.toInt) res80: scala.collection.immutable.IndexedSeq[String] = IndexedSeq(\u0061, \u0073, \u20dd, \u0064, \u0066, \u0305) scala> reverseString(res71) map ("\\u%04x" format _.toInt) res81: scala.collection.immutable.IndexedSeq[String] = IndexedSeq(\u0066, \u0305, \u0064, \u0073, \u20dd, \u0061)
Scheme
<lang scheme>(define (string-reverse s)
(list->string (reverse (string->list s))))</lang>
> (string-reverse "asdf") "fdsa"
Seed7
Seed7 strings are encoded with UTF-32 therefore no special Unicode solution is necessary
<lang seed7>$ include "seed7_05.s7i";
const func string: reverse (in string: stri) is func
result var string: result is ""; local var integer: index is 0; begin for index range length(stri) downto 1 do result &:= stri[index]; end for; end func;
const proc: main is func
begin writeln(reverse("Was it a cat I saw")); end func;</lang>
Output:
was I tac a ti saW
Slate
In-place reversal: <lang slate>'asdf' reverse</lang> Non-destructive reversal: <lang slate>'asdf' reversed</lang>
Smalltalk
<lang smalltalk>'asdf' reverse</lang>
Standard ML
<lang sml>val str_reverse = implode o rev o explode; val string = "asdf"; val reversed = str_reverse string;</lang>
Tcl
<lang tcl>package require Tcl 8.5 string reverse asdf</lang>
TI-83 BASIC
The following program will place the reverse of Str1 in Str0. Note: length( and sub( can be found in the catalog. <lang ti83b>:"ASDF"→Str1
- " "→Str0
- length(Str1)→B
- For(A,B,1,-1)
- Str0+sub(Str1,A,1)→Str0
- End
- sub(Str0,2,B)→Str0</lang>
The reason a single space must be placed in Str0 and then later removed is that for some reason, the TI-83 will not allow concatenation with an empty string (so Str0+sub... would fail).
Ursala
<lang Ursala>#import std
- cast %s
example = ~&x 'asdf'
verbose_example = reverse 'asdf'</lang> output:
'fdsa'
Vedit macro language
This routine reads the text from current line, reverses it and stores the reversed string in text register 10:
<lang vedit>Reg_Empty(10) for (BOL; !At_EOL; Char) {
Reg_Copy_Block(10, CP, CP+1, INSERT)
}</lang>
This routine reverses the current line in-place:
<lang vedit>BOL while (!At_EOL) {
Block_Copy(EOL_pos-1, EOL_pos, DELETE)
}</lang>
- Programming Tasks
- String manipulation
- Ada
- ALGOL 68
- APL
- AutoHotkey
- AWK
- BASIC
- Brainf***
- C
- C++
- C sharp
- Clojure
- ColdFusion
- Common Lisp
- D
- E
- E examples needing attention
- Erlang
- Factor
- Forth
- Fortran
- F Sharp
- Groovy
- Haskell
- J
- Java
- JavaScript
- Logo
- Lua
- M4
- Mathematica
- MAXScript
- Modula-3
- Nial
- Objective-C
- OCaml
- Octave
- Oz
- Pascal
- Perl
- Perl 6
- PHP
- Pop11
- PowerShell
- Python
- R
- REBOL
- Ruby
- Scala
- Scheme
- Seed7
- Slate
- Smalltalk
- Standard ML
- Tcl
- TI-83 BASIC
- Ursala
- Vedit macro language