I'm trying to write a Java program that generates a histogram of asterisks for each occurrence of a value in an array.
If the elements are, respectively, 0,1,2,3,4,5,6,7,8,9 the output should have an asterisk for each occurrence. For example,
0:*
1:*
2:*
3:*
4:*
5:*
6:*
7:*
8:*
9:*
However, my output is
0:**********
1:
2:
3:
4:
5:
6:
7:
8:
9:
The following code below is my own.
public static void drawHistogram(double[] array) {
String count = "";
for (int i = 0; i < array.length; i++) {
if (array[i] >= 0 && array[i] < 1) {
count += "*";
} else if (array[i] >= 1 && array[i] < 2) {
count += "*";
} else if (array[i] >= 2 && array[i] < 3) {
count += "*";
} else if (array[i] >= 3 && array[i] < 4) {
count += "*";
} else if (array[i] >= 4 && array[i] < 5) {
count += "*";
} else if (array[i] >= 5 && array[i] < 6) {
count += "*";
} else if (array[i] >= 6 && array[i] < 7) {
count += "*";
} else if (array[i] >= 2 && array[i] < 8) {
count += "*";
} else if (array[i] >= 2 && array[i] < 9) {
count += "*";
} else if (array[i] >= 9 && array[i] < 10) {
count += "*";
} else if (array[i] >= 10 && array[i] < 11) {
count += "*";
}
}
for (int j = 0; j <= 10; j++) {
System.out.print(j + count);
count = "";
System.out.println();
}
}
How can I fix this issue?
This solution uses (int) Math.floor(array[i]) to choose the bracket into which to put the double value, thus getting rid of the multiple if-then-else statements. I've also used StringBuilder instead of String to make the repeated concatenation of asterisks a little more efficient.
public static void drawHistogram(double[] array) {
StringBuilder histoGram[] = new StringBuilder[11];
for (int i = 0; i < histoGram.length; i++) {
histoGram[i] = new StringBuilder();
}
for (int i = 0; i < array.length; i++) {
int bracket = (int) Math.floor(array[i]);
if (bracket >= 0 && bracket < histoGram.length) {
histoGram[bracket].append("*");
}
}
for (int j = 0; j < 11; j++) {
System.out.format("%02d: %s\n", j, histoGram[j].toString());
}
}
Test main method:
public static void main(String args[]) {
double[] testValues = new double[100];
for (int i = 0; i < 100; i++) {
testValues[i] = Math.random() * 11.0;
}
drawHistogram(testValues);
}
Sample output:
00: *******
01: ********
02: ***********
03: ************
04: ********
05: **********
06: *******
07: ********
08: **********
09: ************
10: *******
public static void drawHistogram(double[] array) {
String count[] = new String[array.length];
for (int i = 0; i < array.length; i++) {
if (array[i] >= 0 && array[i] < 1) {
count[0] = "*";
} else if (array[i] >= 1 && array[i] < 2) {
count[1] = "*";
} else if (array[i] >= 2 && array[i] < 3) {
count[2] = "*";
} else if (array[i] >= 3 && array[i] < 4) {
count[3] = "*";
} else if (array[i] >= 4 && array[i] < 5) {
count[4] = "*";
} else if (array[i] >= 5 && array[i] < 6) {
count[5] = "*";
} else if (array[i] >= 6 && array[i] < 7) {
count[6] = "*";
} else if (array[i] >= 2 && array[i] < 8) {
count[7] = "*";
} else if (array[i] >= 2 && array[i] < 9) {
count[8] = "*";
} else if (array[i] >= 9 && array[i] < 10) {
count[9] = "*";
} else if (array[i] >= 10 && array[i] < 11) {
count[10] = "*";
}
}
for (int j = 0; j <= 10; j++) {
System.out.print(j + count[j]);
System.out.println();
}
}
It seems that you are using only a single variable to count up the occurrences of numbers in this method. This results in you program showing that 0 has nine occurrences and the rest of the numbers have 0 occurrences. I agree with the user David Choweller in the comments, who suggested that you could use an array to solve this problem. However, another solution might be a HashMap, where you store the number as the key, and the string that you want to print out as the value. Then, you can use the loop through the numbers at the end as you do currently, and print out the values associated with them.
You can use a Java Hasmap :
int myArray[] = new int[]{1, 2, 1, 3, 3, 1, 2, 1, 5, 1};
public static void main (String args[]) {
HashMap<Integer, String> hash = new HashMap<>();
hash.put(5, "");
hash.put(4, "");
hash.put(3, "");
hash.put(2, "");
hash.put(1, "");
for (int i = 0; i < myArray.length; i++){
hash.put(new Integer(myArray[i]), hash.get(myArray[i])+"*");
}
for(Integer key: hash.keySet()){
System.out.println(key+": "+ hash.get(key));
}
}
Related
I am writing this program and all of a sudden null appears in the output:
1-10 |null**********
11-20 |null**********
21-30 |null
31-40 |null
41-50 |null
it should be like this:
1-10 |**********
11-20 |**********
21-30 |
31-40 |
41-50 |
This is my code:
import java.util.Arrays;
public class Ex4Method {
public void Average(int[] a) {
int total = 0;
for (int i = 0; i < a.length; i++) {
total = total + a[i];
}
int average = total / a.length;
System.out.println(" ");
System.out.println("Average: " + average);
}
public void MaxAndRange(int[] b) {
int min = b[0];
int max = b[0];
for (int i = 0; i <= 19; i++) {
//System.out.println(i);
if (b[i] < min) {
min = b[i];
}
if (b[i] > max) {
max = b[i];
}
}
int range = max - min;
System.out.println("Maximum Number: " + max);
System.out.println("Range: " + range);
}
public void Median(int[] c) {
Arrays.sort(c);
double median = 0;
System.out.println("Median: " + median);
}
public void findMedian(int a[]) {
// First we sort the array
Arrays.sort(a);
double median;
if (a.length % 2 == 0) {
median = ((double) a[a.length / 2] + (double) a[a.length / 2 - 1]) / 2;
} else {
median = (double) a[a.length / 2];
}
System.out.println("Median: " + median);
}
public void Mode(int[] d) {
int maxValue = 0, maxCount = 0;
for (int i = 0; i < d.length; i++) {
int count = 0;
for (int j = 0; j < d.length; j++) {
if (d[j] == d[i]) {
count++;
}
}
if (count > maxCount) {
maxCount = count;
maxValue = d[i];
}
}
System.out.println("Mode: " + maxValue);
}
public void Histogram(int[] f) {
String[] asterisk = new String[6];
System.out.println("Histogram: ");
System.out.println(" ");
for (int i = 0; i <= f.length - 1; i++) {
if (f[i] >= 1 && f[i] <= 10) {
asterisk[1] += "*";
}
if (f[i] >= 11 && f[i] <= 20) {
asterisk[2] += "*";
}
if (f[i] >= 21 && f[i] <= 30) {
asterisk[3] += "*";
}
if (f[i] >= 31 && f[i] <= 40) {
asterisk[4] += "*";
}
if (f[i] >= 41 && f[i] <= 50) {
asterisk[5] += "*";
}
}
System.out.println(" 1-10 |" + asterisk[1]);
System.out.println("11-20 |" + asterisk[2]);
System.out.println("21-30 |" + asterisk[3]);
System.out.println("31-40 |" + asterisk[4]);
System.out.println("41-50 |" + asterisk[5]);
}
}
MAIN CLASS-
import TurtleGraphics.KeyboardReader;
public class ArrayEx4 {
public static void main(String[] args) {
KeyboardReader reader = new KeyboardReader();
Ex4Method object = new Ex4Method();
int[] nums = new int[20];
int i = 0;
System.out.print("Enter a number (1-50): ");
nums[i] = reader.readInt();
while (nums[i] >= 1 && nums[i] <= 50 && i < 19) {
i++;
System.out.print("Enter a number (1-50): ");
nums[i] = reader.readInt();
//occurences[nums[i]]++;
}
//for(int x=0;x<=4;x++) {
//System.out.println(occurences[x]);
//}
object.Average(nums);
object.MaxAndRange(nums);
object.findMedian(nums);
object.Mode(nums);
object.Histogram(nums);
}
}
Any suggestions? Thanks
This is the code right here:
public void Histogram(int[] f) {
String[] asterisk = new String[6];
System.out.println("Histogram: ");
System.out.println(" ");
for (int i = 0; i <= f.length - 1; i++) {
if (f[i] >= 1 && f[i] <= 10) {
asterisk[1] += "*";
}
if (f[i] >= 11 && f[i] <= 20) {
asterisk[2] += "*";
}
if (f[i] >= 21 && f[i] <= 30) {
asterisk[3] += "*";
}
if (f[i] >= 31 && f[i] <= 40) {
asterisk[4] += "*";
}
if (f[i] >= 41 && f[i] <= 50) {
asterisk[5] += "*";
}
}
System.out.println(" 1-10 |" + asterisk[1]);
System.out.println("11-20 |" + asterisk[2]);
System.out.println("21-30 |" + asterisk[3]);
System.out.println("31-40 |" + asterisk[4]);
System.out.println("41-50 |" + asterisk[5]);
}
More specifically, this part:
asterisk[i] += "*";
In Java, + operator for strings means concatenation, and both operands are converted to strings beforehand.
At the very beginning, new String[6] is filled with default values for String type, which, for any type inherited from java.lang.Object is a null value. When you concatenate using operators, the very first pass over any slot in the array will always encounter a null value.
And
String.valueOf(null) + "*"
will output "null*"
Take input from user in an array in form of numeric and show histogram Where i'm wrong The code is given in java the user can enter 5 input in number and histogram should show in any form with no constraints
package p21;
import java.util.Scanner;
public class P21 {
public static void main(String[] args) {
{
int count[] = new int[10]; // count array will keep elements of element
// in particular range;
int elements[]; // for example 27 15 34 22 11 11 19
{ // in above input there is count[0]=0;
for (int i = 0; i < elements.length; i++) // count[1]=4 and count[2]=2 and count[3]=1;
{
if (elements[i] >= 0 && elements[i] < 50) {
if (elements[i] < 10) {
count[0]++;}
else if (elements[i] >= 10 && elements[i] < 20) {
count[1]++;}
else if (elements[i] >= 20 && elements[i] < 30) {
count[2]++;}
else if (elements[i] >= 30 && elements[i] < 40) {
count[3]++;}
else {
count[4]++;
}}
else if (elements[i] >= 50 && elements[i] <= 100) {
if (elements[i] < 60) {
count[5]++;}
else if (elements[i] >= 60 && elements[i] < 70) {
count[6]++;}
else if (elements[i] >= 70 && elements[i] < 80) {
count[7]++;}
else if (elements[i] >= 80 && elements[i] < 90) {
count[8]++;}
else {
count[9]++;
}}}}
{
System.out.println("Histogram of the elements:");
for (int i = 0; i < count.length; i++) // this loop will print line
{
for (int j = 0; j < count[i]; j++) // this will print elements element(*)
{ // at each line.
System.out.print("* ");
}
if (count[i] != 0) // if line does'nt contain zero
System.out.println(""); // then if will change the row;
}
}
}
/*
in above code if count[i]=zero means if there is elements
element in particular range say [0-9] then it will
elementst jump on next line;
*/
{
{
Histogram hg = new Histogram();
System.out.println("Enter the elements of Elements want in a Histogram:");
Scanner sc = new Scanner(System.in);
int noOfElements = sc.nextInt();
int histogramElements[] = new int[noOfElements];
System.out.println("Enter the Elements for Histogram:");
for (int i = 0; i < noOfElements; i++) {
histogramElements[i] = sc.nextInt();
}
hg.showHistogram(histogramElements);
}
For your binning approach..... since you only care about groups of 10. Divide the input number by 10. Bound the divided result then use the result to index your counter array.
I want to turn a string of binary to hexadecimal string
For example, I have a length of 24 binary string
"000100000010000000110000"
Convert hex becomes 0x10 0x20 0x30
How can I do?
I made reference to this: http: //stackoverflow.com/questions/25592084/converting-binary-string-to-a-hexadecimal-string-java
But I tried the results are not correct ...
I was wrong in what I ask?
int digitNumber = 1;
int sum = 0;
String binary = "00000001";
for(int i = 0; i < binary.length(); i++)
{
if(digitNumber == 1)
sum+=Integer.parseInt(binary.charAt(i) + "")*8;
else if(digitNumber == 2)
sum+=Integer.parseInt(binary.charAt(i) + "")*4;
else if(digitNumber == 3)
sum+=Integer.parseInt(binary.charAt(i) + "")*2;
else if(digitNumber == 4 || i < binary.length()+1)
{
sum+=Integer.parseInt(binary.charAt(i) + "")*1;
digitNumber = 0;
if(sum < 10)
System.out.print("0x"+sum);
else if(sum == 10)
System.out.print("A");
else if(sum == 11)
System.out.print("B");
else if(sum == 12)
System.out.print("C");
else if(sum == 13)
System.out.print("D");
else if(sum == 14)
System.out.print("E");
else if(sum == 15)
System.out.print("F");
sum=0;
}
digitNumber++;
}
}
The result is ...
0x00x1
Try this:
Integer.parseInt(binOutput, 2) instead of Integer.parseInt(binOutput)
//Here is my Solution:
package stringprocessing;
/**
*
* #author zayeed
*/
public class StringProcessing {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int index = 0;
String bin = "0000000101100101011011100110011100000001000000000000000010101010010101100110010101100011011010010110110101100001001000000100111001100101011101000111011101101111011100100110101101110011001000000100100001000001010100110010000001001001010100110101001101010101010001010100010000100000010000010010000001010010010001010101000101010101010010010101001001000101010001000010000001010111010001010100010101001011010011000101100100100000010101000100010101010011010101000010000001000110010011110101001000100000010101000100100001000101001000000100011001001111010011000100110001001111010101110100100101001110010001110010000001000011010011110101010101001110010101000100100101000101010100110010111101000001010100100100010101000001010100110011101000100000010100000110100101101110011000010110110000101100001000000100000101011010001110110010000001000001010101000010000000000001111000000011000100110010001110100011000100110011001000000101000001001101001000000100111101001110";
String[] hexString = new String[bin.length() / 4];
for (int i = 0; i < bin.length() / 4; i++) {
hexString[i] = "";
for (int j = index; j < index + 4; j++) {
hexString[i] += bin.charAt(j);
}
index += 4;
}
for (int i = 0; i < bin.length() / 4; i++) {
System.out.print(hexString[i] + " ");
}
// System.out.println("\n" + bin.length());
String[] result = binaryToHex(hexString);
for (int i = 0; i < result.length; i++) {
System.out.print("" + result[i].toUpperCase());
}
System.out.println("");
}
public static String[] binaryToHex(String[] bin) {
String[] result = new String[bin.length];
for (int i = 0; i < bin.length; i++) {
result[i] = Integer.toHexString(Integer.parseInt(bin[i], 2));
}
//return Integer.toHexString(Integer.parseInt(bin[0], 2));
return result;
}
}
I have s a 2-dimensional array with lots of rows and columns, with random numbers between 0 and 255. I'm trying to look for instances of particular integers within my array, i.e. those between 231 and 255, and simply print out a String, i.e. "/", "." or a space, each time it comes across such integers. I suppose the following code only works for columns. How might I extend this into rows?
int[][] result = function(parameter);
System.out.println(Arrays.deepToString(result));
for (int i = 1; i <= result.length-1; i++) {
if (result[i][i] >= 179 && result[i][i] <= 204) {
System.out.print("\\");
}
if (result[i][i] >= 205 && result[i][i] <= 230) {
System.out.print(".");
}
if (result[i][i] >= 231 && result[i][i] <= 255) {
System.out.print(" ");
}
}
You can simply traverse the rows as well, If I understood what you want correctly
int[][] result = function(parameter);
System.out.println(Arrays.deepToString(result));
for (int row = 0; row < result.length; row++) {
for (int col= 0; col< result[0].length; col++) {
if (result[row][col] >= 179 && result[row][col] <= 204) {
System.out.print("\\");
}
if (result[row][col] >= 205 && result[row][col] <= 230) {
System.out.print(".");
}
if (result[row][col] >= 231 && result[row][col] <= 255) {
System.out.print(" ");
}
}
}
You code is only testing elements on the diagonal of the 2d array. You should have a nested loop in order to loop over the entire array :
for (int i = 0; i <= result.length-1; i++) {
for (int j = 0; j <= result[i].length-1; j++) {
if (result[i][j] >= 179 && result[i][j] <= 204) {
System.out.print("\\");
}
if (result[i][j] >= 205 && result[i][j] <= 230) {
System.out.print(".");
}
if (result[i][j] >= 231 && result[i][j] <= 255) {
System.out.print(" ");
}
}
System.out.println("");
}
If I understand your question, then I believe the easiest approach is to use a StringBuilder and dynamically build your output String. Iterate each array in your multidimensional array, and test each value (using else so that each test doesn't logically exclude the previous tests) like
int[][] result = { { 1, 179 }, { 205, 231 }, { 256 } };
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < result.length; i++) {
int[] arr = result[i];
if (i != 0) {
sb.append(", ");
}
sb.append("[");
for (int j = 0; j < arr.length; j++) {
if (j != 0) {
sb.append(", ");
}
if (arr[j] >= 179 && arr[j] <= 204) {
sb.append("\\");
} else if (arr[j] >= 205 && arr[j] <= 230) {
sb.append(".");
} else if (arr[j] >= 231 && arr[j] <= 255) {
sb.append(" ");
} else {
sb.append(arr[j]);
}
}
sb.append("]");
}
sb.append("]");
System.out.println(sb.toString());
Output is
[[1, \], [., ], [256]]
you can use the following ways to convert an integer into string
Integer.toString(i) or String.valueOf(i)
Example:
Integer.toString(result[i][j])
String.valueOf(result[i][j])
anyway your problem is that you need two loops one for rows and 2nd for columns, that is why you are getting only the values of columns :)
int[][] result = function(parameter);
System.out.println(Arrays.deepToString(result));
for (int row = 0; row < result.length; row++) {
for (int col= 0; col< result[0].length; col++) {
if (result[row][col] >= 179 && result[row][col] <= 204) {
System.out.print("\\");
}
if (result[row][col] >= 205 && result[row][col] <= 230) {
System.out.print(".");
}
if (result[row][col] >= 231 && result[row][col] <= 255) {
System.out.print(" ");
}
}
}
This is part of my homework. All I need is a bit of advice. I need to write some nested loop constructs, to print the following:
"122333444455555"
"+**+++****+++++"
"--***++++-----******+++++++"
Here is my code to print the first set of symbols
public static void main (String[] args)
{
int i,j;
for(i=1;i<6;++i)
{
for(j=1;j<i+1;++j)
{
System.out.print(i);
}
}
}
This works perfectly fine. I'm just having trouble figuring out the second and third set of symbols. Apologies for my lack of experience, I'm fairly new to Java.
One solution is:
final String[] arr = {"*", "+"};
And in your inner loop:
System.out.print(arr[i % 2]);
The % (Modulo) operator is responsible of the switches between * and + symbols:
For even i it'll be *, otherwise it'll be +.
Output: "+**+++****+++++".
(Regarding the second output, I'll not show you the solution, but it's very similar to this one once you understand it).
public static void main(String[] args) throws IOException {
int i, j;
for (i = 1; i < 6; ++i) {
for (j = 1; j < i + 1; ++j) {
System.out.print(i);
}
}
System.out.println();
for (i = 1; i < 6; i++) {
if (i % 2 == 1) {
for (j = 1; j < i + 1; ++j){
System.out.print("+");
}
} else {
for (j = 1; j < i + 1; ++j){
System.out.print("*");
}
}
}
System.out.println();
for (i = 2; i < 8; i++) {
if (i % 3 == 1) {
for (j = 1; j <= i; ++j){
System.out.print("+");
}
} else if (i % 3 == 2) {
for (j = 1; j <= i; ++j){
System.out.print("-");
}
} else {
for (j = 1; j <= i; ++j){
System.out.print("*");
}
}
}
}
Cycle #1:
You have to print out numbers from one to five and each number N has to be printed out N times.
for (i = 1; i < 6; ++i) { // this would set `i` to numbers from 1-5
for (j = 1; j < i + 1; ++j) { // for each cycle (next number) it prints
//it out N times where N is the cycle number. 1 is the first cycle,
//2 is the second and so on.
Cycle #2:
Same problem but instead of printing out number of the cycle you have to print out + or * based on if the cycle number is odd or even.
To check if the number is even you can use:
int number = 1;
if(number % 2 == 0){ // is true if the number is even
This checks whats the remainder from the division of number by two.
Cycle #3:
Same as #2 but you start from the second cycle, not from the first and you check for the remainder after division by 3.
If I understand, the third set is composed by sequence of "-*+" so:
String sequence = "-*+";
String s = "+**+++****+++++";
int seqI = 0;
for(i=0; i != s.size(); ++i) {
for(j=0; j < i+2; ++j) {
System.out.print(sequence[seqI]);
}
if(seqI < sequence.size()) {
++seqI;
} else {
seqI = 0;
}
}
You can define a function like this:
public static char Output(int i, int mode)
{
if (mode == 1)
{
return (char) i;
}
else if (mode == 2)
{
if (i % 2 == 0)
{
return '+';
}
else
{
return '*';
}
}
else if (mode == 3)
{
if (i % 3 == 0)
{
return '-';
}
else if (i % 3 == 1)
{
return '*';
}
else
{
return '+';
}
}
}
And use it just like:
for (int mode = 1 ; mode < 4 ; mode++)
{
for (int i = 1 ; i < 6 ; i++)
{
for (int j = 0 ; j < i + (int)(mode / 3) ; j++)
{
System.out.println(Output(i, mode));
}
}
}
Note: Yes! Actually my code is hard to read, but if you try to read it, you will learn something more than other answers!