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...

Recommended Answers

All 12 Replies

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 we do not have, so how are we going to compile your program, seeing as some functions are defined in those header files...??

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 <string.h> -- its in <string> header file. And some compiler include <string> with <fstream>

commented: Correct! +6

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

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...

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..

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

commented: Nicely put !!! +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

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

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.

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

for( int i = 0; i < 10; i++ )
{
  index = arr[i] / 10; 
    str[index] += "*";
}
commented: Nice, clean code :) +1

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.

commented: Spaces are cheap use it...Good one !!! :) +2

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.

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

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

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.