Total noobie question here.
I'm just learning Java, and studying passing arguments to functions. I created this basic example, and it is doing what I expect, but I want to be sure I am understanding the "signal path" correctly:
public void run() {
int value = 4;
println(" the value is "+ add(value));
}
private int add(int n) {
int result = 4;
result = n + result;
return result;
}
}
Am I correct to say that:
1) the int value is being passed from add(value) to the private method and so then int n = 4
2) then the result = n + return. (8)
3) then the return result passes back to the public method and takes the place of add(value).
Is my thinking correct?
Thanks!
Joel
Yes, precisely.
1) the int value is being passed from add(value) to the private method and so then int n = 4
The int value is being passed to the method add(), and then int n will be 4.
2) then the result = n + return. (8)
Yes, that's true. An alternate syntax would be result += n; Which would do the exact same thing.
3) then the return result passes back to the public method and takes the place of add(value).
Yes, then the value is returned from add and that is the value that would be used.
Your thinking is correct.
Yes, this is what parameter passing and value returning is all about. Note that in Java, everything is passed by value.
This means the following:
void f(int x) {
x = 0;
}
void main() {
int n = 10;
f(n);
// n is still 10
}
On (2) that should be "result = n + result", not "n + return". But I think that's just a typo, you appear to understand what's going on.
Related
I'm having some problems whit an exercise I found.
I was provided a method, and can't make any changes to it.
Inside said method, I should identify the first repeating digit, beetwen two integers, And return it's position.
For example: 1234 and 4231 results in 1.
And I managed to make it work,
It's just that it doesn't work if I try to use the method more than once, it simply keeps adding to the previous value.
This is my code so far
public static final int BASENUMERACAO = 10;
public static int indice = 0;
private static int getLowestIndexWithSameDigit(int a, int b) {
if (a < 0 || b < 0) {
throw new IllegalArgumentException("Both numbers should positive " + a + " " + b);
} else {
if (a % BASENUMERACAO == b % BASENUMERACAO) {
return indice;
} else if (a / BASENUMERACAO != 0 && b / BASENUMERACAO != 0) {
indice++;
return getLowestIndexWithSameDigit(a / BASENUMERACAO, b / BASENUMERACAO);
} else {
return -1;
}
}
I tried passing index, as a local variavel, but it just overrides the curent value, everytime it's called, therefore only returning 0 or -1
Could someone tell me how to I do keep count in a recursive method, or just how do I identify the digit whitout a counter?
The problem is that you are retaining state from the previous invocation, in the indice variable. indice is an example of mutable global state, which is generally a bad idea for the reason you are experiencing here: you might carry over the results of previous calculations into new calculations, leading to unpredictable (or maybe unexpected) results.
Make your indice variable a parameter of the method:
private static int getLowestIndexWithSameDigit(int a, int b, int indice) {
// ...
}
So your recursive call will also pass a value for this:
return getLowestIndexWithSameDigit(a / BASENUMERACAO, b / BASENUMERACAO, indice);
To start the iteration, you can either explicitly pass 0, or you can create a method which takes just a and b:
private static int getLowestIndexWithSameDigit(int a, int b) {
return getLowestIndexWithSameDigit(a, b, 0);
}
Create another method to call your recursive method and use the vars that you need as parameter for the recursive version and keep passing them.
Something like:
private static int myMethod( int a, int b ) {
return myRecursiveMethod( a, b, 0, 0 );
}
private static int myRecursiveMethod( int a, int b, int var1, int var2 ) {
// do the recursive work...
myRecursiveMethod( newValueForA, newValueForB, var1, var2 ) {
}
Could anyone give me some clue about how could I Transform this code to recursion:
public class arrayExample {
public static void main (String[] args) {
int[] a = {2,2,2,2};
int[] b = {2,2,2,2};
int n = a.length;
int sum = 0;
for (int i = 0; i < n; i++) {
sum += a[i] * b[i];
}
System.out.println(sum);
}
}
So to do this do product with recursion.
You asked for a hint, so I'm not giving you the complete solution. When you want to process a list (or an array) recursively, the concept is nearly always:
public int recursiveFunction(List l, int carry) {
if (l.isEmpty()) {
return carry;
}
return recursiveFunction(l.subList(1, l.size()), operation(carry, l.get(0));
}
Where operation is whatever you want to do with your list. carry is used to provide an initial value (in the first call) and save the interim results.
You just have to change the code so it uses two arrays instead of one list and choose the correct operation.
Ok so hoping you have tried it before this is one possible way to code it.
public class ArrayExample {
public static void main (String[] args) {
int[] a = {2,2,2,2};
int[] b = {2,2,2,2};
int n = a.length;
int result = recurseSum(a, b, n-1);
System.out.println(result);
}
public static int recurseSum(int[] a, int[] b, int n){
if(n == 0)
return a[0]*b[0];
else{
return (a[n] * b[n]) + recurseSum(a,b,n-1);
}
}
}
This code is basically doing the same thing in the iteration.
The recursive call happens 4 times. When n hits 0, a[0]*b[0] is returned to the higher call. so basically from right to left it happens as follows:
a[3]*b[3] + a[2]*b[2] + a[1]*b[1] + a[0]*b[0]
One simple way to make a loop into a recursion is to answer these two questions:
What happens when the loop executes zero times?
If the loop has already executed n-1 times, how do I compute the result after the n-th iteration?
The answer to the first case produces your base case; the answer to the second question explains how to do the recursive invocation.
In your case, the answers are as follows:
When the loop executes zero times, the sum is zero.
When the loop executed n-1 times, add a[n] * b[n] to the previous result.
This can be translated into a recursive implementation
static int dotProduct(int[] a, int[] b, int n) {
... // your implementation here
}
I want to calculate the factorial of a number with a get method (I must solve a bigger problem). Here's what I tried and it returns 1:
public Sigma() {
n = -1;
}
public Sigma(int n) {
n = n;
}
private int Facto(int n) {
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
public int getFacto() {
return Facto(n);
}
The problem is that, in your constructor, you type n = n rather than this.n = n. The problem with this is that the local variable inside the constructor is assigned, rather than your class's field. this.n refers to the field n and is what you want.
You are receiving an output of 1 because the default value of all primitive number fields is 0. Using your code, 0! = 1 (which is correct), so that's your output no matter what you pass into the constructor, as the constructor ignores its parameter.
On an unrelated note, please use camelCase rather than UpperCase for method names (and field names). UpperCase should only be used for classes/interfaces/enums/annotations. Also, result = result * n may be simplified to the (almost) equivalent statement result *= n.
For the factorial you need to initialize result in the facto function, like this
private int Facto(int n)
{
int result = 1;
for (int i = 1; i <= n; i++)
{
result = result * i;
}
return result;
}
Usually, when assigning a number to an int larger than 2,147,483,647, then the code won't compile. But in the following snippet, result is larger than (2^31)-1, and it can still print. I know that the "correct" result is obtained by letting result be long , but how come this still prints something and what happens behind the scenes? Thanks in advance.
public class intAssigning
{
static int n = 500000;
static int i;
static int result;
//static long result;
static boolean [] array = new boolean [n];
public static void main(String[] args)
{
for (i = 0; i<n; i++)
{
array[i] = true;
}
for (i=2; i<n; i++)
{
if (array[i])
{
result+=i;
}
}
System.out.println(result);
//result with long: 124999750000
//result with int: 445698416
}
}
If you try to assign a constant that is longer that the maximum size of the int you'll face a compiler error, and if you try to do this at runtime with a variable or some arithmetic manipulations that the compiler cannot detect the exceedance, it will over flow.
E.g. :
int i = Integer.MAX_VALUE;
i = i+1;
System.out.println(i);
output: -2147483648
The value cannot be assigned, meaning it can't appear at the right of the assignment operator, because it's a compile-time constant and is known to be out of the integer bounds, so it's not even a valid int literal, in a sense (btw, beside assignment, it cannot appear in expressions, argument to method calls, and anywhere an int is expected)
However, when arithmetics are performed on integers inside the JVM, values can wrap and you'll have negative numbers or otherwise unrelated figures, depending on the particular operation (addition, multiplication) and operands involved.
This happens because the value overflows. This means when you do this
int i = Integer.MAX_VALUE;
i = i+1
then the value overflows, which means it goes back to the minimum value (Integer.MIN_VALUE) and continues from there. If it underflows, it goes back to the maximum value and continues from there.
Your other problem is a feature of the compiler. It prevents you to assign a "bad" value at the first place.
For your behind the scenes (with int 4bytes):
It's eaiser to understand arithmetical operation with overflow if we use binary representation, consider this
long l = 0x7FFFFFFF; // 2147483647
l = l + l;
System.out.printf("%x %d %n", l, l);
int i = 0x7FFFFFFF; // 2147483647
i = i + i;
System.out.printf("%x %d %n", i, i);
output
fffffffe 4294967294
fffffffe -2
that is during int overflow bits above 32 are lost
public class negativeTest {
public static int Negativenum (int[] array) {
int negative = 0;
for (int i = 0; i < array.length; i++){
if(array[i] < 0){
negative = negative + 1;
}
System.out.println(negative);
}
}
}
I am trying to count how many elements in array are negative. This is what i have so far. My question is: eclipse is telling me that i should return a void instead of static int? How can i do this without using void?
I'd want to use
public static int negativenum(int[] array){
Only way i can get this working is create an array with positive and negative numbers and count them, but i want to be able to have method that does that without creating array of numbers. Can you help me?
Try giving a return statement , your method is expecting a int as a return parameter.
Therefore it will give compiler error.
public class negativeTest {
public static int Negativenum (int[] array) {
int negative = 0;
for (int i = 0; i < array.length; i++){
if(array[i] < 0){
negative = negative + 1;
}
System.out.println(negative);
}
return negative;
}
}
Ther error you are getting is because you have not declared the main function inside the class.
You have to call Negativenum from the main function.
you can do it like this :
public static void main (String args[])
{
negativeTest nt = new negativeTest();
int [] array = new int[]{ 100,200 };
int count = nt.Negativenum(array);
System.out.println(count); // It will print **2**
}
Regarding your doubts you have asked in comments.
You have to return anything from function only when you want to use that use that return value from the calling function.
Otherwise if you want to just print that value on console or log that value , you can easily do it in the negativeTest function and you can change the return type of this function to void.
FYI , you should not begin your classname with the lower case character.
The error is because you are not returning anything from the function which is expected to return an int.
If you want the function to count the number of negative numbers and return the count so that the caller of the function gets the count, you can add an
return negative;
before the end of the function.
Alternatively if you don't want to return anything from the function and want to just print the count as part of the function call, you can change the return type of the function from int to void:
public static void Negativenum (int[] array) {
Your function signature suggest a return type of int, but you aren't returning anything from the function. I suspect this is why Eclipse is suggesting you change the function signature to return void.
If you add return negative; it should avoid the notice from Eclipse.
If your intention is to simply print the count, then you should change the return type.
if you dont want to return anything, set your method signature to void, but add an out variable, like so:
public static void NegativeNum(int[] array, out int negative)
{
negative = 0;
foreach(int i in array) { if (i < 0) negative++;
}
then you just declare negative wherever this method is called from, and pass it in as an out variable:
int negative = 0;
NegativeNum(array, out negative);
After that call, negative will contain the count of negative numbers determined by the method.