numberOfDigits() in java? [duplicate] - java

This question already has answers here:
How to add a new method called numberOfDigits() in java?
(4 answers)
Closed 9 years ago.
i posted a question similar to this one but I still can't figure how to code this little part. Can someone please tell me how I can add a new method named "numberOfDigits"and a line to test it in the main() method . Below is the code I came up for numberOfZeros. To be more specific, all I want to know is how I can add numberOfDigits to this.
import java.util.*;
public class ZeroCounter {
public static void main(String[] args)
{
System.out.println("Enter a nonnegative number:");
Scanner keyboard = new Scanner(System.in);
int number = keyboard.nextInt( ) ;
System.out.println(number + " contains " + numberOfZeros(number) + " zeros.");
} // End of main
// * * * * Recursive Method * * * *
public static int numberOfZeros(int n) {
n = Math.abs(n); // Make sure the number is not negative.
// 1. STOPPING CONDITION: Number has only only digit.
if ( n < 10 ) {
// if( n == 0 ) return 1; else return 0;
return n==0 ? 1: 0 ; // Conditional operator.
} // end of the outer if block handling the stopping condition.
// 2. Else handle the case of two or more digits using recursion.
else {
return n%10 == 0 ? 1 + numberOfZeros(n/10): numberOfZeros(n/10) ; // Conditional operator.
// if (n%10 == 0) return 1 + numberOfZeros(n/10);
// else return numberOfZeros(n/10);
} // end of outer else block
} // end of recursive method method numberOfZeros. * * * * * * * *
// * * * * Non-recursive method using a while loop. * * * *
public static int numberOfZeros(int n)
{
if (n<0) n = -n;
if (n == 0) return 1; // Handle the special case of n = 0.
int zeros = 0; // The variable "zeros" will keep track of the number of zeros.
while (n > 0) { if(n%10==0) zeros++; n = n/10; }
return zeros;
} // End of NON_RECURSIVE method numberOfZeros.
// End of multiline comment below.
*/
} // end of class

int noOfDigits = (int) Math.log10(n) + 1;

Related

Power and factorial series sum Explanation

Question:
A class SeriesSum is designed to calculate the sum of the following series:
Class name : SeriesSum
Data members/instance variables:
x : to store an integer number
n : to store number of terms
sum : double variable to store the sum of the series
Member functions:
SeriesSum(int xx, int nn) : constructor to assign x=xx and n=nn
double findfact(int m) to return the factorial of m using recursive
technique.
double findpower(int x, int y) : to return x raised to the power of y using
recursive technique.
void calculate( ) : to calculate the sum of the series by invoking
the recursive functions respectively
void display( ) : to display the sum of the series
(a) Specify the class SeriesSum, giving details of the constructor(int, int),
double findfact(int), double findpower(int, int), void calculate( ) and
void display( ).
Define the main( ) function to create an object and call the
functions accordingly to enable the task.
Code:
class SeriesSum
{
int x,n;
double sum;
SeriesSum(int xx,int nn)
{ x=xx;
n=nn;
sum=0.0;
}
double findfact(int a)
{ return (a<2)? 1:a*findfact(a-1);
}
double findpower(int a, int b)
{ return (b==0)? 1:a*findpower(a,b-1);
}
void calculate()
{ for(int i=2;i<=n;i+=2)
sum += findpower(x,i)/findfact(i-1);
}
void display()
{ System.out.println("sum="+ sum);
}
static void main()
{ SeriesSum obj = new SeriesSum(3,8);
obj.calculate();
obj.display();
}
}
MyProblem:
I am having problems in understanding that when i= any odd number (Taking an example such as 3 here)then it value that passes through findfact is (i-1)=2 then how am I getting the odd factorials such as 3!
Any help or guidance would be highly appreciated.
Optional:
If you can somehow explain the recursion taking place in the findpower and findfactorial,it would be of great help.
Take a closer look a the loop. i starts at 2 and is incremented by 2 every iteration, so it is never odd. It corresponds to the successive powers of x, each of which is divided by the factorial of i -1 (which IS odd).
As for the recursion in findfact, you just need to unwrap the first few calls by hand to see why it works :
findfact(a) = a * findfact(a -1)
= a * (a - 1) * findfact(a -2)
= a * (a - 1) * (a - 2) * findfact(a - 3)
...
= a * (a - 1) * (a - 2) * ... * 2 * findfact(1)
= a * (a - 1) * (a - 2) * ... * 2 * 1
= a!*
The same reasoning works with findpower.
As a side note, while it may be helpful for teaching purposes, recursion is a terrible idea for computing factorials or powers.
I'm not sure I understand your question correctly, but I try to help you the best I can.
I am having problems in understanding that when i= any odd number
In this code i never will be any odd number
for(int i=2;i<=n;i+=2)
i will be: 2 , 4 , 6 , 8 and so on because i+=2
The Recursion
The findfact() function in a more readable version:
double findfact(int a){
if(a < 2 ){
return 1;
} else {
return a * findfact(a - 1);
}
}
you can imagine it as a staircase, every call of findfact is a step:
We test: if a < 2 then return 1 else we call findfact() again with a-1 and multiply a with the result of findfact()
The same function without recursion:
double findfact(int a){
int sum = 1;
for(int i = a; i > 0; i--){
sum *= i;
}
return sum;
}
Same by the findpower function:
if b == 0 then return 1 else call findpower() with a, b-1 and multiply the return value of findpower() with a
So the last called findpower() will return 1 (b = 0)
The second last findpower() will return a * 1 (b = 1)
The third last findpower() will return a * a * 1 (b = 2)
so you can see findpower(a, 2) = a * a * 1 = a^2
Hope I could help you
Try to run below code, it will clear all your doubts (i have modified some access specifier and created main method)
public class SeriesSum
{
int x,n;
double sum;
SeriesSum(int xx,int nn)
{ x=xx;
n=nn;
sum=0.0;
}
double findfact(int a)
{ return (a<2)? 1:a*findfact(a-1);
}
double findpower(int a, int b)
{ return (b==0)? 1:a*findpower(a,b-1);
}
void calculate()
{
System.out.println("x ="+x);
System.out.println("n ="+n);
for(int i=2;i<=n;i+=2){
System.out.println(x+"^"+i+"/"+(i-1)+"!" +" = " +(findpower(x,i)+"/"+findfact(i-1)) );
//System.out.println(findpower(x,i)+"/"+findfact(i-1));
sum += findpower(x,i)/findfact(i-1);
}
}
void display()
{ System.out.println("sum="+ sum);
}
public static void main(String arg[])
{ SeriesSum obj = new SeriesSum(3,8);
obj.calculate();
obj.display();
}
}
// ----- output ----
x =3
n =8
3^2/1! = 9.0/1.0
3^4/3! = 81.0/6.0
3^6/5! = 729.0/120.0
3^8/7! = 6561.0/5040.0
sum=29.876785714285713
You can simplify the summation and get rid of power and factorial. Please notice:
The very first term is just x * x
If you know term item == x ** (2 * n) / (2 * n - 1)! the next one will be item * x * x / (2 * n) / (2 * n + 1).
Implementation:
private static double sum(double x, int count) {
double item = x * x; // First item
double result = item;
for (int i = 1; i <= count; ++i) {
// Next item from previous
item = item * x * x / (2 * i) / (2 * i +1);
result += item;
}
return result;
}
In the real world, you can notice that
sinh(x) = x/1! + x**3/3! + x**5/5! + ... + x**(2*n - 1) / (2*n - 1)! + ...
and your serie is nothing but
x * sinh(x) = x**2/1! + x**4 / 3! + ... + x**(2*n) / (2*n - 1)! + ...
So you can implement
private static double sum(double x) {
return x * (Math.exp(x) - Math.exp(-x)) / 2.0;
}

Finding primeNumber and repDigit fails

