CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Fun With Perl: Perl Quizzes - Learn Perl the Fun Way:
String Division (2 Quizzes in 1!)

 



japhy
Enthusiast

Dec 15, 2000, 2:56 PM

Post #1 of 8 (46753 views)
String Division (2 Quizzes in 1!) Can't Post

Quiz 1 -- Equal Parts

Given a string, how can you efficiently divide the string into x pieces, where each piece has y characters, except for possibly the last, which has between 1 and y characters?

For the love of Perl, please test your solutions before posting them -- if you find a place where your algorithm fails, post THAT along with your attempt, so that people might be able to help you.

Quiz 2 -- Approximate Parts

This is an introduction to greedy algorithms. Greedy algorithms do what is locally best, and, if they are successful, end up doing the right thing.

So you are given a string, and you are asked to split it into x pieces, but can only split on whitespace. And you are asked to make the pieces as close to the same length as possible. Example:

Splitting "would you like some pizza?" into two pieces results in "would you like" and "some pizza?", whereas splitting it into 3 pieces results in "would you", "like some", and "pizza?"

Assume the string is a list of non-whitespace characters joined by single spaces (that is, you'll never have two spaces in a row, and there is only space between words, not at the beginning of end of the string).

You might find it easier to approach the problem for splitting into 2 pieces, and then generalizing from there.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author


japhy
Enthusiast

Dec 15, 2000, 3:50 PM

Post #2 of 8 (46751 views)
Hints for the the quizzes [In reply to] Can't Post

Quiz 1

There are multiple ways to get substrings of a string -- substr(), unpack(), a regex...

Quiz 2

You want to split the string as close to the center as possible (for the "split into 2 pieces" approach). So find the whitespace closest to the center, and split the string there. For splitting into n pieces, you want to find the whitespace closest to 1/n way through the string.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author


jas
Deleted

Dec 19, 2000, 9:11 AM

Post #3 of 8 (46731 views)
Re: String Division (2 Quizzes in 1!) [In reply to] Can't Post

I am sure this is not a very -nice- solution. I discovered something about building REs which I didn't know before which is this:

$re = '$a';
$a = "apple";
/$re/ does not then match "apple" which is why I am reassigning the entire regular expression in the loop. Perhaps someone can enlighten me about how to force the variables in an existing string to get interpolated.

#!/bin/perl
($pieces,$_) = @ARGV;
$c = length;
chop($re = "(.{$c,}) " x $pieces);

until (@matches = /$re/) { $c--; chop($re = "(.{$c,}) " x $pieces); $c or last; }

print join("\n",@matches)."\n";
__END__


Cheers
jas



Jasmine
Administrator

Dec 22, 2000, 8:20 AM

Post #4 of 8 (46720 views)
Re: String Division (2 Quizzes in 1!) [In reply to] Can't Post

Jas,

I'm not sure if there was a type in your post, but $re doesn't contain a or even the contents of $a -- it contains $a, and apple doesn't contain $a.

The single quotes around $a doesn't allow interpolation -- it's an "as is" assignment.

If you wanted to match the value of $a (which was assigned to $re), you should use double quotes, or unless there are other charatcters, nothing:

$re = $a;
$re = "$a and something";

Have I misunderstood?



japhy
Enthusiast

Dec 22, 2000, 2:36 PM

Post #5 of 8 (46715 views)
Re: String Division (2 Quizzes in 1!) [In reply to] Can't Post

Interpolation only goes so far.


Code
$a = 'something'; 
$b = '$a';
if ($str =~ /$b/) { ... }

The single quotes around $a make it mean the ACTUAL 2-character string $a. When Perl gets to /$b, it interpolates the variable, and it gets expanded to its value, $a. Perl does not then go and interpolate THAT as well.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author


BigRich
Novice

Jan 3, 2001, 5:05 PM

Post #6 of 8 (46656 views)
Re: String Division (2 Quizzes in 1!) [In reply to] Can't Post

Here are a few quick and dirty hacks. I've attached a script that prints out results to show how they work.

Quiz 1 (split string into equal parts)

$y_characters = 7; # number of characters to divide string by
$string = "How can you efficiently divide a string into x pieces with y characters (lets try y = $y_characters)";

## $string =~ s/ //g; if you don't want to count a space as a character

## Using substr()

$x_pieces = 0;
while ($x_pieces < length($string)) {
push @pieces, substr($string, $x_pieces, $y_characters);
$x_pieces += $y_characters;
}

@pieces contains: [How can] [ you ef] [ficient] [ly divi] [de a st] [ring in] [to x pi] [eces wi] [th y ch] [aracter] [s (lets] [ try y ] [= 7)]


## Using split() (& grep() to remove the null values)

@pieces_2 = split(/(.{$y_characters})/, $string);
@pieces_2 = grep(/(.+)/, @pieces_2);

@pieces_2 contains: [How can] [ you ef] [ficient] [ly divi] [de a st] [ring in] [to x pi] [eces wi] [th y ch] [aracter] [s (lets] [ try y ] [= 7)]


# Using unpack()

$pcs = ('a'.$y_characters." ") x int(length($string) / $y_characters +1);
@pieces_3 = unpack("$pcs", "$string");

@pieces_3 contains: [How can] [ you ef] [ficient] [ly divi] [de a st] [ring in] [to x pi] [eces wi] [th y ch] [aracter] [s (lets] [ try y ] [= 7)]



Quiz 2, split string into equal parts(on whitespace only)

$x_pcs = 7; # number of pieces to divide string into
$string2 = 'How can you divide a string into x pieces on whitespace only, while keeping each piece as equal as possible?';

## Slice it up
@str_arry = split(/\s/, $string2);
$split_at = int($#str_arry / $x_pcs);
$cnt = 0;
$cnt2 = 0;
while ($cnt < @str_arry) {
$_ = ($cnt == 0) ? $split_at : $cnt + $split_at;
$_ = $#str_arry if ($_ > $#str_arry);
$equal_pcs[$cnt2] = join(' ', @str_arry[$cnt..$_]);
$cnt += $split_at + 1;
$cnt2++;
}

@equal_pcs contains:

[How can you]
[divide a string]
[into x pieces]
[on whitespace only,]
[while keeping each]
[piece as equal]
[as possible?]



BigRich






ihb
newbie

Jan 4, 2001, 10:57 PM

Post #7 of 8 (46646 views)
Re: String Division (2 Quizzes in 1!) [In reply to] Can't Post

This only answers Quiz 1:

$_ = "This string shall be split into equal parts.";
$part_length = 5;
@parts = /(.{1,$part_length})/sg;

I don't think there's any need for an explanation here.
Perhaps I get around to do Quiz 2 anytime soon.

/ihb



dennis.jacob
New User

Mar 16, 2010, 4:41 AM

Post #8 of 8 (40219 views)
Re: [ihb] String Division (2 Quizzes in 1!) [In reply to] Can't Post

#!/usr/bin/perl
$a="Cooking is also one of the oldest of the arts. Some modern artists would have you believe that so-called
ephemeral art is a recent invention, but cooking has always been an ephemeral art.";

$size = 10; # number of strings to split

$str = (" A".int(length($a)/$size)) x $size . " A".(length($a)-(int(length($a)/$size)*$size)) ;
@arr = unpack ($str,$a);
print join "\n",@arr;

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives