Why here I got different results? - java

I have next task: Given an array of ints, return true if the array contains no 1's and no 3's.
First version and it's right:
for (int i = 0; i < nums.length; i++){
if(nums[i] == 1 || nums[i] == 3)
return false;
}
return true;
but here's I got many wrong tests:
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 1 || nums[i] != 3)
return true;
}
return false;
Can you explain me reason why does it work like this? I supposed reason is something happened in second if(...)

The code should return true if there are no 1s and no 3s.
Let us take a look at your second code:
// Iterate all values
for (int i = 0; i < nums.length; i++) {
// Return true if value is not 1 OR not 3
if (nums[i] != 1 || nums[i] != 3)
return true;
}
// Return false
return false;
The key here is the condition val != 1 || val != 3 which is a tautology, i.e. it is true in all cases. Suppose a value of 5, it is not 1, so true is returned. Now suppose a value of 1, it is 1 but it is not 3, also true is returned.
You would need to substitute || by && which means and, which also better reflects your textual condition:
return true if the array contains no 1's and no 3's
However you can not directly return true if you found the first element which is not 1 and not 3. You first need to check all elements. However you can directly return false if you found the first 1 or 3. And that is exactly the first version of your code, which is correct.
Note that when negating a conditions you need to negate all quantifiers and operators too.
The first code realizes an approach using this logic:
Not (there exists one element which is 1 or 3)
¬(∃ e : e = 1 ∨ e = 3)
When now solving the negation you receive this logic:
All elements are not 1 and not 3
∀ e : e ≠ 1 ∧ e ≠ 3
So ∃ (exists) turns to ∀ (for all), = to ≠ and ∨ (or) to ∧ (and).

Why the first one works
It returns false if any item is not 1 or 3, and true if no items match
Why the second one does not work
It returns true all the time (if any item is not equal to 1 or 3, and no integer is equal to both 1 and 3), the only way to get false is to pass it an empty array.

You're implementing a short-circuit evaluation. The first version is right. In the second version, you prematurely return true when you encounter a number that isn't 1 or 3 - which is every number, since 1 is not 3 and vise versa.

For the second answer, you are using OR instead of AND. Hence whatever value you provide, it will always enter into the if condition.
Hope this helps.

Related

Java confused by this syntax

boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
boolean is a true or false.
! = not
|| = or
&& = and
but I still dont understand this syntax... can someone explain me what this syntax excactly does?
Just dissect it:
There are some comparisons such as
5 > 2 ... true
3 < 5 ... true
Those two are pulled together using &&; so true && true --> true
1 < 8 ... true
That one is or'ed to the rest; so we get true or true --> true
Finally, not (true) --> false
Long story short: if you don't understand the whole picture, break it down into the parts you understand; and then pull those together again.
Edit: and of course, the order I am using in my explanation isn't what happens in reality. There, 1 < 8 is evaluated first; and as that is true; and "true or X" is always true, the other comparisons are not even computed.
The not ! operator negates what it is in front of. In this case !() it will produce the opposite of the what is inside of the parenthesis.
the || or operator checks to see if one condition or the other is true. At least one must be true for the condition to return true.
Finally the && checks both sides of the conditional statement to see if they are both true, and both of them must be true to proceed.
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
Let's parse it the way Java does :
boolean : Here comes a boolean, i.e. true or false.
riddle : The variable riddle is declared to be a boolean.
= : The boolean variable riddle is initialized with the expression on the right.
!(...) : It returns a boolean, the negation (=opposite) of the boolean inside of the parentheses.
Inside the parentheses is a bool1 || bool2 expression, where || is a "lazy OR" operator. If bool1 is true, there's no need to evaluate bool2.
bool1 is 1 < 8, which is true.
bool2 isn't evaluated
bool1 ||bool2 is true
!(...) is false
riddle is initialized with false
At no point in time are 5 > 2 or 3 < 5 evaluated. Eclipse warns that those 2 expressions are "dead code" and could be removed.
The whole expression could be :
boolean riddle = !( 1 < 8 || (5 > 2 && doSomethingVeryDangerous()));
the result would be the same and no method call would happen at all.
The problem that you have is that you initialize at the same time as you are checking if it's true or false. You cannot compare boolean with integer. If you want to do it then you need to solve it in another way by converting from one datatype to another, or involve another variable in your solution. The way you need to solve your syntax problem is by dividing it like this:
How you did it...
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
How to potentially solve it...
boolean riddle;
"...some code to decide if riddle will be true or
false and assign it to the variable riddle..."
if (riddle == true){
"...do some code here...";
}
if (riddle == false){
"...do some code here...";
}
Or you can solve the problem by not using boolean as datatype and instead only use integers like this...
int riddle;
"...some code to decide what value riddle will
have and assign it to the variable riddle..."
if ( riddle < 8 && riddle > 1){
"...do some code here...";
}

