I need to create a recursive Boolean method named isMemeber. The method should accept two arguments ONLY: an array and a value. The method should return true if the value is found in the array, or false if the value is not found in the array.
I think that the base case will be if the passed array is empty, but I need help with the recursive case:
public static boolean isMember(int[] array, int value)
{
if(array.length==0){
return false;
}else{
return isMember(???);
}
}
Here is how it looks with position variable:
public static boolean isMember(int[] array, int value, int position)
{
if (position > -1)
{
if (array[position] == value)
{
return true;
}
else
{
return isMember(array, value, position - 1);
}
}
return false;
}
If you need to use recursion you can copy the array on each recursion. This is inefficent, but using recursion is inefficient compared with using a loop. e.g. Arrays.indexOf()
public static boolean isMember(int[] array, int value) {
if(array.length == 0) return false;
if(array[0] == value) return true;
int[] array2 = new int[array.length-1];
System.arraycopy(array,1,array2,0,array2.length);
return isMember(array2, value);
}
There is a slight issue with your problem. If you are going to use recursion then each array element needs to have a subsey of elements otherwise whay do you passed to the recursive method? If this is not the casr and the case is as you stated then solving this problem with recursion isnot appropriate. Also you are missing the value comparison.
See the MSDN Array class. This looks like it is c#. Maybe try the Array.Find<T> method.
Update:
For Java, I'd recommend looking at Arrays (Java 2 Platform):
binarySearch
public static int binarySearch(int[]
a,
int key)
Searches the specified array of ints for the specified value using the binary search algorithm. The array must be sorted (as by the sort method above) prior to making this call. If
it is not sorted, the results are
undefined. If the array contains
multiple elements with the specified
value, there is no guarantee which one
will be found.
Parameters:
a - the array to be searched.
key - the value to be searched for.
Returns:
index of the search key, if it is contained in the list; otherwise,> (-(insertion point) - 1).
The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size(), if all elements
in the list are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found. See Also: sort(int[])
If this is homework and they want it recursive, then maybe you should:
1 look for the middle value of the array and check if it matches. If it matches, return true
2 apply the function to the first half of the array. If it returns true, return true
3 apply the function to the second half of the aray. If it returns true, return true
4 return false
No code since it is homework.
EDIT: Is the array ordered?
I was just doing the question, and checking answers for alternative ways. Maybe this might be useful when you have to match names to String arrays.
public class Recursion {
public static void main(String[] args) {
String[] array = {"Tom", "Mary"};
if(isMember(array,"John"))
System.out.print("Found!");
else
System.out.println("Not Found!");
}
public static boolean isMember(String[] array, String name)
{
int i = array.length;
if(array.length == 0)
return false;
if(array[i - 1].equals(name))
return true;
else
{
String[] array2 = new String[array.length - 1];
for(int b = 0; b< array.length -1; b++)
{
array2[b] = array[b];
}
return isMember(array2, name);
}
}
}
Related
I need to write a code to returns true if the first argument contains a number greater than the second argument; returns false otherwise. Given that a list of integers(first argument) is compared to an integer(second argument). I must use Iterator to implement this function.
This is the code I have so far:
public class ListHasGreater {
public static boolean hasGreater(List<Integer> numbers, int number) {
// write your code here
Iterator<Integer> selectedNum = numbers.iterator();
if (selectedNum.hasNext()){
int result = selectedNum.next();
while (result > number){
return true;
}
return false;
}
}
}
And I got this error error: class, interface, or enum expected
I'm not sure if my code is logically correct and don't know how to solve this error.
You are returning from a conditional, you should also add a return statement at the end of loop.
Instead of
while (result > number){return true;} it should be if(result > number) return true
The explicit use of iterators is quite an old way of programing, instead you can use a foreach loop and let Java convert this into iterators at compilation.
public static boolean hasGreater(List<Integer> numbers, int number) {
for (int numInList : numbers) {
if (numInList > number) {
return true;
}
}
return false;
}
How can I create a method that would check whether or not a linked list contains any number larger than a parameter?
Let's say we have the linked list
[ 8 7 1 3 ]. This would return true and
[ 10 12 3 2] would return false.
Would this work?
public boolean f(int k) {
for (int=0; int<linkedList.size(); i++) {
if (linkedList.get(i)>k)
return false;
}
else
return true;
}
Also, I need to mention, this method would not change the list in any way and it should still work if the list contains null elements.
Thanks!
With Java 8
public boolean f(int k) {
return !linkedList.stream().anyMatch(i-> i> k );
}
clarification: I assume that you want to return false from the method in the case that even a single element is higher then the given k. Hence I use anyMatch since we only need to look for one element that is higher. There is no need to loop over the whole list.
No this will not work how you have it currently. You need to loop through the whole list before returning. The only time you should return prematurely is if you find a reason to return false in this context. So move your return true outside of your loop and then you'd be fine.
Also, try to give meaning to your method and class definitions. Saying obj.f(12) doesn't really say much, whereas obj.noElementGreaterThan(12) says a lot more.
for example:
public boolean noElementGreaterThan( int k ) {
for( int i = 0; i < linkedList.size(); i++ )
{
if( linkedList.get(i) > k )
return false;
}
return true;
}
The reason this works is because it will loop through the entire list of objects, comparing each to the value passed in (k). If the value is greater than k, then it will return false, meaning in this case that it does have an element greater than k.
using streams you could do like this:
public boolean f(int k) {
List<Integer> filtered = linkedList.stream().filter(i -> i > k).collect(Collectors.toList());
return !filtered.isEmpty();
}
I'm new to Java and still trying to wrap my head around recursion.The function below returns true at the very first intersection between the two sorted lists list x and list y.
public static boolean checkIntersection(List<Integer> x, List<Integer> y) {
int i = 0;
int j = 0;
while (i < x.size() && j < y.size()) {
if (x.get(i).equals(y.get(j))) {
return true;
} else if (x.get(i) < y.get(j)) {
i++;
} else {
j++;
}
}
return false;
}
Now I've been trying to implement it using recursion instead, and I know that there should be a base case which is an empty list in this case and then try to reduce the list by excluding one element at a time and feed it back to the same recursive function, but I can't work out how to check for intersection as I pass the rest of the list over and over.
public static boolean recursiveChecking(List<Integer> x,List<Integer> y) {
if(x.size() == 0){
return false;
}
else {
return recursiveChecking(x.subList(1, x.size()-1), y);
}
}
Any help would be highly appreciated. Thank you.
General approach to making something recursive is to think of two things:
When can I produce an answer trivially? - An answer to this question lets you code the base case. In your situation, you can produce the answer trivially when at least one of two lists is empty (the result would be false) or the initial elements of both non-empty lists are the same (the result would be true)
How do I reduce the problem when the answer is non-trivial? - An answer to this question lets you decide how to make your recursive call. In your case you could, for example, remove the initial element of one of the lists before making the recursive call*, or pass ListIterator<Integer> in place of List<Integer> for a non-destructive solution.
*Of course in this case you need to take care of either adding your numbers back after the call, or make a copy of two lists before starting the recursive chain.
As the lists are ordered, your recursion should remove the first element of the list with the smaller first value. Then you have to return true, if both lists start with the same number and false if any of the lists is empty. Otherwise you keep removing elements. This would look something like this (This code is untested):
public static boolean recursiveChecking(List<Integer> x,List<Integer> y) {
if(x.size() == 0 || y.size() == 0){
return false;
} else if (x.get(0).equals(y.get(0))) {
return true;
} else {
if (x.get(0) < y.get(0)) {
return recursiveChecking(x.subList(1, x.size()-1), y);
} else {
return recursiveChecking(x, y.subList(1, y.size()-1));
}
}
}
We have a Final exam that is coming up, it is proctored this is just a study question, but I am having issues with two arrays I wrote out when I put them into eclipse. I would like some insight that may help me on the test, thanks.
Write a Java function that accepts two one-dimensional arrays of integers and returns true if and only if all the integers in the first array are contained in the second, and all the integers in the second array are contained in the first
public class Two1dimensionalArraysMain
{
public boolean main(int []array1, int []array2)
{
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
if(array1[i]==array2[j])
{
break;
}
else if (array1[i] != array2[j])
return false;
}
return true;
}
}
}
The problem is that you're returning false too early.
Here's what it looks like you're trying to do. You look at each element X in array1. Then you compare that one element to each element in array2. If X equals any element in array2, you're good (so far) and you can look at the next element in array1. But if X is different from every element in array2, then return false.
That's a good approach. The problem is that you return false if X is different from any element in array2, not if it's different from every element. This is because as soon as you see two elements that are different between the two arrays, you return false right away.
public boolean main(int []array1, int []array2)
{
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
if(array1[i]==array2[j])
{
break;
}
else if (array1[i] != array2[j])
return false;
}
return true;
}
}
To fix this: You need to do the return false check outside the for (int j... loop. There are a number of ways to do this, but my favorite is this:
Declare a boolean variable found. You will initialize this to false before going through array2.
Before you break, set found = true;, to indicate that the element X in array1 was found in array2.
After you're done going through array2, check found. If it's false, then you know the whole function should return false.
Also, your return true is in the wrong place. If you fix those two things, your method should work.
EDIT: I missed that the equality has to be two ways. The above, with my suggestions, will return true if every element in array1 is in array2, but not vice versa. One simple update would be to write a helper method allElementsAreIn that uses two int[] arrays, and then call it twice, something like allElementsAreIn(array1,array2) && allElementsAreIn(array2,array1).
By the way, don't call your function main. That name should be used only for the main program, which must be void and take a String[] parameter.
P.S. I'm assuming that the purpose of the exercise is to learn the basics of loops and such. In an actual production environment, it would be much simpler to use a Set as in amit's answer.
Best solution in my opinion is to use set equality, if that's allowed.
public static boolean checkArraysContainSameElements(int[] array1, int[] array2) {
Set<Integer> set1 = new HashSet<Integer>();
for (int x : array1) set1.add(x);
Set<Integer> set2 = new HashSet<Integer>();
for (int x : array2) set2.add(x);
return set1.equals(set2);
}
Other than that, I refer to #ajb to see what's wrong with the solution you proposed.
You can sort the array and compare in the loop:
public boolean checkArrayEquality(int[] source, int[] target)
{
Arrays.sort(source);
Arrays.sort(target);
if(source.length == target.length)
{
for (int i = 0; i < target.length; i++)
{
if(source[i] != target[i])
{
return false;
}
}
}
else
{
return false;
}
return true;
}
I will explain the title better for starters. My problem is very similar to the common: find all permutations of an integer array problem.
I am trying to find, given a list of integers and a target number, if it is possible to select any combination of the numbers from the list, so that their sum matches the target.
It must be done using functional programming practices, so that means all loops and mutations are out, clever recursion only. Full disclosure: this is a homework assignment, and the method header is set as is by the professor. This is what I've got:
public static Integer sum(final List<Integer> values) {
if(values.isEmpty() || values == null) {
return 0;
}
else {
return values.get(0) + sum(values.subList(1, values.size()));
}
}
public static boolean groupExists(final List<Integer> numbers, final int target) {
if(numbers == null || numbers.isEmpty()) {
return false;
}
if(numbers.contains(target)) {
return true;
}
if(sum(numbers) == target) {
return true;
}
else {
groupExists(numbers.subList(1, numbers.size()), target);
return false;
}
}
The sum method is tested and working, the groupExists method is the one I'm working on. I think it's pretty close, if given a list[1,2,3,4], it will return true for targets such as 3 and 10, but false for 6, which confuses me because 1,2,3 are right in order and add to 6. Clearly something is missing. Also, The main problem I am looking at is that it is not testing all possible combinations, for example, the first and last numbers are not being added together as a possibility.
UPDATE:
After working for a bit based on Simon's answer, this is what I'm looking at:
public static boolean groupExists(final List<Integer> numbers, final int target) {
if(numbers == null || numbers.isEmpty()) {
return false;
}
if(numbers.isEmpty()) {
return false;
}
if(numbers.contains(target)) {
return true;
}
if(sum(numbers.subList(1, numbers.size())) == (target - numbers.get(0))) {
return true; }
else {
return groupExists(numbers.subList(1, numbers.size()), target);
}
}
For convenience, declare
static Integer head(final List<Integer> is) {
return is == null || is.isEmpty()? null : is.get(0);
}
static List<Integer> tail(final List<Integer> is) {
return is.size() < 2? null : is.subList(1, is.size());
}
Then your function is this:
static boolean groupExists(final List<Integer> is, final int target) {
return target == 0 || target > 0 && head(is) != null &&
(groupExists(tail(is), target) || groupExists(tail(is), target-head(is)));
}
There are no surprises, really, regular checking of base cases plus the final line, where the left and right operands search for a "group" that does or does not, respectively, include the head.
The way I have written it makes it obvious at first sight that these are all pure functions, but, since this is Java and not an FP language, this way of writing it is quite suboptimal. It would be better to cache any function calls that occur more than once into final local vars. That would still be by the book, of course.
Suppose you have n numbers a[0], a[1], ..., a[n-1], and you want to find out if some subset sums to N.
Suppose you have such a subset. Now, either a[0] is included, or it isn't. If it's included, then there must exist a subset of a[1], ..., a[n] which sums to N - a[0]. If it isn't, then there exists a subset of a[1], ..., a[n] which sums to N.
This leads you to a recursive solution.
Checking all combinations is factorial (there's a bit missing on your implementation).
Why not try a different (dynamic) approach: see the Hitchhikers Guide to Programming Contests, page 1 (Subset Sum).
Your main method will be something like:
boolean canSum(numbers, target) {
return computeVector(numbers)[target]
}
computeVector return the vector with all numbers that can be summed with the set of numbers.
The method computeVector is a bit trickier to do recursively, but you can do something like:
boolean[] computeVector(numbers, vector) {
if numbers is empty:
return vector
addNumber(numbers[0], vector)
return computeVector(tail(numbers), vector);
}
addNumber will take vector and 'fill it' with the new 'doable' numbers (see hitchhikers for an explanation). addNumber can also be a bit tricky, and I'll leave it for you. Basically you need to write the following loop in recrusive way:
for(j=M; j>=a[i]; j--)
m[j] |= m[j-a[i]];
The lists of all possible combinations can be reached by asking a very simple decision at each recursion. Does this combination contain the head of my list? Either it does or it doesn't, so there are 2 paths at each stage. If either path leads to a solution then we want to return true.
boolean combination(targetList, sourceList, target)
{
if ( sourceList.isEmpty() ) {
return sum(targetList) == target;
} else {
head = sourceList.pop();
without = combination(targetList, sourceList, target); // without head
targetList.push(head);
with = combination(targetList, sourceList, target); // with head
return with || without;
}
}