I am making a histogram - java

I am trying to make a histogram with inputting a value and rounding it. The rounded value should print out the number of asterisks.
I did the following code and inputted a value but, the output is coming out as nothing.
public class Histogram
{
public static void main(String args[])
{
histogram obj = new histogram();
obj.histogram(13.5);
}
}
class histogram
{
public void histogram(double num)
{
int roundNum = (int)(num);
if (roundNum == 14)
{
System.out.println("**************" + num);
}
if (roundNum == 3)
{
System.out.println("***" + num);
}
if (roundNum == 16)
{
System.out.println("****************" + num);
}
if (roundNum == 0)
{
System.out.println("" + num);
}
if (roundNum == 1)
{
System.out.println("*" + num);
}
}
}

In Java, typecasting to primitive type int from primitive type double can be thought of as simply removing the decimal part.
For example;
System.out.println((int) 13.1); // prints 13
System.out.println((int) 13.5); // prints 13
System.out.println((int) 13.9); // prints 13
So, when you call obj.histogram(13.5); with the function parameter num being 13.5, the operation int roundNum = (int)(num); is the same as int roundNum = (int)(13.5);, and assigns 13 to the roundNum variable.
Since no if statements handle this case (roundNum being 13), no output is generated.
On another note, hardcoding a lot of if statements for checking the same variable over and over again can usually lead to unnecessarily complex, inefficient and hard-to-read code. Can you think of a better way to print "*" characters for the histogram, by using the roundNum variable? (Hint: try experimenting with for loops)

Change your int roundNum = (int)(num); to int rounded = Math.round((float)num); it should give you the desired output.

Related

Using recursion to compute factorials without new variables [duplicate]

This question already has answers here:
Recursion vs For loops - Factorials, Java
(3 answers)
Closed 6 years ago.
I am trying to compute the entered factorial in the method factorialRecursive by using recursion, However I cannot declare any variables or objects in that method and thats what i am struggling with, my attempt is in the method already but doesn't work. This has to call itself in a While loop not a for loop.
class Factorial{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int number;
do {
System.out.print("Enter a positive number: ");
number = input.nextInt();
} while (number < 0);
System.out.println(number + "! = " + factorialIterative(number) + " (iterative)");
System.out.println(number + "! = " + factorialRecursive(number) + " (recursive)");
}
private static int factorialIterative(int num) {
int result = 1;
while (num > 0) {
result = num*result;
num--;
}
return result;
}
private static int factorialRecursive(int num){
if (num==1 | num==0)
return 1;
return num*(num-1) * num;
}
}
Try this:
private static int factorialRecursive(int num) {
// Warning here use || instead of |
if (num==1 || num==0)
return 1;
return num * factorialRecursive(num - 1);
}
I can also be simplified like this:
private static int factorialRecursive(int num) {
return (num == 1 || num == 0) ? 1 : num * factorialRecursive(num - 1);
}
You don't need to declare any variables. Take advantage of the recurrence relation for factorials:
n! = n * (n - 1)!
Multiply num by the result of making a recursive call by passing num - 1. Return that product without storing it in a variable.
Recursivity means you need to call the method itself inside of the method
Example:
private static int factorialRecursive(int num){
if (num==1 | num==0)
return 1;
return num*factorialRecursive(num-1);
}
and since factorial will increase really high with low values, consider to use other data type than integers... otherwise it will only work until factorial(16) after that you will get invalid data by using ints...
private static long factorialRecursive(long num){
if (num==1 | num==0)
return 1;
return num*factorialRecursive(num-1);
}

Remove unnecessary decimals

