Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Counting consecutive array elements from array

Status
Not open for further replies.

arun10427

Programmer
Oct 24, 2009
29
US
Hi all

I am a perl newbie! And i am confused as to how to use arrays..

After some operation, my @array consists of lotta numbers..when i print @array, I get something like 1111111123448395911111111111245 etc..

I need to count the consecutive ones and store it in an array. Is there anything I could do?
 
Not sure just what you are asking but one possible solution would be the 'foreach' function which will iterate through your array 1 character at a time. You can then perform whatever action you require for each character.

Keith
 
I need to count the consecutive ones and store it in an array.

To me this means you either want to count the number of elements in the array:

Code:
my $numberofelements = @array;
print "$numberofelements\n";

Or you want to add all the numbers together to produce a total:

Code:
my $total;
foreach my $current (@array) {
     $total += $current;
}
print "$total\n";

Either way, as audiopro pointed out, a foreach loop is often used to process an array, 1 element at a time.

Chris
 
Thanks for your replies guys.
I guess I could explain my problem more clearly.
If I have the array elements as 1,1,1,1,1,1,2,1,1,1,3,1,1,1

Then I want the output as 6 3 3 , the number of times 1 occurs until a different integer occurs, and again the count continues.
Hope that helps.
Thanks :)
 
I am trying to help you work the answer out for yourself rather than just provide a solution. The best way to learn in my opinion.
In your example of output, how do you know which number was repeated?
What are you doing with the data?

Keith
 
Hi,

I've had a quick play and think something like this would be what you are looking for:

Code:
#!/usr/bin/perl

use strict;

my @array = (1,1,1,1,1,1,2,1,1,1,3,3,1,1,1,1,1,2,2,2,3,4,5,8,9,9);

my $consecutiveItems = [];
my $consecutiveHash = {};
my $lastElem = undef;
my $count = 0;

# gather data...
foreach my $elem (@array) {
	
	if ($elem != $lastElem) {
		push @$consecutiveItems, $consecutiveHash if $consecutiveHash->{$lastElem} > 1;
		
		# reset hash
		$consecutiveHash = {};
	}
	
	++$consecutiveHash->{$elem};
	
	# exit condition check...
	if ($count == $#array) {
		push @$consecutiveItems, $consecutiveHash if $consecutiveHash->{$lastElem} > 1;
	}
	
	$lastElem = $elem;
	++$count;
}

# print out results...
foreach my $item (@$consecutiveItems) {
	my ($number, $value) = each %$item;
	
	print "\nNumber: $number\tConsecutive Matches: $value";
}

This is very simple and builds an array of hashes that store consecutive matches. This could be adapted quickly to work for strings.

Hope this helps!

Thanks.

Steven Parker
 
A rough script which counts the number of times a number is seen consecutively, then resets when a new number is seen. With your input data the output will be 6 1 3 1 3. Still not 100% clear what you are trying to achieve though. If you would like to count how many times a number occurs throughout the entire array, build a hash within the foreach loop like $hash{$_} += 1;.

Code:
#! /usr/bin/perl
use strict;

my @input = (1,1,1,1,1,1,2,1,1,1,3,1,1,1);
my ($marker1,%hash,@output);
my $marker2 = 0;

foreach (@input) {
     if ($marker1 != $_) {
          $marker1 = $_;
          $marker2++;
     }
     $hash{$marker2} += 1;
}

foreach my $key(sort(keys(%hash))) {
     push(@output,$hash{$key});
}

#Prints 6 1 3 1 3
print "@output\n";

Chris
 
Hi All!

Thanks for the efforts. It surely is Useful!

Why I need to do this

- I am using a perl code to read a DBF file which has timestamps in 1 of its column- field. I am using xBase for it..My code needs to check the consecutive timestamps and if the count of the consecutive timestamps is less than 100,I need to delete those records. So I wrote a script which populates the difference between current timestamp and prev timestamp when i traverse through the list.
This is my code till now
Code:
#!C:\perl\bin
use Date::Day;
use warnings;
use XBase;
my $data7 = @_;
my $sum = 0;
my $table = new XBase "input.dbf";
my $first = $table->get_record(0,"TimeStamp");
my $second = $table->get_record(1,"TimeStamp");
my $iff = $second - $first;

print $iff;
my $final;
my $array = @_;
my $count = 0;
my $data9 = @_;
my @array=();
for (my $i=2;$i<$table->last_record;$i++)
{
	@data7 = $table->get_record($i,"TimeStamp");
	@data8 = $table->get_record($i-1,"TimeStamp"); 	
        $data9 = $data7[1] - $data8[1];
	push(@array,$data9);	
	
}
#my @array2 =(1,1,1,1,1,1,1,1,1,2,1,1);
my $cout=0;
$array[0]=1;

for(my $j=1;$j<@array;$j=$j+1)
{
if($array[$j]==1)
{
if($array[$j]==$array[$j-1])
{
	$cout=$cout+1;
}
else {next;}
}

}

I am totally new to perl. Any input for the same would be helpful..
 
maybe you should just do it here

Code:
my @array=();
my $old_diff;
my $old_count;
for (my $i=2;$i<$table->last_record;$i++){    
@data7 = $table->get_record($i,"TimeStamp");    
@data8 = $table->get_record($i-1,"TimeStamp");             $data9 = $data7[1] - $data8[1];    
if ($data9 == $old_diff) {
 $old_count++;
}
else {
 if ($old_count >= '100') {
  #Do something here with your data
  print "$old_diff $old_count;
 }
 $old_count = 0;
}

$old_diff = $data9;
#Just leave the push here if you need it for something else
push(@array,$data9);        
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top