int fnum = Integer.parseInt(split[0]);// holds 5
//split[] holds each line of the file.
double sum = fnum;// sum = 5
double i = 0.0;
double last = 0.0;
for(int j = 1; j<(split.length-1);j++)
{
i = Integer.parseInt(split[j].replaceAll("[^0-9]", ""));
if(split[j].charAt(0) == '*')
{
sum = sum * i;
}
else if(split[j].charAt(0) == '/')
{
sum = sum / i;
}
else if(split[j].charAt(0) == '+')
{
sum = sum + i;
}
else if(split[j].charAt(0) == '-')
{
sum = sum - i;
}
else if(split[j].charAt(0) == '%')
{
sum = sum % i;
}
}
System.out.println(sum);// Prints 1.0
}
}
/*
Actual Data File Imported
5
+ 3
* 7
+ 10
* 2
* 3
+ 1
% 11
Answer should be : 1
*/
Alright My code may look messy, but I tried hard on it. Gave up a few times but tried again. My question is for smaller data sets such as the one I imported and commented out on the code on the last few lines, work fine. But for bigger data sets it's all wrong why is that? I've tried making al my data sets double to get bigger values but somehow it's wrong?
I'm a beginner so far, any help would be greatly appreciated.
To be more specific on the problem I imported the file, I made it all a String, line by line, then I added it all in a String array so each line was in a string array for example split[1] would print + 3. Now after that I isolated the number and the symbol in the if loop wrapped in a forloop to go over all the sets. Now the if loop captures the symbols and then does the appropriate arithmetic. SomeHow it didn't though? And I used a double instead of an int for sum. That didn't help.I believe the if statement could be the issue.
Not sure if you still need the answer but, here's a tip:
The whole point of that specific exercise was to learn the modular arithmetic, which is that if you sum up/multiply the remainders of all of the numbers, you get the same answer as you would using the numbers given, that is if you apply the same number that's after % for all of them.
For example:
14
+ 78
* 9
* 3
+ 4
% 3
After all of the applied operations, the numbers above % 3 result in 2488.
And so 2488 % 3 = 1.
So if you apply % 3 to each one of the numbers, including the initial one, you get the same answer, using the same operations on their remainders of course and dividing the sum again by 3.
14 % 3 = 2
78 % 3 = 0
9 % 3 = 0
3 % 3 = 0
4 % 3 = 1
So, you get 2 + 0 * 0 * 0 + 1 which equals to 1.
And 1 % 3 = 1 which is the same as 2488 % 3 = 1.
My point being, you should apply modulo to every one of the numbers, so you get little numbers and don't even have the big ones you're having problems with.
Hope this was clear enough and hope it helps.
Related
I am doing exercises with algebraic formulas to practice the use of recursion in Java.
I am trying to write a method that returns the result of n + (n - 3) + (n - 6) + (n - 9) ... + 0.
For example, when n = 7, the result should be 12.
When n = 10, the result should be 22.
So far, this is what I have:
public static int sumDownBy3(int n)
{
if(triSum <= 0)
{
return sum;
}
sum = n;
triVar += 3;
triSum = (n - triVar);
return sumDownBy3(n + triSum);
}
However, when I compile and run it, it does not return the expected result.
How may I fix this method to correctly apply the formula I am trying to emulate?
So, here are a few tips to hopefully get you going considering the comments by childofsoong and Jonny Henly.
What you are looking for is simply:
f(n) = n + f(n-3) for n > 0.
Your recursive function should just check if n is <= 0. If it is, return 0. Else return the variable n + another call to your function with n-3.
Hope this helps without giving too much away.
Since this isn't an assignment, just practice, then here is a working solution based off the information given in your question. This solution works for all n, however n <= 0 will always return 0.
public static int sumDownBy3(int n) {
if (n <= 0) {
return 0;
}
return n + sumDownBy3(n - 3);
}
Instead of having an extra parameter or global/class variables keeping track of the sum, this example just uses the stack to keep track of the sum. One downside to this approach is that for a very, very large number the stack could overflow and/or the program could lock up.
Output:
sumDownBy3(7) = 12
sumDownBy3(10) = 22
sumDownBy3(9) = 18
Breakdown for sumDownBy3(10):
sumDownBy3(10): 10 !<= 0 -> return 10 + sumDownBy3(10 - 3)
sumDownBy3( 7): 7 !<= 0 -> return 7 + sumDownBy3( 7 - 3)
sumDownBy3( 4): 4 !<= 0 -> return 4 + sumDownBy3( 4 - 3)
sumDownBy3( 1): 1 !<= 0 -> return 1 + sumDownBy3( 1 - 3)
sumDownBy3(-2): -2 <= 0 -> return 0
So 0 + 1 + 4 + 7 + 10 ='s 22
Is there a difference between the way that the Modulo operates calculates values in Java vs the way that it does in VBScript?
Both of these are returning a digit that I am using as part of a larger number later in the code but I believe the issue is between the way VBScript and Java are handling the Mod operator. I may be wrong though.
I am trying to work through reasons why I am seeing different outputs from when I run the below VBscript code block vs my replicated version in Java, sorry for the delay in updating the post.
The function takes in a String and then works to determine a return digit based upon the logic in the loop. The missing code just has to do with initializing the variables used, and determining the length of the string to loop over.
Any help would be greatly appreciated! Thank you
VBScript:
For i=1 to Length
CurrentNumber = Mid(CCNumber,i,1)
CurrentNumber = Int(CurrentNumber)
If (i mod 2) <> 0 then
ModNumber = CurrentNumber * 2
If ModNumber > 9 then
Total = Total + 1 + (ModNumber mod 10)
Else
Total = Total + ModNumber
End If
Else
Total = Total + CurrentNumber
End If
Next
cd = ((Int(Total/10) + 1) * 10) - Total
if cd = 10 then cd = 0
CheckDigit = cd
Java:
for (i=0; i<length; i++)
{
String currentNumberString = CCNumber.substring(i,i+1);
currentNumber = Integer.valueOf(currentNumberString);
if (i % 2 != 0)
{
Integer ModNumber = currentNumber * 2;
if (ModNumber > 9)
{
total = total + 1 + (ModNumber % 10);
}
else
{
total = total + ModNumber;
}
}
else
{
total = total + currentNumber;
}
}
int cd = ((Integer.valueOf(total/10) + 1) * 10) - total;
if (cd == 10)
{
cd = 0;
}
return cd;
}
One difference: The Mod operator in VBScript always returns an integer. Java's % operator can return a fractional value. So 5.2 Mod 2 evaluates to 1 in VBScript, but 5.2 % 2 evaluates to 1.2 in Java.
Edit: Based on your edit, this appears to be the Luhn algorithm. The only real problem with the Java code is a typo; nothing to do with the mod operator. Here you assign a variable currrentNumber (with a triple R):
currrentNumber = Integer.valueOf(currentNumberString);
Then you use a different variable (double R):
Integer ModNumber = currentNumber * 2;
Edit: Another difference is that because VBScript string indices start at 1, and Java string indices start at 0, the code is using different alternate digits. Either If (i mod 2) <> 0 should be If (i mod 2) = 0, or if (i % 2 != 0) should be if (i % 2 == 0), I'm not sure which.
So, I want to find what numbers between 1 and 100 are divisible by 3 and 7. I got it to work, except for one of the numbers. For some reason, 3 % 3 is giving me 3 as a remainder, but 6 % 3 is giving me 0. This is my code:
public class factors
{
public static void main(System args[])
{
//Variables
int integer, remainder;
//Displays header
System.out.print("Integers less than 100 that are \nevenly divisible by 3 or 7");
//Loops through each integer
for (integer = 1; integer <= 100; integer++)
{
remainder = integer % 3; //determines if 3 is a factor
if (remainder == 0) //displays integer
{
System.out.println(integer + " is divisible by 3");
}
remainder = integer % 7; //determines if 7 is a factor
if (remainder == 0) //displays integer
{
System.out.println(integer + " is divisible by 7");
}
}
}
}Does anyone know why this isn't working for the number 3?
You code is actually doing
remainder = 3 % 7; // equals 3.
The best way to determine why your code is not doing what you think is to step through your code using a debugger.
All the multiples of 3 & 7 will be multiples of 21, i.e. 21, 42, 63, 84.
Your 3 is getting tacked onto the end of the line of text above. You'll be seeing
Integers less than 100 that are
evenly divisible by 3 or 73
because you wrote print instead of println for this line of text. The % operator is working just fine, and 3 % 3 is indeed 0, not 3.
You are not outputting a remainder - you are displaying integer. So for 3 it should print 3.
Make you print statements more definite:
System.out.println(integer + " is divisible by 3"); // for the first `if`
and
System.out.println(integer + " is divisible by 7"); // for the second `if`
This should clear your confusion.
Your logic prints number divisible by 3 or 7.
Firstly, your code can be shortened to:
//and
for (int i = 1; i <= 100; i++){
if(i % 3 == 0 && i % 7 == 0) {
System.out.println(i);
}
}
//or
for (int i = 1; i <= 100; i++){
if(i % 3 == 0 || i % 7 == 0) {
System.out.println(i);
}
}
Also I note you're not declaring a type for your integer, remainder variables. I didn't attempt to recreate with those issues; start by solving that.
I need some explanation for this code.
This is the example code given by others.
for ( int i = 1; i <= 8; i++ )
{
if(check % 2 == 0)
sum += i;
else
sum -= i;
check /= 2; <--- Need explanation for this line.
}
But in the Pseudo code, there is no check /= 2; procedure.
Here is the full Pseudo code.
int binary = 0;
int sum;
while(binary<256)
sum = 0;
for(go through all 8 digits)
if the i-th digit is 0
sum += i
if the i-th digit is 1
sum -= i
end for
if sum == 0
output
binary++
end while
So, what is the purpose for that line of code?
Since sum, binary, and check is initialize as 0.
I have written this code using the Pseudocode given above.
But seems like my code will duplicate the output and one more problem, the format.
I want the output be like this format:
Enter a number : 3
-1 -2 +3 = 0
1 +2 -3 = 0
But my currently output is:
Enter a number : 3
-1 -2 3 = 0
1 2 -3 = 0
Here is my code:
CODE IS REMOVED!
Solved!
I'm too focus on the for-loop for the output part, hence miss the while-loop for the binary, because the pseudocode is for 256 possible solutions, hence, there will be same output for the front part, example:
1 - 2 - 3 + 4 = 0
1 - 2 - 3 + 4 + 5 - 6 - 7 + 8 = 0
Hence, the pseudocode may give an same output. So, since the solution is in 2 ^ n where n = 1, 2, 3, ... form, so change the
while( binary < 256 ) ---> while ( binary < Math.pow(2, input))
should solve it.
The format and the duplicate of the answer are solved.
This is the way to go through all digits. The most right digit is retrieved by check % 2, and after checking it, you shift check one digit (bit) to the right by check /= 2 (equals to check = check / 2;)
With this algorithm you are counting all the bit set to 1 and set to 0.
check /= 2;
it is like
check = check / 2;
and you can use it to shift all bits right by one.
For example:
(binary) 101 / (decimal) 2 = (binary) 10
that is 101 shift right by one digit.
Let's look at this line:
check /= 2;
In Java it is equivalent to the following simple statement:
check = check / 2;
Now let's find out the purpose behind it:
The right most digit is checked by check % 2
Then it is shifted right by one digit by check /= 2
check /= 2 is equivalent to check = check / 2;
its just a way of combining multiple assignments into a single one, like sum += 2 is equivalent to sum = sum + 2;
I know how to get the program to add up the sums of the multiple for each of 3, 5 and 7, but I'm not sure how I'd get the program to only use each number once. For example, I can get the program to find out all of the numbers and add them up for 3 and then do the same for 5, but then the number 15 would be in the final number twice. I'm not sure exactly how I'd get it to only take the number once. Thanks for any help.
While the generate-and-test approach is simple to understand, it is also not very efficient if you want to run this on larger numbers. Instead, we can use the inclusion-exclusion principle.
The idea is to first sum up too many numbers by looking at the multiples of 3, 5 and 7 separately. Then we subtract the ones we counted twice, i.e. multiples of 3*5, 3*7 and 5*7. But now we subtracted too much and need to add back the multiples of 3*5*7 again.
We start by finding the sum of all integers 1..n which are multiples of k. First, we find out how many there are, m = n / k, rounded down thanks to integer division. Now we just need to sum up the sequence k + 2*k + 3*k + ... + m*k. We factor out the k and get k * (1 + 2 + ... + m).
This is a well-known arithmetic series, which we know sums to k * m * (m + 1)/2 (See triangle number).
private long n = 9999;
private long multiples(long k) {
long m = n / k;
return k * m * (m + 1) / 2:
}
Now we just use inclusion-exclusion to get the final sum:
long sum = multiples(3) + multiples(5) + multiples(7)
- multiples(3*5) - multiples(3*7) - multiples(5*7)
+ multiples(3*5*7);
This will scale much better to larger n than just looping over all the values, but beware of overflow and change to BigIntegers if necessary.
The easiest approach would be to use a for loop thus:
int sum = 0;
for(int i=1; i<10000; i++)
{
if (i % 3 == 0 || i % 5 == 0 || i % 7 == 0)
sum += i;
}
Use a Set to store the unique multiples, and then sum the values of the Set.
I would use a Set. This way you are guaranteed that you won't get any duplicates if they are your main problem.
One simple solution would be to add each number thats a multiple of 3,5, or 7 to an Answer list. And then as you work thru each number, make sure that its not already in the answer list.
(pseudo-code)
List<int> AnswerList;
List<int> MultiplesOfFive;
List<int> MultiplesOfSeven;
List<int> MultiplesOfThree;
for (int i = 0 ; i < 10000; i++)
{
if ( i % 3 == 0 && AnswserList.Contains(i) == false)
{
MultiplesOfThree.Add(i);
AnswerList.Add(i);
}
if ( i % 5 == 0 && AnswserList.Contains(i) == false)
{
MultiplesOfFive.Add(i);
AnswerList.Add(i);
}
if ( i % 7 == 0 && AnswserList.Contains(i) == false)
{
MultiplesOfSeven.Add(i);
AnswerList.Add(i);
}
}
for the solution that loops 1 to 1000 use i<=10000 otherwise it'll skip 10000 itself which is a multiple of 5. Apologies, for some reason i can't post this as a comment