I have a method for finding, wheter a number is a prime or not. It is working in my test class, but when I am using System.outprintf, it fails.
Same for the repDigit method.
Any help would be appreciated
Method for finding prime number:
/**
* Checks whether the number is a prime number.
*
* #param number Any number
* #return true if the number is prime, otherwise false
*/
public static boolean isPrime(int number) {
boolean isPrime = true;
if (number < 2) {
isPrime = false;
} else {
// Start counting from two to begin with even numbers
for (int i = 2; i < number/2; ++i) {
if (number % i == 0) {
isPrime = false;
}
}
}
return isPrime;
}
Method for finding repDigit:
/**
* This method checks if numbers, after each other, are the same. We take
* modulus of the number, in order to get the last digit, as long as the
* number is above 0. The number is divided by 10, to end up with all
* remaining numbers. Then it checks, if the last digit + the remaining are
* the same
*
* #param number
* #return
*/
public static boolean isRepDigit(int number) {
int repDigit = number % 10;
boolean toReturn = true;
if (number < 10) {
toReturn = false;
} else {
while (number > 0) {
int digit = number % 10;
number = number / 10;
if (repDigit != digit) {
toReturn = false;
}
}
}
return toReturn;
}
Main method:
public static void main(String[] args) {
final int START = 5;
final int END = 100;
final int SPACE = digitCount(END);
for (int i = START; i < END; i++) {
System.out.printf("%" + SPACE + "d is a repdigit &n", isRepDigit(i));
System.out.printf("%" + SPACE + "d is a prime &n", isPrime(i));
}
}
Error message:
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.Boolean
at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747)
at java.util.Formatter.format(Formatter.java:2520)
at java.io.PrintStream.format(PrintStream.java:970)
at java.io.PrintStream.printf(PrintStream.java:871)
at Grp17_ueb01.main(Grp17_ueb01.java:164)
C:\Users\rasmu\Documents\NetBeansProjects\ueb01\nbproject\build-impl.xml:1040: The following error occurred while executing this line:
C:\Users\rasmu\Documents\NetBeansProjects\ueb01\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 1 second)
I think you misunderstood the meaning of the second argument of printf.
Here d in your string is supposed to be replaced by as a decimal, given as second argument. And the boolean isRepDigit(i) cannot be converted as a decimal.
The printf method documentation may be found here.
The Format string syntax is explained here.
What I think you wanted is:
if (isRepDigit(i)) {
System.out.printf("%" + SPACE + "d is a repdigit \n", i);
}
if (isPrime(i)) {
System.out.printf("%" + SPACE + "d is a prime \n", i);
}

Arraylist, do while loop and calling a method

