Reverse a string

From Rosetta Code

Jump to: navigation, search
Task
Reverse a string
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".

Contents

[edit] ActionScript

function reverseString(string:String):String
{
var reversed:String = new String();
for(var i:int = string.length -1; i >= 0; i--)
reversed += string.charAt(i);
return reversed;
}

[edit] 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;

[edit] ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used

Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386

Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386

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))
)

Output:

was I tac a ti saW

[edit] APL

      ⌽'asdf'
fdsa

[edit] AutoHotkey

MsgBox % reverse("asdf")
 
reverse(string)
{
Loop, Parse, string
reversed := A_LoopField . reversed
Return reversed
}

[edit] AWK

function reverse(s)
{
p = ""
for(i=length(s); i > 0; i--) { p = p substr(s, i, 1) }
return p
}
 
BEGIN {
print reverse("edoCattesoR")
}

[edit] BASIC

Works with: QuickBasic version 4.5

FUNCTION reverse$(a$)
b$ = ""
FOR i = 1 TO LEN(a$)
b$ = MID$(a$, i, 1) + b$
NEXT i
reverse$ = b$
END FUNCTION

[edit] Batch File

@echo off
setlocal enabledelayedexpansion
call :reverse %1 res
echo %res%
goto :eof
 
:reverse
set str=%~1
set cnt=0
:loop
if "%str%" equ "" (
goto :eof
)
set chr=!str:~0,1!
set str=%str:~1%
set %2=%chr%!% class="re2">2!
goto loop

[edit] Befunge

To see this in action, it's best to use an interpreter that animates the process.

v  The string to reverse. The row to copy to.
| | The actual copying happens here.
| | | Increment column to write to.
| | | | Store column #.
v v v v v
> "reverse me" 3 10p >10g 4 p 10g1+ 10pv
^ ^ |: <
First column --| | @ ^
to write to. | ^ Get the address
All calls to 10 | to copy the next
involve saving or | character to.
reading the End when stack is empty or
column to write explicit zero is reached.
to.

[edit] Brainf***

[-]>,+[->,+]<[.<]

The former wont stop taking input bytes unless a special compiler was made to stop at ENTER. The following checks for 10 ascii (line feed) and stops taking input at that point

,----- ----- [+++++ +++++ > , ----- -----]	If a newline is hit counter will be zero and input loop ends
<[.<] run all chars backwards and print them
 
just because it looks good we print CRLF
+++++ +++++ +++ . --- .

[edit] 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;
}

[edit] C++

#include <iostream>
#include <string>
#include <algorithm>
 
int main()
{
std::string s;
std::getline(std::cin, s);
std::reverse(s.begin(), s.end()); // modifies s
std::cout << s << std::endl;
return 0;
}

[edit] 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:

private static string ReverseString(string input)
{
char[] inputChars = input.ToCharArray();
Array.Reverse(inputChars);
return new string(inputChars);
}

As of C# 4.0 you can call the Reverse method on a string, however it returns an Enumerable of chars. It appears that this only helps by letting you do the above in a different order (reverse the string, convert that to an array of chars, and return a new string from the reversed array):

return new string(input.Reverse().ToArray());

[edit] Clojure

[edit] 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.

(defn str-reverse [s] (apply str (reverse s)))

[edit] 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.

(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)))))

And the test result:

user=> s
"as⃝df̅"
user=> (str-reverse s)
"f̅ds⃝a"[
user=> (str-reverse (str-reverse s))
"as⃝df̅"
user=>

[edit] ColdFusion

You can reverse anything that can be written to the document in hashmarks (i.e. strings, numbers, now( ), etc.).

<cfset myString  = "asdf" />
<cfset myString = reverse( myString ) />

[edit] Common Lisp

(reverse my-string)

[edit] D

D has a built-in reverse function for array types (including string=char[]). It is an in-place function.

string s ;
s.reverse ;
s.dup.reverse ; // preserve original array

[edit] E

pragma.enable("accumulator")
def reverse(string) {
return accum "" for i in (0..!(string.size())).descending() { _ + string[i] }
}

[edit] Emacs Lisp

 
(concat (reverse (append "Hello World" nil)))
 

Output:

"dlroW olleH"

[edit] Eiffel

class
APPLICATION
create
make
feature
make
-- Demonstrate string reversal.
do
my_string := "Hello World!"
my_string.mirror
print (my_string)
end
my_string: STRING
-- Used for reversal
end

Output:

!dlroW olleH

[edit] Erlang

1> lists:reverse("reverse!").
"!esrever"

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.

reverse(Bin) ->
Size = size(Bin)*8,
<<T:Size/integer-little>> = Bin,
<<T:Size/integer-big>>.

Result:

1> test:reverse(<<"hello">>).
<<"olleh">>

[edit] Factor

A string is a sequence and there is a default reverse implementation for those.

"hello" reverse

string-reverse preserves graphemes:

"as⃝df̅" string-reverse "f̅ds⃝a" = .

[edit] Forth

: exchange ( a1 a2 -- )
2dup c@ swap c@ rot c! swap c! ;
: reverse ( c-addr u -- )
1- bounds begin 2dup > while
2dup exchange
-1 /string
repeat 2drop ;
 
s" testing" 2dup reverse type \ gnitset

[edit] Fortran

Works with: Fortran version 90 and later

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

Output:

This is a string
gnirts a si sihT

Another implementation that uses a recursive not-in-place algorithm:

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

Output:

no devil lived on
no devil lived on

[edit] F#

let ReverseString (s:string) = new string(Array.rev (s.ToCharArray()))

[edit] Gema

Reverse each line in the input stream. Using built in function:

\L<U>=@reverse{$1}

Not using built in function (recursively apply substring to same rule):

\L<U1><U>=@{$2}$1

[edit] Groovy

Solution:

println "Able was I, 'ere I saw Elba.".reverse()

Output:

.ablE was I ere' ,I saw elbA

[edit] Haskell

reverse = foldl (flip (:)) []

This function in defined in the Haskell Prelude.


[edit] HicEst

CHARACTER string = "Hello World", tmp
 
L = LEN( string )
DO i = 1, L/2
tmp = string(i)
string(i) = string(L-i+1)
string(L-i+1) = tmp
ENDDO
 
WRITE(Messagebox, Name) string

[edit] Icon and Unicon

[edit] Icon

procedure main(arglist)
s := \arglist[1] | "asdf"
write(s," <-> ", reverse(s)) # reverse is built-in
end

[edit] Unicon

This Icon solution works in Unicon.

[edit] Io

"asdf" reverse

[edit] J

Reverse (|.) reverses a list of items (of any shape or type).

   |.'asdf'
fdsa

[edit] Java

public static String reverseString(String s) {
return new StringBuffer(s).reverse().toString();
}

[edit] JavaScript

var a = "cat".split("");
a.reverse();
print(a.join("")); // tac

[edit] Liberty BASIC

input$ ="abcdefgABCDEFG012345"
print input$
print ReversedStr$( input$)
 
end
 
function ReversedStr$(in$)
for i =len(in$) to 1 step -1
ReversedStr$ =ReversedStr$ +mid$( in$, i, 1)
next i
end function

[edit] Logo

REVERSE works on both words and lists.

print reverse "cat   ; tac

[edit] Lua

Built-in string.reverse(s) or s:reverse().

theString = theString:reverse()

[edit] M4

define(`invert',`ifelse(len(`$1'),0,,`invert(substr(`$1',1))'`'substr(`$1',0,1))')

[edit] Mathematica

StringReverse["asdf"]

[edit] MATLAB

A built-in function, "fliplr(string)" handles reversing a string of ASCII characters. Unicode is a whole other beast, if you need this functionality test to see if "fliplr()" properly handles the unicode characters you use. If it doesn't then you will need to code a function that is specific to your application.

Sample Usage:

>> fliplr(['She told me that she spoke English and I said great. '...
'Grabbed her hand out the club and I said let''s skate.'])
 
ans =
 
.etaks s'tel dias I dna bulc eht tuo dnah reh debbarG .taerg dias I dna hsilgnE ekops ehs taht em dlot ehS
 

[edit] MAXScript

fn reverseString s =
(
local reversed = ""
for i in s.count to 1 by -1 do reversed += s[i]
reversed
)

[edit] Modula-3

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.

Output:

zabrabooF

[edit] MUMPS

 
REVERSE
 ;Take in a string and reverse it using the built in function $RE
NEW S
READ:30 "Enter a string: ",S
WRITE !,$REVERSE(S)
QUIT
 
Example:
USER>D REVERSE^ROSETTA
Enter a string: Hello, World!
!dlroW ,olleH

[edit] Nial

reverse 'asdf'
=fdsa

[edit] Objective-C

This extends the NSString object adding a reverseString class method.

#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

Usage example:

int main()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
NSString *test = [@"!A string to be reverted!" reverseString];
 
NSLog(test);
 
[pool release];
return 0;
}

[edit] Objeck

 
result := "asdf"->Reverse();
 

[edit] OCaml

Here a version that returns a new allocated string (preserving the original one):

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)

and here with in place modification:

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

[edit] Octave

s = "a string";
rev = s(length(s):-1:1)

[edit] Oz

Strings are lists. A function "Reverse" defined on lists is part of the implementation.

{System.showInfo {Reverse "!dlroW olleH"}}

An efficient (tail-recursive) implementation could look like this:

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

Oz uses a single-byte encoding by default. If you decide to use a multi-byte encoding, Reverse will not work correctly.

[edit] Pascal

The following examples handle correctly only single-byte encodings.

[edit] 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).

{ 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;

[edit] Extended Pascal, Turbo Pascal, Delphi and compatible compilers

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;

[edit] Perl

reverse $string

[edit] Perl 6

Works with: Rakudo version #21 "Seattle"


# Not transformative.
my $reverse = flip $string;
# or
say "hello world".flip;

[edit] PHP

strrev($string)

[edit] PicoLisp

(pack (flip (chop "äöüÄÖÜß")))

Output:

-> "ßÜÖÄüöä"

[edit] PL/I

 
s = reverse(s);
 

[edit] 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;

[edit] PowerShell

Test string

$s = "asdf"

[edit] Array indexing

Creating a character array from the end to the string's start and join it together into a string again.

Works with: PowerShell version 1

[string]::Join('', $s[$s.Length..0])

Works with: PowerShell version 2

-join ($s[$s.Length..0])

Works with: PowerShell version 2

[array]::Reverse($s)

[edit] 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.

Works with: PowerShell version 1

$s -replace
('(.)' * $s.Length),
[string]::Join('', ($s.Length..1 | ForEach-Object { "`$$_" }))

Works with: PowerShell version 2

$s -replace
('(.)' * $s.Length),
-join ($s.Length..1 | ForEach-Object { "`$$_" } )

[edit] PureBasic

Debug ReverseString("!dekrow tI")

[edit] Python

[edit] Optimized for user input

raw_input()[::-1]

[edit] Already known string

string[::-1]

[edit] Unicode reversal

(See this article for more information)

'''
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)

[edit] R

Works with: R version 2.8.1

The following code works with UTF-8 encoded strings too.

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!

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.

[edit] REBOL

print reverse "asdf"

Note the string is reversed in place. If you were using it anywhere else, you would find it reversed:

x: "asdf"
print reverse x
print x ; Now reversed.

REBOL/View 2.7.6.3.1 14-Mar-2008 does not handle Unicode strings. This is planned for REBOL 3.

[edit] REXX

say reverse('asdf')

Output:

fdsa

[edit] Ruby

str = "asdf"
reversed = str.reverse

[edit] Sather

class MAIN is
main is
s ::= "asdf";
reversed ::= s.reverse;
-- current implementation does not handle multibyte encodings correctly
end;
end;

[edit] Scala

Easy way:

"asdf".reverse

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.

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)
}

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)

[edit] Scheme

(define (string-reverse s)
(list->string (reverse (string->list s))))
> (string-reverse "asdf")
"fdsa"

[edit] Seed7

Seed7 strings are encoded with UTF-32 therefore no special Unicode solution is necessary

$ 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;

Output:

was I tac a ti saW

[edit] Slate

In-place reversal:

'asdf' reverse

Non-destructive reversal:

'asdf' reversed

[edit] Smalltalk

'asdf' reverse

[edit] SNOBOL4

ASCII-only

	output = reverse(reverse("reverse"))
end

output:

reverse

[edit] Standard ML

val str_reverse = implode o rev o explode;
val string = "asdf";
val reversed = str_reverse string;

[edit] Tcl

package require Tcl 8.5
string reverse asdf

[edit] TI-83 BASIC

The following program will place the reverse of Str1 in Str0. Note: length( and sub( can be found in the catalog.

:"ASDF"→Str1
:
:" "→Str0
:length(Str1)→B
:For(A,B,1,-1)
:Str0+sub(Str1,A,1)→Str0
:End
:sub(Str0,2,B)→Str0

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).

[edit] Ursala

#import std
 
#cast %s
 
example = ~&x 'asdf'
 
verbose_example = reverse 'asdf'

output:

'fdsa'

[edit] Vedit macro language

This routine reads the text from current line, reverses it and stores the reversed string in text register 10:

Reg_Empty(10)
for (BOL; !At_EOL; Char) {
Reg_Copy_Block(10, CP, CP+1, INSERT)
}

This routine reverses the current line in-place:

BOL
while (!At_EOL) {
Block_Copy(EOL_pos-1, EOL_pos, DELETE)
}
Personal tools
Support