Remove multi-elements from an arraylist error

public class test {
public static void main(String[] args) throws supernova, autowin{
ArrayList<Integer> integer = new ArrayList<Integer>();
integer.add(new Integer(0));
integer.add(new Integer(1));
integer.add(new Integer(2));
integer.add(new Integer(3));
System.out.println(integer.get(0));
System.out.println(integer.get(1));
System.out.println(integer.size());
for(int i = 0;i<2;i++){
if(i == integer.get(i)){integer.remove(i);System.out.println("remove");}
}
System.out.println(integer.get(0));
System.out.println(integer.get(1));
System.out.println(integer.size());
}
The outputs are
0
1
4
remove
1
2
3
.I expect this code to remove two elements(0 and 1),but it eventually only remove the first element. What if I want to remove all elements that have a special feature ,speaking like all elements store a odd number ,from an arraylist.
Could you explain the reason? Thank you a lot.
When you use the remove method, all elements ahead of the index are moved to the left. Therefore, after the first element is removed, i == integer.get(i) will always be false, because the Integer's value was set to be its original index, but now they are all "one ahead", so to speak.
Use a debugger in an IDE to see the process happen.
After the first iteration (i=0) the list is modified and becomes to
[1, 2, 3]
then for the next iteration i=1 adn then you do
if (i == integer.get(i)) {
if 1 == elementAtIndex1--> if 1==2 wich returns false an is not removing anything....
therefore your code is behaving like that...
Lets go step by step:
in for loop, when i = 0, you remove value from arraylist on position 0. Now, your ArrayList will be 1,2,3. Now, you check position i = 1, and in that position you have 2, not 1. because 2 is not equal to 1, if will not be executed.
One solution would be to change the direction of the for loop:
for(int i = 1;i >= 0;i--){
if(i == integer.get(i)) {integer.remove(i);System.out.println("remove");}
}
Now, the output will be:
0
1
4
remove
remove
2
3
2
Update: OP asked new question
If you want to remove odd numbers, just place logic for it in if:
for(int i = integer.size() - 1;i >= 0;i--){
if(integer.get(i) % 2 != 0 {
integer.remove(i);
System.out.println("remove");
}
}

What exactly does this piece of code do? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am a beginner programmer,
I have an array called myArray and was wanting to know what exactly the if statment in this code does. Also what does myArray[count] do?
for(int i = 0; i < count; i++)
if (number == myArray[i])
{
containsNumber = true;
}
if ( !containsNumber )
{
myArray [ count ] = number;
count++;
} // end if
Cheers
Notice
Because the code is not complete I have to do some assumptions:
All variables are declared and initalized before
count represents the number of elements in the array
The array is sufficiently sized
containsNumber is initalized with false
Short
It checks if the given number exists in the array and if not it will add it.
Explained
At first, to make it a bit more readable we can add two braces after the for instruction:
for(int i = 0; i < count; i++)
{
if (number == myArray[i])
{
containsNumber = true;
}
}
if ( !containsNumber )
{
myArray [ count ] = number;
count++;
} // end if
Because there are no breaces after the for it will just affect the following statement or block, which is the if statement.
At first the code will loop through the array and check every position smaller than count (value of i ) for the given number.
If the value is found (if (number == myArray[i])) the variable containsNumber is set to true.
After iterating over the array the variable containsNumber is checked.
An if statement must contain a boolean value, so you can just write if (containsNumber) instead of if (containsNumber == true).
The ! negates the boolean value. That means you check if containsNumber is not true. if (containsNumber != true) or if (containsNumber == false) would be the same.
If the number is not in the array (containsNumber is false) than it is added at the next position (myArray [ count ] = number;) and count is incremented by one (count++;).
Example
Let's say the array contains the values 1, 5 and 7.
Number has the value 4 and count is 3 because the array contains 3 elements.
For loop:
First iteration
i has the value 0 --> 0 is smaller than 3 (count)
if (number == myArray[i]) --> if (4 == myArray[0]) --> if (4 == 1)
--> false
Second iteration
i has the value 1 --> 1 is smaller than 3 (count)
if (number == myArray[i]) --> if (4 == myArray[1]) --> if (4 == 5)
--> false
Third iteration
i has the value 2 --> 2 is smaller than 3 (count)
if (number == myArray[i]) --> if (4 == myArray[2]) --> if (4 == 7)
--> false
Fourth iteration
i has the value 3 --> 3 is not smaller than 3 (count)
for ends
Next step
containsNumber is still false
if ( !containsNumber ) --> the value of containsNumber is negated what means if (true)
myArray [ count ] = number; --> myArray [ 3 ] = 4;
The value of number (4) is set to the fourth position of the array (remember, the array starts with 0).
Now the array contains the values 1, 5, 7 and 4.
It seems to me that it's searching for a value. If it exists, skip. If it doesn't, add it in. Here's the pseudocode:
for i = 0 to the value in count
if number is equal to myArray at position i
Set a flag to say the number has been found.
if(the flag is not set, the number has not been found)
Set myArray at position count to the number i'm searching for
increase count.
if the "number" is not in the "myArray" Array the number would assign to the array on the current position (count).
The first if statement
if (number == myArray[i])
checks if the item at position i in the myArray is equal to the value that the variable number contains
The second if statement
if ( !containsNumber )
Checks if the value of the variable containsNumber is false. If it is, it probably means that the array doesn't contain the number
In this case, myArray [ count ] = number; set the item at position count of the array to the number that you were previously searching, so that now the array contains also this value
There are two if statements, which one do you mean?
if (number == myArray[i])
If number is equal to element i in myArray.
if ( !containsNumber )
If containsNumber is false.
It will check the number in myArray. If myArray didn't contain number then it will store the number at last index of myArray specified by count and increment count by 1.
The first IF statement
if (number == myArray[i])
checks if the number is there in myArray. If not then it adds the number at the current index position & increments the count.
Actually, the code that you put only checks if the value 'number' exist in the array 'myArray'. Then, an IF condition checks if the variable containsNumber and increases the limit 'count' used in the FOR. But this IF condition is not part of the FOR, it is outside.
Probably it lacks of curly brackets to delimitate the FOR.
This is what is interpreted by the machine:
for(int i = 0; i < count; i++)
if (number == myArray[i])
{
containsNumber = true;
}
if ( !containsNumber )
{
myArray [ count ] = number;
count++;
} // end if

Java - for() loop and arrays

The next question is from test that I've done.. I've run the code on BlueJ and don't get why the return value is 5...
public int mystery(int[] myStuff, int num) {
for (int k = myStuff.length - 1; k >= 0; k--) {
if (myStuff[k] < num) {
return k;
}
}
return -1;
}
myStuff = 2, 4, 0, 1, -6, 3, 8, 7, 5
num = 4
In the test I wrote - 0. Why 5? I don't get it!
What is the part of the
`return -1`
?
You're getting 5 because that is the index of the first element in the array whose value is less than 4 (when starting from the last element and working towards the first). Note that you have:
return k;
...where k is your array index. If you wanted to get the value at that index, you should do:
return myStuff[k];
Here's a simple example that shows that your result is in fact correct: http://ideone.com/7byIY
And the return -1; is just saying "if no elements are less than the specified number then return a value of -1 to indicate that no match was found". This is not an uncommon practice (returning an intentionally chosen, invalid value to indicate that there is no result).
It returns five because that's the index of 3 in your input array, which is the first number strictly smaller than 4 starting from the end of your array.
return -1; would be executed if none of the items in your array satisfy the "strictly smaller than num" criteria.
The function returns the largest index in the array corresponding to a value less than the target. This is accomplished on arbitrary arrays by scanning from the back and returning the first index corresponding to a value less than the target. In your example, 3 < 4 at index 5, so this is the correct answer. If no values smaller than the target are found, -1 is used as a sentinel value to indicate the algorithm failed to find a valid answer.
That function gives the position of the last number in the first argument that's smaller than the second argument (or -1 if all the numbers are larger than the second argument; -1 is a special value with no chance of ambiguity because there's no position -1).
That number is 3 and its position is 5 (starting with 0).
This function just searches for the last value in the array which is greater or equal than num. Let's compute the check myStuff[k] < 4 for all values:
0 1 2 3 4 5 6 7 8 // k
2 4 0 1 -6 3 8 7 5 // myStuff[k]
true false true true true true false false false // myStuff[k] < 4
The last index for which myStuff[k] < 4 is true is obviously 5, so that's the correct answer.
return -1 is needed so that the function returns a value, even if all elements of myStuff are larger than num. For example, with num = -99, the result would be -1.
your return-1 doesn't mean anything for the parameters you have passed here.
as the condition is true for value 3 so it returns the value of k, which is nothing but 5 bt that movement. this is because you are iterating backwards.
mystery(myStuff=[2,4,0,1,-6,3,8,7,5], 4)
then the for begins
for (int k = 8; k>=0; k--)
if ( myStuff[8]=5 < 4) - NO
2nd iteration
k = 7 if (7 < 4) - NO
... so on
k = 6 if (8 < 4) - NO
k = 5 if (3 < 4) - YES - so return k = 5
The last part means:
if myStuff does not have any value < num then it returns -1

combination of combination java

I need to find combination of combination in JAVA.
I have for instance 6 students in class. Out of them, I need to create combination of 4 people in group, and for each group I can choose an intimate group of 2.
I have to make sure that there are no doubles (order does not matter).! and need to print the 4 people group.
However, this is the hard part:
So defining students with numbers:
If I print out 1234 as one of the combinations, I can't print out1256 as well, since 12 appears both in 1234 and in 1256.
How can I write it in Java?
EDITED
output of ([1,2,3,4,5],3,2) will be:
Combinations without repetition (n=5, r=3)
{1,2,3} {1,2,4} {1,2,5} {1,3,4} {1,3,5} {1,4,5} {2,3,4} {2,3,5} {2,4,5} {3,4,5}
deleting repeating groups of 2 elements, will leave me only:
{1,2,3} {1,4,5} (i deleted groups that have combinations of 12,13,23,45,14,15 since they already appear in the first two that I have found.
Ok, here's the simple emulation of the process you described. But I use binary numbers to present set, it makes manipulations easier. For example, number 19 is 10011 in binary form: it means students 0, 3 and 4 are selected (there're 1's in those positions).
A little helper first.
// return all subsets of 'set', having size 'subsetSize'
Set<Integer> allSubsets(int set, int subsetSize) {
Set<Integer> result = new HashSet<Integer>();
if (subsetSize == 0) {
result.add(0);
return result;
}
if (set == 0) {
return result;
}
// check if 1st element is present
if (set % 2 == 1) {
// use 1st element, one less element to collect
for (Integer i : allSubsets(set / 2, subsetSize - 1)) {
result.add(i * 2 + 1);
}
}
// not use 1st element
for (Integer i : allSubsets(set / 2, subsetSize)) {
result.add(i * 2);
}
return result;
}
And main program. Suggestions are welcome.
int N = 5;
int M = 3;
int Z = 2;
List<Integer> result = new ArrayList<Integer>();
// get all groups of M elements from 'wholeSet'
int wholeSet = (1 << N) - 1;
for (int s : allSubsets(wholeSet, M)) {
// Check all subsets of 'Z' elements from set 's'
boolean valid = true;
for (int t : allSubsets(s, Z)) {
// check if this Z-element subset already was used
for (int past : result) {
// check if 't' is subset of 'past' set
if ((past|t) == past) {
valid = false;
break;
}
}
if (!valid) {
break;
}
}
if (valid) {
// none of Z-element subsets of 's' were used before
result.add(s);
}
}
But it may require improvements (like memoization) for big inputs. But for now, since you don't say what kind of input you expect, I assume this is good enough.
Imagine you have a Student object with an equals comparing their Primarykey. In your example, student 1 will return 1, 2 will return 2 and so on.
Put them all in the set, this will ensure that there will be no double.
Iterate though the set by 4 then by 2 and will return you your desired result.

Categories