I need to create an array list to save the value of resistors entered by user. Then I need to ask user which type of method to calculate his answer with, then return back answer. The do while loop needs to keep asking for resistors values until user enter the number zero. The calculations have to be pulled from a class Resistance to Main.
**CLASS***
import java.util.ArrayList;
public class Resistance {
/**
* Holds an object type.
*/
public int userChoice;
ArrayList<Double> resistor = new ArrayList<Double>();
/**
*Chooses which process follows next.
*#return circuitType
*/
public final double calculateResistance() {
if (userChoice == 1) {
return calculateSeriesResistance();
} else {
return calculaParallelResistance();
}
}
/**Returns object of parallel circuit.
*
* #return 1 / runningResistance.
*/
public double calculaParallelResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.lenght; ++index) {
runningResistance = runningResistance
+ +1 / resistor.lenght;
}
return 1 / runningResistance;
}
/**Returns object of series circuit.
*
* #return runningResistance.
*/
private double calculateSeriesResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.length; ++index) {
runningResistance = runningResistance + resistor[index];
}
return runningResistance;
}
}
***MAIN********
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
/**
* Makes a Constant.
*/
public final static int DONE = 0;
/**
* Makes a Constant.
*/
public static final int USER_CHOICE_SERIES = 1;
/**
* Makes a Constant.
*/
public static final int USER_CHOICE_PARALLEL = 2;
public static void main(final String[] args) {
// TODO Auto-generated method stub
DecimalFormat f = new DecimalFormat("##.00");
Resistance myRes = new Resistance();
Scanner keyboard = new Scanner(System.in);
//Display Purpose
System.out.println("\nThis program will calculate "
+ "the resistance of a Parallel or Series "
+ "Circuit\n");
//Display instructions
System.out.println("Please enter the value of your "
+ "resistors separately, when done press 0 (zero)");
int n = 0;
do {
System.out.println("Enter Resistor #" + ++n);
myRes.resistor.add(keyboard.nextDouble());
} while (myRes.resistor > 0);
// Ask Which Method To Use,
do {
System.out.println("\nEnter 1 to calculate "
+ "a Series Circuit "
+ "or 2 for a Parallel Circuit");
myRes.userChoice = keyboard.nextInt();
// Ask user again in case he enters something else
} while (myRes.userChoice != USER_CHOICE_PARALLEL
&& myRes.userChoice != USER_CHOICE_SERIES);
//Output the total resistance
System.out.printf("\nThe Total Resistance is "
+ f.format(myRes.calculateResistance()));
}
}
As said, there are few isues with your code, let's break it down step by step.
First, ArrayList doesn't have a field called length, you want to use size() instead.
Next, your method of calculating parallel resistance is wrong. You are not iterating over your resistors, instead you're using number of resistors to calculate. The correct formula is:
1 / Rtotal = 1 / R1 + 1 / R1 + 1 / R3 + ...
Change your code to:
public double calculaParallelResistance() {
double runningResistance = 0;
//use size() instead of length, which doesn't exist in ArrayList
for (int index = 0; index < resistor.size(); index++) {
//also, iterate over each resistor's value, and to get it,
//use...err, get() method :)
runningResistance += (1 / resistor.get(index));
}
return 1 / runningResistance;
}
Your method calculateSeriesResistance() also has an issue: you can't access object by using array notation, as in resistance[index]. Use get() method, so the correct code is:
private double calculateSeriesResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.size(); index++) {
runningResistance += resistor.get(index);
}
return runningResistance;
}
Now, to the main method. Your first 'do' loop is checking against number of resistors in your ArrayList, not against 0 value entered by user. You could use while loop instead and break when 0 entered:
//holds current resistor's value
Double val;
while(true) {
System.out.println("Enter Resistor #" + ++n);
val = keyboard.nextDouble();
//only add if higher than 0
if (val > 0.0) {
myRes.resistor.add(val);
}
//0 entered, so finish the loop
else break;
}

Java for loop to get X

I need help with a for loop I have for an assignment.
There is a math problem called N!, I bet some of you have heard of it. It goes like 1*2*3*4*5*n=x
I made a table like this:
1 = 1
1 * 2 = 2
1 * 2 * 3 = 6
1 * 2 * 3 * 4 = 24
1 * 2 * 3 * 4 * 5 = 120
1 * 2 * 3 * 4 * 5 * 6 = 720
But I just can't seem to solve the problem. How do I get what x is from 1*2*3*4....*n=x? Here's my code so far:
Scanner input = new Scanner(System.in);
System.out.println("\n~~Assignment 8.5~~");
boolean go = true;
do {
int n;
int total;
System.out.println("Loop until:");
n = input.nextInt();
for (int i = 1;i <= n;i++)
{
System.out.print(i);
if (i == n) { System.out.print(" = " + "idk" + "\n"); break;} else { System.out.print(" * ");}
}
} while ( go == true);
Just add total calculation s
inside the for loop:
total *= i;
and after the for loop print it. Remember to initialize total with value 1
You can use following Class;
public class RecursiveTest {
public RecursiveTest(int x){
int i=1;
int temptotal=1;
while(true){
System.out.print(i+"*");
if(temptotal==x || temptotal>x) break;
temptotal=temptotal*(++i);
}
}
public static void main(String[] args) {
new RecursiveTest(100);
}
}
Here's the hint,
fact(x) = x * fact(x-1) iff x > 0
fact(x) = 1 iff x == 0
fact(x) = ERROR iff x < 0
Create and implement the function public int fact(int x) and call it from inside a main function after picking up input from the command line or from reading user input. (and validating the input is a number)
int rec_n( int n){
int result = 1;
for(int i = 1; i <= n; i++ ){
result *= i;
}
return result;
}

