Part of an assignment I have for a beginning Java class is to take a time entered in as a string and convert it (while rounding to the nearest quarter hour) to a double and store it in an array. The part I am having difficult with is what to do with the two integers I receive from the split method of the String class. How do I make the two integers into one double to use in the array? (So it would be like hours.minutes, or 5.25)
Here is a snippet of code from a program I am working on:
public static double convertClockOutTimes(String clockOut){
double convertedTimeOut = 0;
String time = clockOut;
int hours;
int minutes;
String[]splitFields;
splitFields = time.split(":");
hours = Integer.parseInt(splitFields[0]);
minutes = Integer.parseInt(splitFields[1]);
if (minutes <= 7)
{
minutes = 0;
}
else if (minutes >= 8 || minutes <= 22)
{
minutes = 15;
}
else if (minutes >= 23 || minutes <= 37)
{
minutes = 30;
}
else if (minutes >= 31 || minutes <= 53)
{
minutes = 45;
}
else
minutes = 0;
hours = hours + 1;
convertedTimeOut = //This is where I don't know what to do!!
return convertedTimeOut;
}
I think the trick is to use a bit of math here. You could always do the following:
double convertedTimeOut = Math.round(minutes / 15.0) * 0.25 + hours;
then you don't need the if-else tree to figure out the nearest quarter hour.
There are 15 minutes in a quarter hour, and a quarter hour is 0.25 hours. Using the formula above, you are dividing the minutes into how many quarters of an hour you've got (0-4), which you then multiply by how many hours are in a quarter hour. Then add that to the hours you've got.
Math.round just does the rounding for you.
I'm guessing what's giving you the most trouble is how to deal with the minutes. Try this:
double minutesAsDecimal = 0.01 * minutes;
So if the number of minutes was 24, you would end up with 0.24. I bet you'll know where to go from there.
Just as a side note, your if and else ifs are not doing what you think they are. But since it's homework.. Just take a closer look at your logic there.
Your conditions should be AND not OR:
if(minutes >= 8 && minutes <= 22)
Etc, or better yet, a single statement, simply
minutes = ((minutes + 7) % 15) * 15;
which calculates the rounding using arithmetic rather than logic.
Related
Just starting to learn recursion and I am confused on this bacteria problem. Basically, I must create a method that multiplies the bacteria over a certain amount of hours. The pattern/ equation for this is bacteriaLastHour + bacteriaLastHour * 2. As an example, after one hour there will be 10 + 10 * 2 = 30 bacteria, and after 2 hours there will be 30 + 30 * 2 = 90 bacteria.
Here is my code:
public static int numBacteriaAlive(int hour)
{
int bacteriaLastHour = 10;
int total = 0;
// Write a base case
if(hour == 0){
return 10;
}
// Write a recursive call
total += (bacteriaLastHour * 2) + numBacteriaAlive(hour-1);
bacteriaLastHour *= 3;
return total;
}
For hours 1 & 2, the method works perfectly, returning 10 & 30. Yet for the other hours, the variable bacteriaLastHour doesn't change and therefore the number it return is off. My code returns 50 for 2hours (should be 90), 70 for 3hours (should be 270), etc. Any advice helps, thank you!
Edit: Cannot change parameter values
It's a lot simpler than you're imagining:
public static int numBacteriaAlive(int hour) {
if (hour == 0) { // base case
return 10;
}
int bacteriaLastHour = numBacteriaAlive(hour-1); // recursive case
return bacteriaLastHour*3;
}
Note: bacteriaLastHour + 2*bacteriaLastHour is the same as bacteriaLastHour*3
Once you've written the base case (for hour==0) then you must trust that numBacteriaAlive(hour-1) will return the correct value. Once you know that, returning the answer for the current hour value is easy.
I have a problem with a program that will tell the time. For example if you ask java what Time(4,129)is, the output should give 6 hours and 9 minutes(Because 129 minute can be simplfied.
Note: This is just a part of my code. I know my code will fail for minute values such as 120,180.
I do understand my forloop is inefficient, but that is not the problem. My problem is that my output for Time(4,129) gives me 4 hours and -51 minutes which is wrong. It should be 6 hours and 9 minutes.
How I think the code is working:
We enter the forloop, go to if statement,check if 129%60 is greater than 0 (9>0) which is true, then proceed.
2.For the body of the if statement, minutes will reduce from 129 to 69 and increment hours by 1 (It is now 5 hours). Forloop ends.
We repeat our forloop which is the 2nd iteration. Check if statement condition ,69%60>0 --> 9>0,True, go to if statement body.
minutes will change to 9 from 69 minutes and hours increment by 1. If statement ends.
Repeat if statement, Third iteration, 9%60 is false therefor if statement does not run.
Time(int x, int y) {
hours = x;
minutes = y;
for (int i = 0; i < 12; i++) {
int temp;
if (minutes % 60 > 0) {
minutes = minutes - 60;
hours = hours++;
Repeat if statement, 9%60 is false therefor if statement does not run
Is it? For minutes being 9, minutes % 60 is 9, which is greater than 0. You want minutes > 59, no modulo needed.
But even easier: hours += minutes / 60; minutes %= 60. No loop required.
It's not clear why you use a loop. But if you insist, how about
while (minutes >= 60) {
minutes -= 60;
hours += 1;
}
Your analysis for the final loop is wrong. 9 % 60 is 9. That's greater than 0 so minutes becomes -51.
This will yield the correct result, the flaw in your code is the use of modulo to figure out when the minutes should be taken into account:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int x = 4;
int y = 129;
int hours = x;
int minutes = y;
for (int i = 0; i < 12; i++) {
int temp;
if (minutes > 59) {
minutes = minutes - 60;
hours = ++hours;
}
}
System.out.println("Hours: "+ hours + " minutes: " + minutes);
}
}
I'm trying to let the user enter the length of a song except they can enter the length as 5.76 for example. Is there a way I can format that 6.16?
This is how they enter the duration if it makes any difference:
System.out.println("Please enter the length of the song");
double length = sc.nextDouble();
The code below will split the entered time into minutes and seconds, and then operate on the seconds entry to calculate the total number of minutes and seconds are represented by that number.
EDIT Modified the code so that trailing zeroes are not truncated.
System.out.println("Please enter the length of the song");
String length = sc.next("\\d+\\.\\d{2,}");
String[] split = ("" + length).split("\\.");
double minutes = Double.parseDouble(split[0]);
double seconds = (Double.parseDouble(split[1]));
seconds = (Math.floor(seconds / 60)) + ((seconds % 60) / 100);
System.out.println(minutes + seconds);
Get the decimal value and check if its greater than 0.6. You can then subtract it from 0.6 and add that difference and 1 to the floor of the orignal number.
double dec = length - Math.floor(length);
if(dec > 0.6){
double diff = dec - 0.6;
length = length + 1 - dec + diff;
}
However, this might cause a lot of decimals due to the way double is stored in Java. You could get around this, but you should really use a different value to store hours and minutes than a double. You could use an integer for each, and you could initially scan in the input as a String and then process it.
With the following code, you can convert to minutes and seconds, then output that however you want, including put it back into a double (as shown).
int minutes = Math.floor(length);
length -= minutes;
length = Math.floor(length * 100.0);
if (length > 59) {
minutes++;
length -= 60;
}
int seconds = Math.floor(length);
length = ((double) minutes) + ((double) seconds) / 100.0;
I'm trying to convert the time format (hh:mm:ss) to this Special Time Format (hhmmt)?
The Special Time Format (STF) is a 5 digit integer value with the format [hhmmt] where hh are the hours, mm are the minutes and t is the tenth of a minute.
For example, 04:41:05 would convert to 4411.
I'm not sure how to convert the seconds value (05) to a tenth of a minute (1).
Edit:
I've incorporated Adithya's suggestion below to convert seconds to a tenth of a minute, but I'm still stuck.
Here is my current code:
String[] timeInt = time.split(":");
String hours = timeInt[0];
String minutes = timeInt[1];
double seconds = Double.parseDouble(timeInt[2]);
int t = (int) Math.round(seconds/6);
if (t>=10) {
int min = Integer.parseInt(minutes);
// min+=1;
t = 0;
}
String stf="";
stf += hours;
stf += minutes;
stf += String.valueOf(t);
int stf2 = Integer.parseInt(stf);
return stf2;
I'm using a String to store the minutes value but it makes it difficult to increment it since it is a String and not a Integer. But when calculating the "t" (tenth of minute) I have to add 1 to minutes if it exceeds 10. If I were to use parseInt again it will exclude the 0 in front of minutes again.
How can I retain the leading zero and still increment the minutes?
Thanks.
I am guessing, its the value of seconds, compared to the tenth of a minute, which is 6 seconds. So formula for t would be
t= seconds/6 //rounded off to nearest integer
This makes sense as this value is always between 0 and 9, as seconds range from 0 and 59, so its always a single digit
For your example
t = 5/6 = 0.833 = rounded off to 1
Note the 6.0f in the division - this helps you avoid the INT truncation.
string FormatSpecialTime(string time)
{
if (time.Length != 8) throw YourException();
int HH, mm, SS, t;
if (!int.TryParse(time.Substring(0, 2), out HH)) HH = 0;
if (!int.TryParse(time.Substring(0, 2), out mm)) mm = 0;
if (!int.TryParse(time.Substring(0, 2), out SS)) SS = 0;
t = (int) Math.Round(SS / 6.0f);
if (t >= 10)
{
mm++;
t = 0;
}
if (mm >= 60)
{
HH += mm / 60;
mm = mm % 60;
}
return HH.ToString() + (mm > 10 ? mm.ToString() : #"0" + mm) + t;
}
I am developing a Java countdown timer. I am totally new to Java though have done some C++ before so it's not all totally new. I am having problems with this - can anyone easily see what I have done wrong in the logic?
What is happening:
On run, if you enter in for example 23 in hours leave mins blank and put in 5 secs - the 5 secs should count to 0 - the mins should go to 59 and the hours to 22. However once the 5 secs elapses all digits go to zero.
If on the input box I enter though 23 hours 1 in minutes and 5 in secs - when the 5 has elapsed it changes to 22 hours 59 mins 59 secs so I know its nearly there (just hoping I may have missed something silly.
Finally the last problem with the logic - if I for example enter 30 mins 5 secs when the 5 have elapsed the mins go to 29 the secs go to 59 and continue counting down but the hours go to -1. Code below - sorry for long post but wanted to paint the scenarios - Thanks - Colly
Integer sec = new Integer (seconds.getText ());
Integer min = new Integer (minutes.getText ());
Integer hr = new Integer (hours.getText ());
int temp1 = sec.intValue ();
int temp2 = min.intValue ();
int temp3 = hr.intValue();
temp1--;
if (temp1 == -1 )
{
temp1 = 59;
temp2--;
if (temp2 == 0 && temp3 != 0)
{
temp2 = 59;
}
temp3--;
}
hr = new Integer (temp3);
sec = new Integer (temp1);
min = new Integer (temp2);
hours.setText (hr.toString ());
minutes.setText (min.toString ());
seconds.setText (sec.toString ());
if (seconds.getText ().length () == 1)
seconds.setText ("0" + seconds.getText ());
Please don't do time counting manually, it is painful to write and painful to read. I don't even mention how it feels to debug it.
The Calendar class may be interesting:
Calendar c = Calendar.getInstance();
c.clear(); // To reset all fields
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 5);
c.add(Calendar.SECOND, -1);
And you don't have to worry about counting.
Using Calendar for date/time is (despite its shortcomings) the right thing. There's a simple alternative here: Compute the total seconds like
int total = 3600 * hrs + 60 * min + sec;
decrement and decompose using
int x = total;
hrs = x / 3600;
x = x - 3600 * hrs;
min = x / 60;
x = x - 60 * min;
sec = x;
This is surely less error-prone than working on the parts, especially for more complicated operations. But again, I recommend using Calendar.
May it's because you are leaving the minutes text box blank. Can you try with a 0 there?
On run, if you enter in for example 23 in hours leave mins blank and
put in 5 secs - the 5 secs should count to 0 - the mins should go to
59 and the hours to 22. However once the 5 secs elapses all digits go
to zero.
I renamed your vars:
s--;
if (s == -1 )
{
s = 59;
m--;
if (m == 0 && h != 0)
{
m = 59;
}
h--;
}
If the seconds are 0, you decrement minutes. Then you test something, but without further tests, you always decrement hours.
While the code doesn't do what it should, it doesn't do what you describe. Is this your real code?