I am new to programming and I need some help. I am supposed to make my own method checking if one array has a subsequence to another one. Meaning if the first array is {1, 2, 3, 4, 5} and the second one is {1, 2, 3} the second one is a subsequence of the first. However if the first is {1, 2, 3, 4, 5} and the second is {1, 4, 5} it is not a subsequence, so the second has to be in order as well.
I have tried to do it this way through strings:
private static boolean subs(int[] array, int[] subsequence) {
String a = Arrays.toString(array);
String b = Arrays.toString(subsequence);
boolean c = false;
if (a.equals(b)) {
return true;
}
for (int i = 0; i < a.length(); i++) {
if (!(b.equals(a.substring(i, b.length() + i)))) {
c = false;
} else {
c = true;
break;
}
}
if (c == true) {
return true;
} else {
return false;
}
}
However I get 3 errors, here is the printscreen :
And here is how I am testing the method:
int[] fArray = { 1, 2, 3, 4, 5 };
int[] tempArray = { 2, 3, 4 };
System.out.println(subs(fArray, tempArray));
I know I probably made a lot of mistakes, so hit me with it.
Here:
for (int i = 0; i < a.length(); i++) {
if (!(b.equals(a.substring(i, b.length() + i)))) {
Your outer loop condition makes sure that i stays smaller than a.length().
But then you try to take a substring within a that goes for b.length()+i!
In other words: for any b.length() > 0 ... that code will always try to fetch characters beyond the end of a.
And there is also a bug in your result handling - it seems very much possible that you assign
c = true;
at some point; to later overwrite that with
c = false;
In other words: your code forgets that he found a match! The much easier solution: when hitting the true case, just return true there! And if you don't return within the loop; you just return false in the end.
Finally: although it seems like a cool idea to turn your arrays into strings ... that doesn't really buy you anything. You are still doing the work of going through the first array and checking if the second is in there. Writing code that does that directly on the provided arrays ... would not be much different from what you got there with your "string detour".
Edit: when using multiple returns in a method, you simply have to make sure that any possible path has a return statement. In your case:
boolean subs(... {
if equal strings
return true
for i as index in a
if a.substring equals b
return true
return false
The issue is that fArray as String has more chars than tempArray as string, so when you start to compare char by char from a to b, is a given point where the index is going beyond the size of b and then you get the exception
Your problem line is: if (!(b.equals(a.substring(i, b.length() + i))))
Why?
Lets assume your a.length() is equals 6 and b.length() is equals 2 now your looping for (int i = 0; i < a.length(); i++) with i going from 0 to 5.
Now lets say your loop executed 3 times and i is equals 4now.
Now when you call a.substring(4, b.length() + 4) with b.length() == 2 => a.substring(4, 6) but your string only goes from 0 to 5
The simplest way to do this would be to use Collections.indexOfSubList:
private static boolean subs(int[] array, int[] subsequence) {
return Collections.indexOfSubList(toList(array), toList(subsequence)) >= 0;
}
private static List<Integer> toList(int[] array) {
List<Integer> list = new ArrayList<>(array.length);
for (int num : array) {
list.add(num);
}
return list;
}
//*******************************************************************
// NOTE: please read the 'More Info' tab to the right for shortcuts.
//*******************************************************************
import java.lang.Math; // headers MUST be above the first class
import java.util.Arrays;
// one class needs to have a main() method
public class HelloWorld
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
int[] fArray = { 1,2,3,4,5 };
int[] tempArray = { 2,3,4 };
System.out.println(subs(fArray, tempArray));
}
private static boolean subs(int[] array, int[] subsequence) {
String a = Arrays.toString(array);
String b = Arrays.toString(subsequence);
boolean c = false;
if (a.equals(b)) {
return true;
}
String ss = b.substring(1,b.length()-1);
for (int i = 0; i < 8; i++) {
String substr =a.substring(i, ss.length()+i);
if (!(ss.equals( substr ))) {
System.out.println("heelllo");
c = false;
} else {
c = true;
break;
}
}
if (c == true) {
return true;
} else {
return false;
}
}
}
Related
i have a problem with an exam test.
I have two arrays: int[] a, int[] b, with random values.
E1 return true if there are two elements of b greater then each element of a.
How do I write "there are two elements of b greater than each element of a"?
I can write "there is ONE elements of b greater than each element of a" in this way:
public static boolean e1(int[] a, int[] b){
boolean ris = false;
boolean ogniA = true;
int i = 0;
if(a != null && a.length != 0){
while(ogniA && i<a.length){
boolean es1= false;
boolean es2 = false;
int j = 0;
if(b!= null && b.length != 0){
while(!es1 && j < b.length){
if(j%2!=0){
es1 = a[i] < b[j];
}
j++;
}ris = es1 ;
}
i++;
}
}
return ris;
I need something like this. Thanks for help.
So I would solve this problem, by dividing it into smaller problems.
1st you need to find the 2 biggest values in the first array.
I presume this should be abstract and work for every array
Code (using the example from Andronicus):
"E1 return true if there are two elements of b greater then each element of a"
Basically you need the second greater value of array B and the greater value of the array A
int[] a = {3, 5, 7, 9};
int[] b = {2, 4, 3, 10, 11};
int secondGreatestOfB = IntStream.of(b).boxed()
.sorted(Comparator.reverseOrder())
.limit(2)
.sorted(Comparator.naturalOrder())
.limit(1)
.findFirst().orElse(0);
System.out.println(areTheTwoBiggestNumbersOfArrayBbiggerThanAllValuesFromArrayA(a, secondGreatestOfB));
private static boolean areTheTwoBiggestNumbersOfArrayBbiggerThanAllValuesFromArrayA(int[] a, int secondGreatestOfArrayB) {
return secondGreatestOfArrayB > IntStream.of(a).max().orElse(0);
}
I'm having trouble executing this function in which it would print out "true" if there is 2 consecutive numbers in an array and "false"if not. The errors I get is that a boolean cannot be converted to an int and also in the last line of code what would I have to put inside the brackets for System.out.println()?
public class A1Q2 {
private static int hasTwoLengthRun(int[] array) {
for(int i=0; i < array.length; i++){
if(array[i+1] == array[i]){
return true;
}
else{
return false;
}
}
}
public static void main(String[] args) {
int[] array = new int[]{5, 16, 7, 35, -2, -9, 75};
System.out.println();
}
}
1)hasTwoLengthRun() should return a boolean and not an int as you return boolean values.
2) it has a broken logic as it returns false as soon as two elements of the array are not equals between.
You should return false only when you have iterated over all elements.
3) For the compiler the method doesn't return a value since you return a value only in the for. If you have a array with no element, you don't enter in the for and you return nothing. It is not legal.
4) you will get an ArrayIndexOutOfBoundsException with the for condition as the last iteration use a index out of the array.
Here is a code that should work :
private static boolean hasTwoLengthRun(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
if (array[i + 1] == array[i]) {
return true;
}
}
return false;
}
I see at least 3 problems here:
Return type of hasTwoLengthRun function should be boolean
You've incorrectly arranged return false statement - it should be invocated in the end of the method
You've incorrectly used array boundaries - you'll get exception trying to reach element out of array.
Here is the corrected code:
public class Test {
private static boolean hasTwoLengthRun(int[] array) {
for(int i=0; i < array.length - 1; i++){
if(array[i+1] == array[i]){
return true;
}
}
return false;
}
public static void main(String[] args) {
int[] array = new int[]{5, 16, 7, 35, -2, -9, 75};
System.out.println(hasTwoLengthRun(array));
}
}
You get an error, because you've written that your hasTwoLengthRun function returns int, while in your return statements you return true or false - a boolean-typed values.
Here:
private static int hasTwoLengthRun(...
says the method shall return an int. A number.
Then you return true/false. In java, those two types can not be interchanged.
So, change to:
private static boolean hasTwoLengthRun(...
Besides; your logic is wrong:
for(int i=0; i < array.length-1; i++){
if(array[i+1] == array[i]) {
return true;
}
}
return false;
is what you need instead; to A) avoid running over the length of your array and B) not returning with false when the first two elements are not matching your condition!
I'm trying to check wvhether my 2D array is symmetric or not. I wrote a method to check if array is symmetric. It always returns true, even if I change elements in the input array. What am I doing wrong?
Here is my code:
public class learnigBoolean
{
public static void main(String[] args)
{
int[][] array = {
{ 1, 1, 4, -1},
{ 1, 5, 0, -1},
{ 4, 0, 1, -4},
{-1, -1, 4, 10}
};
System.out.println(symetrisk(array));
}
public static boolean symetrisk(int[][] f)
{
for (int out = 0; out < f.length; out++) {
for (int in = 0; in < f[out].length; in++) {
if (f.length == f[out].length && f[out][in] == f[out][in]) {
return true;
}
}
}
return false;
}
}
if(f.length==f[out].length && f[out][in]==f[out][in])
The first check ensure your matrix is squared, the second does nothing! You are comparing each element to itself.
Don't you mean :
if(f.length==f[out].length && f[out][in]==f[in][out])
But your return statement is problematic, as stated by Michael Faisst.
You need something like this :
for (int out = 0; out < f.length; out++) {
for (int in = 0; in < f[out].length; in++) {
if (f.length != f[out].length || f[out][in] != f[in][out])) {
return false;
}
}
}
return true;
By inverting the check, you ensure that every element is checked before you return true.
Think of it this way : you only need to find one elements that doesn't satisfy the condition to say your array is not symmetric. However, you need to check every elements before you can say your array is symmetric.
You were doing the opposite, saying the array is symetric after only one check.
f[out][in] == f[out][in]
Will always return true.
Also calling "return true" will exit the loop after the first positive match which is:
f[0][0] == f[0][0]
also always true.
If you want to make it more efficient you might want to initialize your second loop to "out" to prevent checking the same pair twice, skip checking numbers against themselves and exit the loop as soon as you find a non-match like so:
public static boolean symetrisk(int[][] f)
{
for (int out = 0; out < f.length; out++) {
if (f.length == f[out].length) //only need to check this once per row.
{
for (int in = out + 1; in < f[out].length; in++)
{
if (f[out][in] != f[in][out])
{
return false; //once we find a non-matching value we stop checking
}
}
}
else
{
return false; //non-square array.
}
}
return true;
}
I need to write a method that takes an array of integers and checks for every element if all its divisors (except the number itself and 1) are present in this array. If yes, the method will return true.
For example, the following array will return true:
4,5,10,2
I can't think of something efficient enough to be implemented. Could you guys help me out here?
I've been thinking to iterate through every element in the array, search for all of its divisors, put them on array, return the array and then compare to the elements in the original array.
This is a possible solution and it could work but I want to know of other possible solutions.
EDIT: Here is a code I've came up with but it is super slow. Could you guys help me optimise it a little bit?:
import java.util.Arrays;
public class Divisors {
public static void main(String[] args) {
int[] numbers = { 4, 5, 10, 2 };
boolean flag = true;
for (int num : numbers) {
if (num % 2 != 0) {
for (int subNum = 1; subNum < num / 2; num += 2) {
if(num%subNum == 0 && subNum != 1) {
if(!Arrays.asList(numbers).contains(subNum)) {
flag = false;
}
}
}
} else {
for (int subNum = 1; subNum < num / 2; num++) {
if(num%subNum == 0 && subNum != 1) {
if(!Arrays.asList(numbers).contains(subNum)) {
flag = false;
}
}
}
}
}
System.out.println("Result is: "+flag);
}
}
I think the following alogorithm solves your need. I have tested it on a few cases and it seems to work.
For example the array:
int[] set = {2, 3, 4, 5, 7, 10, 11, 15, 18, 35};
executes instantly giving the answer "true". Try removing the 7 which will give the answer "false".
You call it thus:
reduce(set, 0, 0)
The principle used is to iterative recursively through the array, reducing the array through factorization of the array by each element. If you find an element which is smaller than the last factor, it means it can't be factored. This only works if the array is sorted. Once you reach the end of the array, you know all elements have been factored.
private static boolean reduce (int[] set, int index, int factor) {
// NOTE: set must be a sorted set of integers
if (index == set.length) {
return true;
} else {
int divisor = set[index];
if (divisor != 1) {
if (divisor < factor) return false;
for (int i = index; i < set.length; i++) {
while ((set[i]%divisor) == 0) {
set[i] = set[i]/divisor;
}
}
return reduce(set, index+1, divisor);
} else {
return reduce(set, index+1, factor);
}
}
}
See if it works, let me know if you run into any problems.
1.Iterate through every element in the array
2. Find in for loop its divisor
3. While doing 2), check for every divisor if it is contained in the array. If false - return false.
I am trying for too long to figure out this exersies but I am stuck here. I need to write a boolean method that will an array as argument and should return true if numbers in array are in decreasing order. Bu any time that I am trying I am having the same value or errors. Here is my code:
public class Question1c{
public static void main (String[] args){
int[] arr = {1, 9, 3, 4, 5, 6};
boolean product = isDecreasing(arr);
System.out.println(product);
}
public static boolean isDecreasing (int[] numbers){
int first = numbers[0];
for (int i : numbers){
if(first <= i){
first = i;
return true;
}
//else{
// return false;
//}
}return false;
}
}
The problem in your code is that you cannot return true until after you went through the entire array. However, you can return false as soon as you detect an "inversion" - i.e. a situation when the number that follows the one you've seen before is greater than the prior number.
You are reasonably close to a working solution - you need to remove return true, uncomment the else, and change the final return false to return true.
To make your code more readable, rename first to prior. Also consider changing the "foreach" version of the for loop to a regular for loop that skips the initial element of the array. This would let you detect decreasing order, as opposed to non-increasing, which you currently detect.
Not sure I understand, but wouldn't this solve your issue?
public class Question1c{
public static void main (String[] args){
int[] arr = {1, 9, 3, 4, 5, 6};
boolean product = isDecreasing(arr);
System.out.println(product);
}
public static boolean isDecreasing (int[] numbers){
for (int i = 0; i < numbers.Length; i++){
if (i == 0)
continue;
if (numbers[i - 1] >= numbers[i])
return false;
}
return true;
}
}
You're essentially just aiming to check that the previous item in the array isn't greater than or equal to the current item in the array, aren't you?
You initialize first with numbers[0] this causes several problems:
An empty array throws IndexOutOfBoundsException
the first check automatically passes (numbers[0] <= numbers[0])
you best check the length of numbers for 0 and use a "normal" for loop (using an index).
Your return values is also the negation of what it should be.
This might solve your issue.
public class Question{
public static void main (String[] args){
int[] arr = {1, 9, 3, 4, 5, 6};
boolean product = isDecreasing(arr);
System.out.println(product);
}
public static boolean isDecreasing (int[] numbers){
int first = numbers[0];
for (int i = 1; i < numbers.length ; i++) {
if (first <= numbers[i]) {
return false;
}
first = numbers[i];
}
return true;
}
}