Your skill will accomplishwhat the force of many cannot PerlMonks

### string functions

by valavanp (Curate)
 on Oct 25, 2006 at 08:34 UTC Need Help??

valavanp has asked for the wisdom of the Perl Monks concerning the following question:

I have a string. \$a="2A2B2C". The values of A,B,C are stored in an array @p=(1.5,2.5,3.5). The result of \$a should be like this: (AA)*(50/100) (BB)*(55/100) (CC)*(60/100). The values of A,B,C should be repeated according to the adjacent number before that character. I may be wrong somewhere in the coding. The answer should be 28.4238 where as i am getting 2.165625. Here is the code which i used:
```\$a="2A2B2C";
@p=(1.5,2.5,3.5);
#print substr(\$a,0,1);
#print "\n";
\$b=length(\$a);
print "\$b\n";
for(\$i=0;\$i<\$b;\$i++){
\$a=~s/(\d+)(.)/\$2 x \$1/ge;
}
#print \$a;
for(1..\$b)
{
if(1==\$_)
{
\$c=substr(\$a,0,1);
\$r1=\$p[0]*(50/100);
print \$r1;
}
elsif(2==\$_)
{
\$c2=substr(\$a,1,1);
#print "\n\$c";
}
elsif(3==\$_)
{
\$c3=substr(\$a,2,1);
\$r2=\$p[1]*(55/100);
print "\n\$r2";
}
elsif(4==\$_)
{
\$c4=substr(\$a,3,1);
#print "\n\$c";
}
elsif(5==\$_)
{
\$c5=substr(\$a,3,1);
\$r3=\$p[2]*(60/100);
#print "\n\$r3";
}
elsif(6==\$_)
{
\$c6=substr(\$a,5,1);
#print "\n\$c";
}
}

Replies are listed 'Best First'.
Re: string functions
by Corion (Patriarch) on Oct 25, 2006 at 08:54 UTC

There are many errors or weird things in your program

1. You are not indenting your code properly so it is very hard to see what loop goes around what code.
2. Your string expansion is very weird. Why do you expand your string 2A2B2C in a loop when the regular expression already does the complete expansion?
3. Your string length calculation is wrong. You calculate the length of the unexpanded string 2A2B2C instead of calculating the length of the expanded string. Also, name your length variable something better than \$b. Maybe call it \$string_length or \$sequence_length, so that you and others understand what you are doing.
4. Your if ... elsif ... structure is very, very bad and error prone. If you want to associate a letter with a value, a hash is the natural structure:
```my %value = (
A => 1.5,
B => 2.5,
C => 3.5,
);

my %factor = (
A => 50/100,
B => 55/100,
C => 60/100,
);

You can then easily split up your string and calculate the numbers.

```my @letters = split //, \$expanded_string;
my \$result = 0;
for my \$letter (@letters) {
\$result = \$result + \$value{ \$letter } * \$factor{ \$letter };
};

print \$result;

With these changes, I get a result of 8.45, so either your calculation of 28.4238 is wrong or you need to explain how you arrive at that number. Basically, my code calculates the following number:

```\$result = 1.5 * (50/100) * 2 + 2.5 * (55/100) * 2 + 3.5 * (60/100) * 2
A reply falls below the community's threshold of quality. You may see it by logging in.
Re: string functions
by Samy_rio (Vicar) on Oct 25, 2006 at 09:32 UTC

Hi valavanp, Try like this,

```use strict;
use warnings;
my \$str = "2A2B2C";
my %p = (A => 1.5, B => 2.5, C => 3.5);

my @arr = split/(?=\d+)/, \$str;
my \$range = 50;
map{s/^(\d+)([^\d]+)\$/((\$p{\$2}."\*") x \$1)."\$range\/100"/e; \$range+=5;
+}@arr;
\$str = eval join'*', @arr;

print \$str;

Updated
valavanp, see below for The range is (50,55,60,65,70,75,80,85,90). How can i code that. your solutions.

```use strict;
use warnings;
my \$str = "2A2B2C";
my %p = (A => 1.5, B => 2.5, C => 3.5);

my @arr = split/(?=\d+)/, \$str;
my @range = (50,55,60,65,70,75,80,85,90);
my \$i =0;
map{s/^(\d+)([^\d]+)\$/((\$p{\$2}."\*") x \$1)."\$range[\$i]\/100"/e; \$i++;}
+@arr;
\$str = eval join'*', @arr;

print \$str;

Regards,
Velusamy R.

eval"print uc\"\\c\$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

A reply falls below the community's threshold of quality. You may see it by logging in.
Re: string functions
by holli (Abbot) on Oct 25, 2006 at 09:32 UTC
The following uses regexes and eval:
```use strict;
use warnings;

my @p = (1.5, 2.5,  3.5 );
my @m = (0.5, 0.55, 0.60);

my \$a="2A2B2C";

sub calc
{
my \$i = shift;
my \$j = ord(shift)-65;

my \$r = \$p[\$j];

\$r *= \$p[\$j]
for (0..\$i-2);

return \$r * \$m[\$j];
}

\$a=~ s/([0-9]+)([A-Z])/(calc(\$1,"\$2"))/g;
\$a=~ s/\)\(/)*(/g;

eval "\\$a = \$a;";
print \$a; #28.423828125

holli, /regexed monk/
A reply falls below the community's threshold of quality. You may see it by logging in.
A reply falls below the community's threshold of quality. You may see it by logging in.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://580509]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (2)
As of 2023-06-10 17:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How often do you go to conferences?

Results (39 votes). Check out past polls.

Notices?