954,492 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Histogram of int array

write a program that read in an array of integers-- ideally from a text file. and then displays a histogram of those numbers, divided into the ranges 0-9, 10-19 ,20-29, and so forth, up to the range of containing only the valye 100.

Please help me to write a efficient and better code..

#include <iostream>
#include <iomanip>
#include "genlib.h"
#include "strutils.h"
#include <fstream>

void Histogram(int*); //Function prototype
void print(string*);

int main(){	
	int arr[10] = {2,4,5,23,26,29,6,100,100,80};	//integer array inialization
	ofstream out("arr.txt");	//open file for write
	for (int i =0;i<10;i++){   
		out << arr[i] << ' ';   // store data in file
	}
	
	for(int i=0;i<10;i++){
		arr[i]=0;                  //initialization array with zero, so can get values from file
	}
	out.close();                   //close is must.
	
	ifstream in("arr.txt");	       //open file for read
	for(int i=0;;i++){
		in >> arr[i];              // reading data from file into memory  
		if(in.fail()) break;
	}

	Histogram(arr);                //call Histogram Function

	return 0;
}

void Histogram(int *arr){
	string str[11];                    // for storing number of "*"
	for(int i =0;i<10;i++){
		if(arr[i]>=0 && arr[i] <10){
			str[0]+="*";
		}else
		if(arr[i]>=10 && arr[i] <20){
			str[1]+="*";
		}else
		if(arr[i]>=20 && arr[i] <30){
			str[2]+="*";
		}else		
		if(arr[i]>=30 && arr[i] <40){
			str[3]+="*";
		}else		
		if(arr[i]>=40 && arr[i] <50){
			str[4]+="*";
		}else		
		if(arr[i]>=50 && arr[i] <60){
			str[5]+="*";
		}else
		if(arr[i]>=60 && arr[i] <70){
			str[6]+="*";
		}else		
		if(arr[i]>=70 && arr[i] <80){
			str[7]+="*";
		}else		
		if(arr[i]>=80 && arr[i] <90){
			str[8]+="*";
		}else		
		if(arr[i]>=90 && arr[i] <100){
			str[9]+="*";
		}else		
		if(arr[i]==100){
			str[10]+="*";
		}
	}

	print(str); // call print function for display formated data
}

void print(string *str){
	int i,j =0;                  // Display data 
	for (i=0;i<=100,j<11;i+=10,j++){
		cout << setw(8)<< IntegerToString(i) + " :" << str[j] << endl;
	}	
}

Output remain the same as in the image file...

Attachments Histogram.cpp (1.8KB) output.jpg 3.51KB
yun
Light Poster
42 posts since May 2009
Reputation Points: 10
Solved Threads: 2
 

Are you sure that this program compiles? You seem to have used string in your code, but you haven't included <string.h> at all...!

Apart from that, could you tell us what IDE/compiler you are using... or does the code assume all objects to belong to the namespace std , because I don't see using namespace std; anywhere...??

Apart from that, you have two custom header files, which wedo not have, so how are we going to compile your program, seeing as some functions are defined in those header files...??

amrith92
Junior Poster
188 posts since Jul 2008
Reputation Points: 130
Solved Threads: 23
 
Are you sure that this program compiles? You seem to have used string in your code, but you haven't included <string.h> at all...!


That's because std::string is not declared in -- its in header file. And some compiler include with

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 
That's because std::string is not declared in -- its in header file. And some compiler include with

I hadn't realized that... thanks! :) ... But it does work as std::string in my IDE (Dev C++), and it (I mean, including <string.h> ) does not produce any backward warnings at all...

amrith92
Junior Poster
188 posts since Jul 2008
Reputation Points: 130
Solved Threads: 23
 

Ye program Run well as u can see the output of the program. i m using microsoft visual studio 2005 and the header files u r talking about related to university meterial which include
IntegerToString(int) lot of other helpfull functionse. and yes ofcourse using namespace std; is very important but genlib.h have info about it..... thanks for the reply..

yun
Light Poster
42 posts since May 2009
Reputation Points: 10
Solved Threads: 2
 

Another approach might be to display as you go. Here's some pseudocode to rough out how that might work:

1) declare variables needed---stream to read file and two int variables
2) use a while loop to read in numbers from file

body of the while loop will:
3) divide number read in from file by 10 using integer math
4) increase the number obtained in 3) by one
5) use another loop to display the number of *s indicated by the number obtained in 4)
6) start a new line

Lerner
Nearly a Posting Maven
2,382 posts since Jul 2005
Reputation Points: 739
Solved Threads: 396
 

Another approach might be to display as you go. Here's some pseudocode to rough out how that might work:

1) declare variables needed---stream to read file and two int variables 2) use a while loop to read in numbers from file

body of the while loop will: 3) divide number read in from file by 10 using integer math 4) increase the number obtained in 3) by one 5) use another loop to display the number of *s indicated by the number obtained in 4) 6) start a new line

Yeah, this is a good algorithm to use for the same...

amrith92
Junior Poster
188 posts since Jul 2008
Reputation Points: 130
Solved Threads: 23
 
and it (I mean, including <string.h> ) does not produce any backward warnings at all...

why should the compiler produce warnings? string.h defines functions such as strcmp(), strcat(), etc. which are related to character arrays, not std::string. Those functions and that header file were inherited from C language.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

Instead of the big if...else if block, how about

for( int i = 0; i < 10; i++ )
{
  index = arr[i] / 10; 
    str[index] += "*";
}
vmanes
Posting Virtuoso
1,914 posts since Aug 2007
Reputation Points: 1,268
Solved Threads: 228
 

And for your future reference, when you have an if...else if block that is separating values into range groupings, you don't need to test both upper and lower bounds in the succeeding conditions.

if( arr[i] >= 0 && arr[i] < 10 )
{
	str[0] += "*";
}
else 	if( arr[i] < 20 )
{
	str[1] += "*";
}
else 	if( arr[i] < 30 )
{
		//and so on

The fact that you arrive at the test for < 20 means the value must be >= 10 to have not been caught by the first test, and so on.

And do be afraid to put a space between operators and operands - it makes the code a bit more readable. Spaces are cheap.

vmanes
Posting Virtuoso
1,914 posts since Aug 2007
Reputation Points: 1,268
Solved Threads: 228
 

Instead of the big if...else if block, how about

for( int i = 0; i < 10; i++ )
{
  index = arr[i] / 10; 
    str[index] += "*";
}

Thanks for the efficient code.. Best Regards.

yun
Light Poster
42 posts since May 2009
Reputation Points: 10
Solved Threads: 2
 

Instead of the big if...else if block, how about

for( int i = 0; i < 10; i++ )
{
  index = arr[i] / 10; 
    str[index] += "*";
}


obove code work well, but what if i want Histogram output in vertical order.? plz help

yun
Light Poster
42 posts since May 2009
Reputation Points: 10
Solved Threads: 2
 

Once you have the data stored (counted), find the largest value. Then begin printing lines, looking at each count, print an asterisk as needed, line by line

vmanes
Posting Virtuoso
1,914 posts since Aug 2007
Reputation Points: 1,268
Solved Threads: 228
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You