I got this code that fetches floats from a database.
for (int i = 0; i < ingredient.size() ; i++) {
Ingredient ing = (Ingredient) ingredient.get(i);
ingredients += String.valueOf(ing.getAmount()) + " " +
ing.getUnit() + " " + ing.getIngredient() + "\n";
}
The database is written in REAL values as some of them is 1.5, 2.5, 1.4 etc. But we also have these whole numbers without the need of a decimal, such as 1, 4, 10 etc.
The problem is that the database table needs to be in REAL value, which gives us no choice but to give all the values one decimal, no matter if it's needed or not.
So we'll end up with values like:
1.0
1.5
2.3
20.0
5.0
My question is: How do we remove the unnecessary decimals, but keep the ones that need it?
One very simple way to remove these would be to strip the characters using StringUtils.
String displayValue = String.valueOf(ing.getAmount());
displayValue = StringUtils.stripEnd(displayValue, ".0");
For an input of "1.0", "1" will be returned.
A more technical approach would be to use the modulus operator %
For example:
if(value%1 == 0){ //1 divides into number perfectly, there is no decimal
//cast value to integer or another non decimal variable
} else {
//use existing value as it contains a decimal
}
How about this (does't require any fancy things like StringUtils)?
String s = String.valueOf(1.0);
System.out.println(s);
/* Make this block as a function and return an int */
String ss = " ";
if (s.charAt(s.length()-2) == '.' && s.charAt(s.length()-1) == '0'){
ss = s.substring(0,s.length()-2);
System.out.println(ss);
}
/**************************************************/
int converted = Integer.parseInt(ss);
System.out.println(converted);
}
If you want to make it a function block, you can.
You can check it working on IDEONE - http://ideone.com/udJv8M
Check the float values with modulo. If 0 is returned it is an Integer. Here is an example with the numbers you have mentioned:
List<Float> values = new ArrayList<Float>();
values.add(new Float(1.0f));
values.add(new Float(1.5f));
values.add(new Float(2.3f));
values.add(new Float(20.0f));
values.add(new Float(5.0f));
List<String> strValues = new ArrayList<String>();
for(Float value : values)
{
String strValue = "";
if(value % 1 == 0)
{
Integer intValue = value.intValue();
strValue = intValue.toString();
strValues.add(strValue);
}
else
{
strValue = value.toString();
strValues.add(strValue);
}
System.out.println(strValue);
}
You can use a custom DecimalFormat pattern:
public static String customFormat(String pattern, double value) {
DecimalFormat myFormatter = new DecimalFormat(pattern);
return myFormatter.format(value);
}
Then a pattern of # defines places holders for optional digits, so #.### will give up to 3 digits where necessary only.
for (int i = 0; i < ingredient.size() ; i++) {
Ingredient ing = (Ingredient) ingredient.get(i);
ingredients += customFormat("#.###", ing.getAmount()) +
" " + ing.getUnit() + " " + ing.getIngredient() + "\n";
}
So don't convert your data to a String except for display only. Real numbers can represent both integers and floating point numbers using the same data type. Plus if you ever needed to do any math on your numbers you can't use Strings to do that. If you convert your numbers from the database directly to String before storing them into Ingredient then you've screwed yourself later on if you want to do calculations on those numbers. (Say you wanted to add a feature to double a recipe and have all of the quantities change for the user). Under your current plan you're preventing yourself from doing something like that because you're overly focused on the display of that number.
Instead just create a method on Ingredient to convert your numbers using String.format(). Like so:
public class Ingredient {
private double amount;
private String name;
public String asDecimal() {
return String.format("%.1f", amount);
}
public String asInteger() {
return String.format("%.0f", amount);
}
public String asFraction() {
// exercise left to the reader
}
}
You could even add a function that converts decimals to fractional amounts to make it easier to display things chiefs might understand vs decimals which are harder. Bear in mind String.format() will round floating point amounts (0.5 -> 1 using as Integer).
Convert your String returned from ing.getAmount() to a Float object, then use the modulo function to determine whether your value is an exact multiple of 1 (ie no decimal places). If so, convert your Float object to an int, which will concatenate the decimals.
Float f = Float.valueOf(ing.getAmount());
if(f%1 == 0) {
// Use f.intValue() to concatenate your decimals.
ingredients +=String.valueOf(f.intValue() + " " + ing.getUnit() + " " + ing.getIngredient() + "\n";
}
else {
ingredients +=String.valueOf(ing.getAmount()) + " " + ing.getUnit() + " " + ing.getIngredient() + "\n";
}
I hope this helps.

Explaining about prints output ordering of recursive loop?

Can anyone please explain the print order of the recursive loop?
import java.util.Scanner;
public class DecimalToBinary {
static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
int decimalNum;
int base;
base = 2;
System.out.println("Enter a nonnegative integer in decimal: ");
decimalNum = console.nextInt();
System.out.println();
System.out.println("Decimal " + decimalNum + " = ");
decToBin(decimalNum, base);
System.out.println(" binary");
}
public static void decToBin(int num, int base) {
if (num == 0) {
System.out.print(0);
} else if (num > 0) {
decToBin(num / base, base);
System.out.print(num % base);
}
}
}
Num % base must print reverse order like this:
why is the order of calls as shown? (Please help me revise my question, English is my foreign language)
Your printing occurs after the recursion. Using (25, 2) as an example, the order of your calls with printing looks like
decToBin(25, 2):
decToBin(12,2):
decToBin(6,2):
decToBin(3,2):
decToBin(1,2):
decToBin(0,2):
print(0)
print(1%2)
print(3%2)
print(6%2)
print(12%2)
print(25%2)
Removing the recursive calls and just leaving the print statements shows the order you are getting:
decToBin(25, 2):
print(0)
print(1%2)
print(3%2)
print(6%2)
print(12%2)
print(25%2)
If you want the printing to be in the reverse order, move the print statement before the recursive call:
public static void decToBin(int num, int base) {
if (num == 0) {
System.out.print(0);
} else if (num > 0) {
System.out.print(num % base);
decToBin(num / base, base);
}
}
New recursion with printing:
decToBin(25, 2):
print(25%2)
decToBin(12,2):
print(12%2)
decToBin(6,2):
print(6%2)
decToBin(3,2):
print(3%2)
decToBin(1,2):
print(1%2)
decToBin(0,2):
print(0)
New output:
decToBin(25, 2):
print(25%2)
print(12%2)
print(6%2)
print(3%2)
print(1%2)
print(0)
the order of the output is reversed
because once the dectobin function is called
decToBin(int num, int base) {
if (num == 0) {
System.out.print(0);
} else if (num > 0) {
it reaches the line
decToBin(num / base, base);
where it postpones its execution and calls "another instance" of the dectobin function with decreased number parameter, before getting a chance to output anything(in the code below)
System.out.print(num % base);
}
then this subsequent call of dectobin is stopped at the same line and another "instance" is started with even smaller num. and so on and so on. none of the "instances" so far gets a chance to print anything.
at some point the "instance" of the function which was started last, recognizes that its
num argument has decreased under value of 1; and since num is integer type, once it is positive but less than 1 it is "Rounded" to 0. so that the following condition is true:
if (num == 0) {
System.out.print(0);
then this last instance behaves differently from all its predecessors. instead of postponing its execution and creating a new "instance" it prints '0' in the line above and just ends returning the execution point to the one "instance" which called it, which then continues to run from the line it was postponed.
then this "instance" outputs its number
system.out.print(num % base);
and ends itself returning the execution to the one which was starting it. and so and so on.
the bottom line is: the function "instance" which started last had the first output.the one which started first had the last

Recursive method return numbers from int to 0

I'm having trouble with a recursive method that will return and print in my main method the numbers from X (X being a int on commandline) to 0. Returning the numbers as a String.
For example my commandline argument is 4.
My output should be: 4, 3, 2, 1, 0
I kind of understand how to reverse a string like: "123" to "321".. But no clue when getting a integer like 3, and returning it like "3, 2, 1, 0" as a string. :o
My code atm:
public static void main(String[] commandlineArguments) {
if (commandlineArguments.length == 0) {
System.out.println("Please enter a least one commandline!");
}
else {
Integer number = new Integer(0); // initialize number
try {
number = Integer.parseInt(commandlineArguments[0]);
}
catch (NumberFormatException exception) { // NumberFormatException
System.out.println(exception + " is not a integer!");
System.exit(1); // end program
}
String reverse = reverse1(number);
System.out.println(reverse);
}
}
public static String reverse1(Integer number){
if (number == 0){
return "";
}
else{
return "";
}
}
}
public static String reverse1(int number){
if (number == 1){
return "1";
} else {
return number + ", " + reverse1(number - 1);
}
}
The trick with recursion is - in my opinion - always to search the trivial case.
So here the easiest input is 1 and the result would be "1"
reverse1(1) = "1";
And then you need that "strange" recursion step where you reduce your input towards that trivial case.
reverse1(n) = n, reverse(n-1)
Here you just say:
The result of a number n is always the result of "this number minus 1" with that extra number n in front.
Think about it, its quite logical.
It's sometimes not easy to think of a problem in that "recursive way". But often it makes things alot easier.
public static void main(String[] commandlineArguments) {
printNumber(number);
}
public static String printNumber(Integer number){
if (number == 0){
return "0";
}
return number +" " + printNumber(number-1);
}

Sets using bit strings in Java trouble

public class BitStringOperations3
{
public static void main (String args[])
{
Scanner in = new Scanner (System.in);
int setA = 0;
int setB = 0;
int elementsSetA = 0;
int elementsSetB = 0;
System.out.println ("How many integers are in set A?");
elementsSetA = in.nextInt ();
while (elementsSetA > 9 || elementsSetA < 0)
{
System.out.println ("This input is invalid. Please enter a number between 0 and 9 and try again.");
elementsSetA = in.nextInt();
}
System.out.println ("How many integers are in set B?");
elementsSetB = in.nextInt ();
while (elementsSetB > 9 || elementsSetB < 0)
{
System.out.println ("This input is invalid. Please enter a number between 0 and 9 and try again.");
elementsSetB = in.nextInt();
}
for (int i = 1; i <= elementsSetA; i++)
{
System.out.println ("Please enter integer number " + i + " in set A: ");
setA = add(setA, in.nextInt() );
}
for (int i = 1; i <= elementsSetB; i++)
{
System.out.println ("Please enter integer number " + i + " in set B: ");
setB = add(setB, in.nextInt () );
}
}
public static boolean setContainsValue (int set, int value)
{
boolean setContainsValue = (set & maskForValue) != 0;
return true;
}
public static int addValueToSet (int set, int newValue)
{
set = set | maskForValue;
return set;
}
public static void printSet (int set, int value)
{
int mask = 1;
System.out.print ("{");
for (int i = 0; i<= 9; i++)
{
if(( mask & set ) == 1)
System.out.print(i + " " );
int maskForValue = 1 << value;
set >>= 1; //set = (set >> 1);
}
System.out.println ("} ");
}
}
I am having trouble with an assignment for school. We are given the universal set U = {0-9}. I have to gather user input for both sets, and then use bit strings (we are not allowed to use the Set or HashSet classes in java) to store the sets and perform operations on them, such as complement, Set A union Set B and such. I know how to do those, but my code does not convert Sets A and B into the memory correctly and therefore, I cannot perform any operations on them. Help will be gladly appreciated! Thanks in advance. :)
Edit 1:
Alright, I read your ideas and tried to implement them as good as I could, and I have given the result above. This program really pushes me out of my comfort zone and I really appreciate all the help.
First of all, do yourself a favour and create helper methods. Then concentrate only on making them correct:
public static boolean contains(int set, int value) {
//return true if value bit is 1 in set
}
public static int add(int set, int newValue) {
//add newValue to set and return it
}
Afterwards you can express your logic more clearly:
if ( contains(set, 1) ) {
//print 1
}
Some general hints:
Don't use Math.pow() as that is made for floating-point numbers. To get a power of 2 as an integer, use bit shifting:
int maskForValue = 1 << value;
To check if a certain bit is set, find the mask for that bit and use &. This zeros out all bits except for the bit you're checking.
boolean setContainsValue = (set & maskForValue) != 0;
To set a bit in a bit field, find the mask for that bit and use |. This ensures that that bit becomes 1.
set = set | maskForValue;
Edit
As to your direct problem, take a look at this:
for (int i = 1; i <= elementsSetB; i++)
{
System.out.println ("Please enter integer number " + i + " in set B: ");
setB = in.nextInt ();
}
You're overwriting setA and setB every time. In the end, setA and setB will contain the last value the user specified. Then later, you do this:
for (int i = 0; i <=9; i++)
setB |= (int)pow(2.0, i-1);
Which just ignores the user's input and overwrites all bits 0-9 (though in an unsafe way!). So of course what the user inputs is irrelevant.
Get rid of the latter for loops and then store the input like this (using the helper methods I described above):
for (int i = 1; i <= elementsSetB; i++)
{
System.out.println ("Please enter integer number " + i + " in set B: ");
setB = add(setB, in.nextInt());
}
Edit 2
You seem to be having problems understanding where I'm coming from with my idea of these "helper" methods. If this is the first time you've worked with methods that have parameters, sorry for clouding up the issue. But they allow you to focus on getting one piece of functionality working at a time. I'll expand on what I mean more here:
public static boolean setContainsValue(int set, int value) {
//return true if the bit string (or bit set) represented by the "set" parameter
//contains the value stored in the "value" parameter
//see the FIRST and SECOND bullet points above for how to do this
}
public static int addValueToSet(int originalSet, int valueToAdd) {
//add the value stored in the "valueToAdd" parameter to the set represented by the
//"originalSet" parameter and return the result
//see the FIRST and THIRD bullet points above for how to do this.
}
I'll even write some tests for you too. The methods above haven't been implemented properly until at least all of the following print true:
int set = 0;
System.out.println( ! contains(set, 1) ); //make sure set doesn't contain 1
set = addValueToSet(set, 1);
System.out.println( contains(set, 1) ); //make sure set now contains 1
System.out.println( !contains(set, 2) ); //make sure set doesn't contain 2
set = addValueToSet(set, 2);
System.out.println( contains(set, 1) ); //make sure set still contains 1
System.out.println( contains(set, 2) ); //make sure set now contains 2
First, you need a class (this is object-oriented programming, right?) to contain the "DigitSet".
public DigitSet {
private BitSet digits;
public DigitSet() {
// digits contains one bit for each digit
digits = new BitSet(10);
}
... rest of DigitSet code goes here, like ...
/**
* Check if this set contains a particular digit.
*/
public boolean contains(int value) {
// check to see if value is a valid input (0-9)
// look in digits to see if the "right" bit is set.
}
public void set(int value) {
// check to see if value is a valid input (0-9)
// set the "right" bit in digits to 1.
}
public void clear(int value) {
// check to see if value is a valid input (0-9)
// set the "right" bit in digits to 0.
}
public DigitSet union(DigitSet other) {
// construct a "new" output DigitSet.
// Walk through all of the digits in "this" set
// if a digit is set in this set, set it in the output set.
// Walk through all of the digits in the "other" set
// if a digit is set in the other set, set it in the output set.
}
public String toString() {
// return a display string based on the set "digit" bits
}
}
Then the rest is just input handling and "perform the operation"
public static void main(String[] args) {
DigitSet first = new DigitSet();
// read in the values for the first digit set, for each value
// set the digit in first like so
first.set(value);
DigitSet second = new DigitSet();
// read in the values for the second digit set, for each value
second.set(value);
DigitSet result = first.union(second);
System.out.println("Result: " + result.toString());
}

Categories

Resources