Re: reverse a string in place
by choroba (Cardinal) on Mar 24, 2013 at 07:33 UTC
|
In Perl, a string is not an array of characters as in C. Reversing a string is easy, though: use reverse: $string = reverse $string;
Update: What do you mean by doing it "without using any built-in function"? In your example, are you going to implement floor yourself?
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
choroba,
You really made laugh my heart out with your comment:
"What do you mean by doing it "without using any built-in function"? In your example, are you going to implement floor yourself?"
Tripple ++ to you....
| [reply] [Watch: Dir/Any] |
|
by 'without using any built-in' i meant the 'reverse' function in perl which is used to reverse the string.
| [reply] [Watch: Dir/Any] |
|
Re: reverse a string in place
by kcott (Archbishop) on Mar 24, 2013 at 09:23 UTC
|
$ perl -e '
+
$x = "abcdefghi";
print +($x =~ /./g)[-$_] for (1 .. $#{[$x =~ /./g]} + 1);
'
ihgfedcba
| [reply] [Watch: Dir/Any] [d/l] |
Re: reverse a string in place
by tobyink (Canon) on Mar 24, 2013 at 09:47 UTC
|
my $string = "abcdefghi";
$string =~ s/(.)/substr($string, length($string)-pos($string)-1, 1)/eg
+;
print $string, "\n";
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
| [reply] [Watch: Dir/Any] [d/l] |
Re: reverse a string in place
by CountZero (Bishop) on Mar 24, 2013 at 07:42 UTC
|
What is wrong with using the available tools and functions? Unless this is homework, it is a silly requirement.And if it is homework, it still is silly.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] [Watch: Dir/Any] |
Re: reverse a string in place
by Athanasius (Archbishop) on Mar 24, 2013 at 08:04 UTC
|
Just want to point out that the algorithm as given is incorrect. n is the number of elements in the array, so the first line should read:
function reverse_in_place(a[0 .. (n - 1)])
Alternatively, you would need to change the arithmetic:
function reverse_in_place(a[0 .. n])
for i from 0 to floor( ((n + 1) / 2) - 1 )
tmp := a[i]
a[i] := a[n - i]
a[n - i] := tmp
Update 1: Implementing the algorithm in Perl is straightforward, provided you are allowed to use the built-in functions split and join (scalar isn’t really needed in the sub):
use strict;
use warnings;
my $string = 'abcdefghi';
print 'Original string: ', $string, "\n";
print 'Using function: ', reverse_in_place($string), "\n";
print 'Using reverse: ', scalar reverse ($string), "\n"; # For c
+omparison
sub reverse_in_place
{
my ($string) = @_;
my @array = split //, $string;
my $n = scalar @array;
for (0 .. $n / 2 - 1)
{
my $tmp = $array[$_];
$array[$_] = $array[$n - $_ - 1];
$array[$n - $_ - 1] = $tmp;
}
return join('', @array);
}
Update 2: Fixed out-by-one error in the for loop. Thanks to j0se for pointing it out.
Hope that helps,
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Original string: ab
Using function: ab
Using reverse: ba
Original string: abcd
Using function: dbca
Using reverse: dcba
Excellence is an art won by training and habituation: we do not act rightly because we have virtue or excellence, but we rather have these because we have acted rightly. -- Will Durant
| [reply] [Watch: Dir/Any] [d/l] |
|
I don't know how old this thread is but I found it interesting to practice manipulation for strings,
please keep in mind that I am but a few weeks into this perl code but did I meet the requirements? other than using length or split
use strict;
use warnings;
my $string = 'abcdefghi';
#let's find the ways to count the elements in string;
my $l = length($string); #finding number of elemnts
my @ind=split //,$string; #finding the number of elements
#assigning the start of our last element for our looping
my $n = (scalar @ind )-1; #getting the last element to start count bac
+kwards optinal
for (my $i=(length ($string)-1) ; $i >= 0; $i-- ){
print $ind[$i];
}
print "\nfor comparison :", scalar reverse($string),"\n";
| [reply] [Watch: Dir/Any] [d/l] |
|
while (my $letter = pop @ind){
print $letter;
}
pop() removes the last element of an array. Also see shift(), unshift() and push()
-stevieb
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
Re: reverse a string in place
by choroba (Cardinal) on Mar 24, 2013 at 08:57 UTC
|
my $s = "abcdefgh";
print "$s\n";
$s .= substr $s, length($s) - 2 * $_, 1 for 1 .. length($s) - 1;# Add
+the reversed string.
substr $s, 0, length($s) / 2, q(); # Remo
+ve the original string.
print "$s\n";
| [reply] [Watch: Dir/Any] [d/l] |
Re: reverse a string in place
by ww (Archbishop) on Mar 24, 2013 at 17:07 UTC
|
When you ask the Monks to do your homework, it's well to make note of that fact in your initial post.
Otherwise, someone with a spark of evil might just post code to do the job with such sophistication that your instructor will immediately know you've been cheating.
If you didn't program your executable by toggling in binary, it wasn't really programming!
| [reply] [Watch: Dir/Any] |
|
No built-in functions (abundant use of Perl's operators, though).
Yes, there's a spark of evil. But "they" always say that the easiest way is to divide a problem into smaller sub-problems:
sub rec_reverse {
return $_[0] if $_[0] eq '';
my( $char, $smaller_problem ) = $_[0] =~ m/\A(.)(.*)\z/s;
return rec_reverse( $smaller_problem ) . $char;
}
print rec_reverse( "Hello\nworld." ), "\n";
I wouldn't call it sophisticated or elegant though, and if it were turned in as ones own work, it would probably merit some skepticism. Recursion is not an optimal approach here, since the number of recursive calls will match the length of the string, and each call added to the call-stack has a cost. Also, the regexp contortion as a means of eliminating any "built-in" functions (ie, substr) does nothing to dispel the rumor that Perl is difficult to read.
I find with recursion that it always helps me to think through it by thinking in terms of "problem" and "smaller_problem". I'm always tempted to write recursion like this:
sub rec_reverse {
my $problem = shift;
if( $problem eq '' or ! defined $problem ) {
return $problem; # Can't be made smaller. End case.
}
else {
my( $char, $smaller_problem ) = $problem =~ m/\A(.)(.*)\z/s;
return rec_reverse( $smaller_problem ) . $char;
}
}
Which is the same thing but more explicit, and possibly more readable (and possibly less, since we've lost variable names that look like strings).
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: reverse a string in place
by jwkrahn (Abbot) on Mar 24, 2013 at 22:12 UTC
|
$ perl -le'
my $string = "abcdefghi";
print $string;
# get the address of every character
my @addr = map \substr( $string, $_, 1 ), 0 .. length( $string ) - 1;
# swap the characters in-place.
( ${$addr[ $_ ]}, ${$addr[ -( $_ + 1 ) ]} ) = ( ${$addr[ -( $_ + 1 ) ]
+}, ${$addr[ $_ ]} ) for 0 .. $#addr / 2;
print $string;
'
abcdefghi
ihgfedcba
| [reply] [Watch: Dir/Any] [d/l] |
Re: reverse a string in place
by toolic (Bishop) on Mar 24, 2013 at 12:46 UTC
|
| [reply] [Watch: Dir/Any] |
Re: reverse a string in place
by mtve (Deacon) on Mar 27, 2013 at 12:07 UTC
|
hmm, regular expression, without using any other array or (almost no) build-in functions:
#! /usr/bin/perl
use warnings;
use strict;
$_ = 'abcdefghi';
# s/./ substr $_, -$+[0], 1 /eg; # duh, substr and array
# s#.# /(.).{$-[0]}$/; $1 #eg; # duh, array
my $x = 0; s#.# /(.).{$x}$/; $x++; $1 #eg;
print "$_\n";
| [reply] [Watch: Dir/Any] [d/l] |
Re: reverse a string in place
by Anonymous Monk on Feb 27, 2016 at 19:06 UTC
|
my $string_reversed = join '', reverse(split //, $string_to_reverse); | [reply] [Watch: Dir/Any] [d/l] |
Re: reverse a string in place
by Anonymous Monk on Feb 28, 2016 at 08:13 UTC
|
Toady Tim. Is map() a function, technically?
#! /usr/bin/perl -lw
my @a = split //, shift;
print "INPUT = <@a>";
# @a[0..$#a] = @a[map -1-$_, 0..$#a];
@a[$_,~$_] = @a[~$_,$_] for 0..$#a/2;
print "OUTPUT = <@a>";
| [reply] [Watch: Dir/Any] [d/l] |