Project Euler p14, stackoverflowerror java (in bluej)

I'm working on euler problem 14 (http://projecteuler.net/problem=14). I've tried to tackle it by having a method which runs through the collatz equations, and returns the number of steps taken. If it's higher then the current record it overwrites it, otherwise it moves on to the next integer. It was giving stack overflow errors so I added the system.out.println messages to try and identify where it was stalling, and currently it dies whenever it reaches 5200~, I'm confused as to why, because as far as i can tell no values encountered at this point should go over the int limit, and the error persisted even if i changed "numberStorage" from int to long.
Here is my current code:
/**
* Write a description of class calculator here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Calculator
{
// instance variables - replace the example below with your own
private int x;
private int startingNumber = 1;
private int stepCount;
private int numberStorage;
private int currentRecordStart;
private int currentRecordSteps = 0;
/**
* a string and int value to track multiple starting numbers with the same number of steps
*/
private String tieNote = "no ties";
private int multiTie = 0;
/**
* Constructor for objects of class calculator
*/
public Calculator()
{
x = 0;
}
/**
* begins function
*/
public void initiater()
{
numberStorage = 0;
stepCount = 0;
startingNumber = 1;
currentRecordStart = 1;
currentRecordSteps = 0;
stepCount = 0;
recordHolder(1,1);
}
/**
* starts next rotation
*/
public void steprunner()
{
++startingNumber;
System.out.println("starting rotation " + startingNumber + " current record " + currentRecordSteps);
stepCount = 0;
numberStorage = 0;
recordHolder(startingNumber, collatzSequence(startingNumber));
}
/**
* Runs collatz sequence and updates a variable with the number of steps.
*/
public int collatzSequence(int N)
{
numberStorage = 0;
numberStorage = N;
if (N == 1)
{
return stepCount;
}
else if ( (N & 1) == 0)
{
numberStorage = numberStorage / 2;
++stepCount;
return collatzSequence(numberStorage);
}
else if ( (N & 1) != 0)
{
numberStorage = 3 * numberStorage + 1;
++stepCount;
numberStorage = numberStorage / 2;
++stepCount;
return collatzSequence(numberStorage);
}
return stepCount;
}
/**
* stores record and starts next cycle
*/
public void recordHolder(int startingnumber, int stepcount)
{
if (startingNumber <= 999999)
{
if (stepcount > currentRecordSteps)
{
currentRecordSteps = stepcount;
currentRecordStart = startingnumber;
tieNote = "no ties";
multiTie = 0;
System.out.println("a tie occured!");
}
else if (stepcount == currentRecordSteps)
{
tieNote = ("starting number " + startingnumber + " also had " + stepcount + "steps");
++multiTie;
System.out.println("a secondary tie occured!");
}
steprunner();
}
if (startingNumber == 999999)
{
simulationEnder();
}
}
/**
* ends simulation
*/
public void simulationEnder()
{
System.out.println("the number with the highest number of steps was " + currentRecordStart +
" with " + currentRecordSteps + " steps!");
}
}
I'm not going to read your code. But I can show you a solution, written in pseudocode, that is simple and quick:
function euler14(n):
cs := makeArray(1..n)
maxX, maxLen, cs[1] := 1, 1, 1
for k from 2 to n
c, s := 0, k
while k <= s
if s % 2 == 0
s := s / 2
else
s := 3 * s + 1
c := c + 1
cs[k] := cs[s] + c
if maxLen < xs[k]
maxX, maxLen := k, cs[k]
return maxX
The trick is to calculate and save the values of the lengths of the collatz chain, in order starting from 1; then, if a future sequence drops below its starting point, calculation stops in favor of a simple lookup. Here the cs array is the cache, k is the index of the chain that is currently being computed, s is the current item in the chain, and c is the current length of the chain. Computing euler14(1000000) should take no more than a second or two.

Categories