range count

G

Gary Wessle

Hi
I have a vector<char> which looks like this (a d d d a d s g e d d d d
d k)
I need to get the biggest count of consecutive 'd'. 5 in this example

I am toying with this method but not sure if it is optimal.

thanks

int k = 0;
vector::const_iterator i = find(v.begin(), v.end(), 'r')
while ( i != v.end() ) {
vector::const_iterator j = find(i, v.end(), any_thing_but 'r')
if ( (j - i) > k ) k = (j - i)
i = j
}
 
D

Daniel T.

Gary Wessle said:
Hi
I have a vector<char> which looks like this (a d d d a d s g e d d d d
d k)
I need to get the biggest count of consecutive 'd'. 5 in this example

I am toying with this method but not sure if it is optimal.

thanks

int k = 0;
vector::const_iterator i = find(v.begin(), v.end(), 'r')
while ( i != v.end() ) {
vector::const_iterator j = find(i, v.end(), any_thing_but 'r')
if ( (j - i) > k ) k = (j - i)
i = j
}

I'll assume the 'r' was a typo. Shouldn't that last line be something
like "i = find( j, v.end(), 'r' );"?

This might be a useful time for for_each. (uncompiled, untested code)

struct count_consecutive: unary_function< char, void >
{
char comp;
unsigned count;
unsigned max_count;
count_same( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }
void operator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned result() const { return max( count, max_count ); }
}

k = for_each( v.begin(), v.end(), count_consecutive( 'd' ) ).result();

The nice thing about the above is that it can be used in an initializer.
 
G

Gary Wessle

Daniel T. said:
I'll assume the 'r' was a typo. Shouldn't that last line be something
like "i = find( j, v.end(), 'r' );"?

This might be a useful time for for_each. (uncompiled, untested code)

struct count_consecutive: unary_function< char, void >
{
char comp;
unsigned count;
unsigned max_count;
count_same( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }
void operator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned result() const { return max( count, max_count ); }
}

k = for_each( v.begin(), v.end(), count_consecutive( 'd' ) ).result();

The nice thing about the above is that it can be used in an initializer.

thank you for taking the time to post this, :) I am having hard time
understanding the code you gave because of my newbi status. I'd rather
write something I can grasp it for now till my level goes up.

here is my best shut

**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector;

#include <map>
using std::map;

class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();
int bigest_r(vector<char> const& cv);
bool not_r(char c);

public:
statistics(vector<char> const& cv);
~statistics();
map<char,int> get_counts;
};

#endif


**************** statistics.cpp ****************
#include <vector>
#include "statistics.h"

using namespace std;

statistics::statistics(vector<char> const& cv)
: v( cv )
{
statistics::stock_take();
}

void statistics::stock_take()
{
mp['c'] = count(v.begin(), v.end(), 'c');
mp['r'] = bigest_r(v);
}

bool statistics::not_r(char c)
{
return (c != 'r');
}

int statistics::bigest_r(vector<char> const& cv)
{
int k = 0;
vector_iterator i = find(cv.begin(), v.end(), 'r');
while (i != cv.end()){
vector_iterator j = find_if(i, cv.end(), not_r);
if ( (j-i) > k ) k = (j-i);
i = j;
}
return k;
}
};




**************** statistics_test.cpp ****************
#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include <utility>
using std::map;

#include "statistics.h"

int main() {

vector v = {c r r r d x c c d d d d k};
statistics st1(v);
cout << "c" << (st1.get_counts)[c]
<< "r" << (st1.get_counts)[r]
<< '\n';
}
 
D

Daniel T.

First, let me clean up what I wrote:

struct count_consecutive: unary_function< char, void >
{
char comp;
unsigned count;
unsigned max_count;

count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void operator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned result() const { return max( count, max_count ); }
};

k = for_each( v.begin(), v.end(), count_consecutive( 'd' ) ).result();
thank you for taking the time to post this, :) I am having hard time
understanding the code you gave because of my newbi status. I'd rather
write something I can grasp it for now till my level goes up.

That's fine. Let's look at the algorithm you said:
int statistics::bigest_r(vector<char> const& cv)
{
int k = 0;
vector_iterator i = find(cv.begin(), v.end(), 'r');
while (i != cv.end()){
vector_iterator j = find_if(i, cv.end(), not_r);
if ( (j-i) > k ) k = (j-i);
i = j;
}
return k;
}

Obviously your code doesn't compile, but I'm going to ignore that for
now and look at your algorithm:

a r r r a r s g e r r r r r k

what will your algorithm do with the chars above?

find will return element 1 (the second element in the array,) then
find_if will return element 4.

4 - 1 > 0 so k is assigned 3.

Now i will be set to point at element 4, and we loop back up.

That's not the end of the vector, so find_if will set j to point at
element 4 (the first element that is not_r.)

4 - 4 > 3 is false, so loop back up (with i and j both pointing at
element 4 still.)

Your stuck in an infinite loop.

You see, "i" is the beginning of your streak of 'r's, and "j" is the end
of the streak, but then you assign "i" to the end of the first streak of
'r's and expect things to still work. At the end of your while block,
you need to reset "i" to the beginning of the next streak of 'r's (hint,
use "find" again.)

As to the syntax... You need to define the type of "vector_iterator" and
"not_r" must be a global function, not a member function. (You could
make it a member function but it would be much more complicated and
pointless.
 
G

Gary Wessle

Daniel T. said:
First, let me clean up what I wrote:

struct count_consecutive: unary_function< char, void >
{
char comp;
unsigned count;
unsigned max_count;

count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void operator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned result() const { return max( count, max_count ); }
};

k = for_each( v.begin(), v.end(), count_consecutive( 'd' ) ).result();

what is : unary_function< char, void > after the struct name? and what
does it do?
can I replace the word struct with class and expect the same results?
I will stick with your code, mine is few steps behind.
 
G

Gary Wessle

Daniel T. said:
First, let me clean up what I wrote:

struct count_consecutive: unary_function< char, void >
{
char comp;
unsigned count;
unsigned max_count;

count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void operator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned result() const { return max( count, max_count ); }
};

k = for_each( v.begin(), v.end(), count_consecutive( 'd' ) ).result();




Obviously your code doesn't compile, but I'm going to ignore that for

I am embedding what you suggested in my code but would need some
direction, if you could please

**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector;

#include <map>
using std::map;

class count_consecutive: unary_function< char, void >
{
char comp;
unsigned count;
unsigned max_count;

public:
count_consecutive(char value);
~count_consecutive();
void operator()(char c);
unsigned result();
};


class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();
int bigest_r(vector<char> const& cv);

public:
statistics(vector<char> const& cv);
~statistics();
map<char,int> get_counts;
};

#endif




**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;

#include "statistics.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() const {
return max( count, max_count );
}



statistics::statistics(vector<char> const& cv)
: v( cv )
{
statistics::stock_take();
}

void statistics::stock_take()
{
mp['c'] = count(v.begin(), v.end(), 'c');
mp['r'] = bigest_r(v);
}


int statistics::bigest_r(vector<char> const& cv)
{
int k = for_each( cv.begin(), cv.end(),
count_consecutive( 'd' ) ).result();
return k;

}


**************** statistics_test.cpp****************
#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include "statistics.h"

int main() {

vector v = {c r r r d x c c d d d d k};
statistics st1(v);
cout << "c" << (st1.get_counts)[c]
<< "r" << (st1.get_counts)[r]
<< '\n';
}
 
R

Rolf Magnus

Gary said:
what is : unary_function< char, void > after the struct name?

The base type.
and what does it do?

Derive from it.
can I replace the word struct with class and expect the same results?

You'd have to make things explicitly public, e.g. by replacing the first 2
lines with:

class count_consecutive: public unary_function< char, void >
{
public:
 
D

Daniel T.

Gary Wessle said:
what is : unary_function< char, void > after the struct name? and what
does it do?
can I replace the word struct with class and expect the same results?
I will stick with your code, mine is few steps behind.

It is defined in <functional> and helps set up some typedefs. Strictly
speaking, it's not necessary for this example.
 
D

Daniel T.

Gary Wessle said:
I am embedding what you suggested in my code but would need some
direction, if you could please.

What's the first error the compiler give you and what line does it point
to?
 
G

Gary Wessle

Daniel T. said:
What's the first error the compiler give you and what line does it point
to?


the code and the error are as listed ( thank you for helping :) )

**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector;

#include <map>
using std::map;

class count_consecutive : public unary_function< char, void >
{

public:

char comp;
unsigned count;
unsigned max_count;
count_consecutive(char value);
~count_consecutive();
void operator()(char c);
unsigned result();
};


class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();
int bigest_r(vector<char> const& cv);

public:
statistics(vector<char> const& cv);
~statistics();
map<char,int> get_counts;
};

#endif


**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;

#include "statistics.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() const {
return max( count, max_count );
}



statistics::statistics(vector<char> const& cv)
: v( cv )
{
statistics::stock_take();
}

void statistics::stock_take()
{
mp['c'] = count(v.begin(), v.end(), 'c');
mp['r'] = bigest_r(v);
}


int statistics::bigest_r(vector<char> const& cv)
{
int k = for_each( cv.begin(), cv.end(),
count_consecutive( 'd' ) ).result();
return k;

}

**************** statistics_test.cpp ****************
#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include "statistics.h"

int main() {

vector v = {c r r r d x c c d d d d k};
statistics st1(v);
cout << "c" << (st1.get_counts)[c]
<< "r" << (st1.get_counts)[r]
<< '\n';
}


**************** error ****************
$ make
g++ -c -o statistics.o statistics.cpp
statistics.h:9: error: expected template-name before '<' token
statistics.h:9: error: expected `{' before '<' token
statistics.h:9: error: expected unqualified-id before '<' token
statistics.cpp:10: error: invalid use of undefined type 'class count_consecutive'
statistics.h:9: error: forward declaration of 'class count_consecutive'
statistics.cpp: In constructor 'count_consecutive::count_consecutive(char)':
statistics.cpp:11: error: class 'count_consecutive' does not have any field named 'comp'
statistics.cpp:12: error: class 'count_consecutive' does not have any field named 'count'
statistics.cpp:13: error: class 'count_consecutive' does not have any field named 'max_count'
statistics.cpp: At global scope:
statistics.cpp:16: error: invalid use of undefined type 'class count_consecutive'
statistics.h:9: error: forward declaration of 'class count_consecutive'
statistics.cpp: In member function 'void count_consecutive::eek:perator()(char)':
statistics.cpp:17: error: 'comp' was not declared in this scope
statistics.cpp:18: error: no pre-increment operator for type
statistics.cpp:20: error: 'max_count' was not declared in this scope
statistics.cpp:20: error: 'max' was not declared in this scope
statistics.cpp:21: error: overloaded function with no contextual type information
statistics.cpp: At global scope:
statistics.cpp:25: error: invalid use of undefined type 'class count_consecutive'
statistics.h:9: error: forward declaration of 'class count_consecutive'
statistics.cpp: In member function 'unsigned int count_consecutive::result() const':
statistics.cpp:26: error: 'max_count' was not declared in this scope
statistics.cpp:26: error: 'max' was not declared in this scope
statistics.cpp: In member function 'int statistics::bigest_r(const std::vector<char, std::allocator<char> >&)':
statistics.cpp:47: error: invalid use of undefined type 'class count_consecutive'
statistics.h:9: error: forward declaration of 'class count_consecutive'
make: *** [statistics.o] Error 1
fred@debian:~/myPrograms/backtest$
 
D

Daniel T.

Gary Wessle said:
the code and the error are as listed ( thank you for helping :) )

OK, the first 3 errors:
statistics.h:9: error: expected template-name before '<' token
statistics.h:9: error: expected `{' before '<' token
statistics.h:9: error: expected unqualified-id before '<' token

We can see that it deals with the file "statistics.h" at line 9. So
let's look at that line:
class count_consecutive : public unary_function< char, void >
{

Now, all three of the errors have a problem with what is just before the
'<' token so what is that? It's "unary_function". How can the compiler
have a problem with that, it's part of the standard library? Well, first
as part of the standard library it's in the std namespace. Also it's
defined in a file that might not have been included (it's defined in
<functional>.)

So, fix that and compile again.
 
M

Mark P

Gary said:
Hi
I have a vector<char> which looks like this (a d d d a d s g e d d d d
d k)
I need to get the biggest count of consecutive 'd'. 5 in this example

I am toying with this method but not sure if it is optimal.

thanks

int k = 0;
vector::const_iterator i = find(v.begin(), v.end(), 'r')
while ( i != v.end() ) {
vector::const_iterator j = find(i, v.end(), any_thing_but 'r')
if ( (j - i) > k ) k = (j - i)
i = j
}

How about the following?

int count_consecutive (const vector<char>& v, char c)
{
int current_count = 0;
int best_count = 0;
for (vector<char>::const_iterator it = v.begin(); it != v.end(); ++it)
if (*it == c)
best_count = max(best_count,++current_count);
else
current_count = 0;
return best_count;
}

Mark
 
G

Gary Wessle

Daniel T. said:
OK, the first 3 errors:

We can see that it deals with the file "statistics.h" at line 9. So
let's look at that line:


Now, all three of the errors have a problem with what is just before the
'<' token so what is that? It's "unary_function". How can the compiler
have a problem with that, it's part of the standard library? Well, first
as part of the standard library it's in the std namespace. Also it's
defined in a file that might not have been included (it's defined in
<functional>.)

So, fix that and compile again.

thank you

I added
#include <functional>
using std::unary_function;
to the statistics.h

similarly I added to statistics.cpp
using std::max

so that it shows like
#include <algorithm>
using std::count;
using std::max

the error now are
**************** error ****************
t$ make clean; make
rm -rf *.o proj
g++ -c -o statistics.o statistics.cpp
statistics.h:4: error: expected `;' before 'using'
statistics.cpp:29: error: prototype for 'unsigned int count_consecutive::result() const' does not match any in class 'count_consecutive'
statistics.h:23: error: candidate is: unsigned int count_consecutive::result()
make: *** [statistics.o] Error 1

here are the related sections of those files again
**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector; << --- line 4 I don't see a problem.

#include <functional>
using std::unary_function;

#include <map>
using std::map;


**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;

#include <algorithm>
using std::max


#include "statistics.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() const {
return max( count, max_count );
} << ------------- here is line 29, I really don't know what type max returns

on linux
$man::max returns nothing
The C++ Programming Language by Stroustrup did not have a easy-find
way in the index.
could you recommend a good ref. book and/or web link?

thanks
 
G

Gary Wessle

Mark P said:
How about the following?

int count_consecutive (const vector<char>& v, char c)
{
int current_count = 0;
int best_count = 0;
for (vector<char>::const_iterator it = v.begin(); it != v.end(); ++it)
if (*it == c)
best_count = max(best_count,++current_count);
brilliant

else
current_count = 0;
return best_count;
}

Mark

thanks, I simplified the code a lot because of your good idea but I am
getting

ps. I am still working out the other sub-thread in the hope I will
learn something.

**************** error ****************
$ make clean; make
rm -rf *.o proj
g++ -c -o statistics.o statistics.cpp
statistics.h:4: error: expected `;' before 'using'
make: *** [statistics.o] Error 1


here is the code
**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector;

#include <map>
using std::map;

class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();

public:
statistics(vector<char> const& cv);
~statistics();
map<char,int> get_counts();
};

#endif


**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::max

#include "statistics.h"

statistics::statistics(vector<char> const& cv)
: v( cv )
{
stock_take();
}

void statistics::stock_take()
{
char r = 'r';
char c = 'c';
int current_count = 0;
int best_count = 0;
for (vector<char>::const_iterator it = v.begin(); it != v.end(); ++it)
if (*it == r)
best_count = max(best_count,++current_count);
else
if (*it != r){
current_count = 0;
if (*it == c)
mp[c]++ ;
}
mp[r] = best_count;
}


map<char,int> statistics::get_counts(){
return mp;
}

**************** statistics_test.cpp ****************
#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include "statistics.h"

int main() {

vector v = {c r r r d x c c d d d d k};
statistics st1(v);
cout << "c" << (st1.get_counts)[c]
<< "r" << (st1.get_counts)[r]
<< '\n';
}
 
D

Daniel T.

Gary Wessle said:
the error now are
**************** error ****************
t$ make clean; make
rm -rf *.o proj
g++ -c -o statistics.o statistics.cpp
statistics.h:4: error: expected `;' before 'using'
statistics.cpp:29: error: prototype for 'unsigned int
count_consecutive::result() const' does not match any in class
'count_consecutive'
statistics.h:23: error: candidate is: unsigned int
count_consecutive::result()
make: *** [statistics.o] Error 1

here are the related sections of those files again
**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector; << --- line 4 I don't see a problem.

#include <functional>
using std::unary_function;

#include <map>
using std::map;


**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;

#include <algorithm>
using std::max


#include "statistics.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() const {
return max( count, max_count );
} << ------------- here is line 29, I really don't know what type max returns

on linux
$man::max returns nothing
The C++ Programming Language by Stroustrup did not have a easy-find
way in the index.
could you recommend a good ref. book and/or web link?

thanks

To understand the error at line four, you have to understand how the
#include mechanism works. What it does is replace the line where the
#include is with the contents of the file. It works just like a
copy/paste. Many times a syntax error in a program won't be caught by
the compiler until it parses through a line or two more in the code. So,
if you don't see the problem in statistics.h look just above where it is
included. Remember, the compiler was looking for a ';' before the
'using'...

Fix that, post the code and the next error and we will continue. This
really is how I do it by the way, fix the first error then recompile.
 
G

Gary Wessle

Daniel T. said:
Gary Wessle said:
the error now are
**************** error ****************
t$ make clean; make
rm -rf *.o proj
g++ -c -o statistics.o statistics.cpp
statistics.h:4: error: expected `;' before 'using'
statistics.cpp:29: error: prototype for 'unsigned int
count_consecutive::result() const' does not match any in class
'count_consecutive'
statistics.h:23: error: candidate is: unsigned int
count_consecutive::result()
make: *** [statistics.o] Error 1

here are the related sections of those files again
**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector; << --- line 4 I don't see a problem.

#include <functional>
using std::unary_function;

#include <map>
using std::map;


**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;

#include <algorithm>
using std::max


#include "statistics.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() const {
return max( count, max_count );
} << ------------- here is line 29, I really don't know what type max returns

on linux
$man::max returns nothing
The C++ Programming Language by Stroustrup did not have a easy-find
way in the index.
could you recommend a good ref. book and/or web link?

thanks

To understand the error at line four, you have to understand how the
#include mechanism works. What it does is replace the line where the
#include is with the contents of the file. It works just like a
copy/paste. Many times a syntax error in a program won't be caught by
the compiler until it parses through a line or two more in the code. So,
if you don't see the problem in statistics.h look just above where it is
included. Remember, the compiler was looking for a ';' before the
'using'...

ahha
no ";" after max in statistics.cpp
using std::max
Fix that, post the code and the next error and we will continue. This
really is how I do it by the way, fix the first error then recompile.

ok, I fixed this, and compiled, I changed the name of the files where
the word statistics appears to statistics2

**************** statistics2.h ****************
#ifndef STATISTICS2_H
#define STATISTICS2_H
#include <vector>
using std::vector;

#include <functional>
using std::unary_function;

#include <map>
using std::map;

class count_consecutive : public unary_function< char, void >
{

public:

char comp;
unsigned count;
unsigned max_count;
count_consecutive(char value);
~count_consecutive();
void operator()(char c);
unsigned result();
};


class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();
int bigest_r(vector<char> const& cv);

public:
statistics(vector<char> const& cv);
~statistics();
map<char,int> get_counts;
};

#endif



**************** statistics2.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;
using std::max;


#include "statistics2.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() {
return max( count, max_count );
}



statistics::statistics(vector<char> const& cv)
: v( cv )
{
statistics::stock_take();
}

void statistics::stock_take()
{
mp['c'] = count(v.begin(), v.end(), 'c');
mp['r'] = bigest_r(v);
}


int statistics::bigest_r(vector<char> const& cv)
{
int k = for_each( cv.begin(), cv.end(),
count_consecutive( 'd' ) ).result();
return k;

}

**************** statistics2_test.cpp ****************
#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include <map>
using std::map;

#include "statistics2.h"

int main() {

vector<char> v = {c r r r d x c c d d d d k};
statistics st1(v);
map<char, int> mci = st1.get_counts();
cout << "c" << mci['c']
<< "r" << mci['r']
<< '\n';
}


**************** error ****************
$ make clean; make
rm -rf *.o proj
g++ -c -o statistics2.o statistics2.cpp
g++ -c -o statistics_test2.o statistics_test2.cpp
statistics_test2.cpp: In function 'int main()':
statistics_test2.cpp:14: error: 'c' was not declared in this scope
statistics_test2.cpp:14: error: expected `}' before 'r'
statistics_test2.cpp:14: error: 'v' must be initialized by constructor, not by '{...}'
statistics_test2.cpp:14: error: expected ',' or ';' before 'r'
statistics_test2.cpp: At global scope:
statistics_test2.cpp:15: error: 'v' was not declared in this scope
statistics_test2.cpp:16: error: no match for call to '(std::map<char, int, std::less<char>, std::allocator<std::pair<const char, int> > >) ()'
statistics_test2.cpp:17: error: expected constructor, destructor, or type conversion before '<<' token
statistics_test2.cpp:20: error: expected declaration before '}' token
make: *** [statistics_test2.o] Error 1
fred@debian:~/myPrograms/backtest/res$
 
G

Gary Wessle

ok, if fixed them all, now it compiles, man what a learning
experience "many thanks to you".

the code does not give me what I want, but I will keep working on
that.

**************** statistics2.h ****************
#ifndef STATISTICS2_H
#define STATISTICS2_H
#include <vector>
using std::vector;

#include <functional>
using std::unary_function;

#include <map>
using std::map;

class count_consecutive : public unary_function< char, void >
{

public:

char comp;
unsigned count;
unsigned max_count;
count_consecutive(char value);
~count_consecutive(){}
void operator()(char c);
unsigned result();
};


class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();
int bigest_r(vector<char> const& cv);

public:
statistics(vector<char> const& cv);
~statistics(){}
map<char,int> get_counts();
};

#endif




**************** statistics2.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::count;
using std::max;


#include "statistics2.h"


count_consecutive::count_consecutive( char value )
: comp( value )
, count( 0 )
, max_count( 0 )
{ }

void count_consecutive::eek:perator()( char c ) {
if ( c == comp )
++count;
else {
max_count = max( count, max_count );
count = 0;
}
}

unsigned count_consecutive::result() {
return max( count, max_count );
}



statistics::statistics(vector<char> const& cv)
: v( cv )
{
statistics::stock_take();
}

void statistics::stock_take()
{
mp['c'] = count(v.begin(), v.end(), 'c');
mp['r'] = bigest_r(v);
}


int statistics::bigest_r(vector<char> const& cv)
{
int k = for_each( cv.begin(), cv.end(),
count_consecutive( 'd' ) ).result();
return k;

}
map<char,int> statistics::get_counts(){
return mp;
}


**************** statistics2_test.cpp ****************
#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include <map>
using std::map;

#include "statistics2.h"

int main() {

vector<char> v;
v.push_back('c');
v.push_back('r');
v.push_back('r');
v.push_back('c');
v.push_back('r');
v.push_back('r');
v.push_back('r');
v.push_back('r');
statistics st1(v);
map<char, int> mci = st1.get_counts();
cout << "c" << mci['c']
<< "r" << mci['r']
<< '\n';
}


**************** out put ****************
c2r0

**************** expected ****************
c2r4
 
G

Gary Wessle

Mark P said:
How about the following?

int count_consecutive (const vector<char>& v, char c)
{
int current_count = 0;
int best_count = 0;
for (vector<char>::const_iterator it = v.begin(); it != v.end(); ++it)
if (*it == c)
best_count = max(best_count,++current_count);
else
current_count = 0;
return best_count;
}

Mark

many thanks, here is the code after all the repairs

**************** statistics.h ****************
#ifndef STATISTICS_H
#define STATISTICS_H
#include <vector>
using std::vector;

#include <map>
using std::map;

class statistics
{
map<char, int> mp;
vector<char> v;
void stock_take();

public:
statistics(vector<char> const& cv);
~statistics(){}

map<char,int> get_counts();
};

#endif



**************** statistics.cpp ****************
#include <vector>
using std::vector;

#include <algorithm>
using std::max;

#include "statistics.h"

statistics::statistics(vector<char> const& cv)
: v( cv )
{
stock_take();
}

void statistics::stock_take()
{
char r = 'r';
char c = 'c';
int current_count = 0;
int best_count = 0;
for (vector<char>::const_iterator it = v.begin(); it != v.end(); ++it)
if (*it == r)
best_count = max(best_count,++current_count);
else
if (*it != r){
current_count = 0;
if (*it == c)
mp[c]++ ;
}
mp[r] = best_count;
}


map<char,int> statistics::get_counts(){
return mp;
}

**************** statistics_test.cpp ****************

#include <iostream>
using std::cout;

#include <vector>
using std::vector;

#include <map>
using std::map;

#include "statistics.h"

int main() {
vector<char> v;
v.push_back('c');
v.push_back('r');
v.push_back('r');
v.push_back('c');
v.push_back('r');
v.push_back('r');
v.push_back('r');
v.push_back('r');
statistics st1(v);
map<char, int> mci = st1.get_counts();
cout << "c" << mci['c']
<< "r" << mci['r']
<< '\n';
}

**************** output ****************
c2r4
 
D

Daniel T.

Gary Wessle said:
ok, if fixed them all, now it compiles, man what a learning
experience "many thanks to you".

the code does not give me what I want, but I will keep working on
that.

When you first posted about your problem, you seemed to be confused as
to whether you are trying to count the number of consecutive 'd's or the
number of consecutive 'r's. Your current code reflects that confusion.

Look at the function bigest_r. What are you trying to count?
 
B

bjarne

Gary said:
on linux
$man::max returns nothing
The C++ Programming Language by Stroustrup did not have a easy-find
way in the index.

Hmmm. Looked for max in the index, found max(), followed the first
reference to page 544 and found:

18.9 Min and Max
The algorithms described here select a value based on a comparison.
It is obviously useful to be
able to find the maximum and minimum of two values:

template<class T > const T& max (const T& a , const T& b )
{
return (a <b ) ? b : a ;
}

Is that really too difficult?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top