Hey guys im new to java and i came across this thing
Ok so here i got something i just cant comprehend
here i have this class:
class FailSoftArray {
private int a[]; // reference to array
private int errval;
public int length;
public FailSoftArray(int size, int errv) {
a = new int[size];
errval = errv;
length = size;
}
public int get(int index) {
if(indexOK(index)) return a[index];
return errval;
}
public boolean put(int index, int val) {
if(indexOK(index)) {
a[index] = val;
return true;
}
return false;
}
private boolean indexOK(int index) {
if(index >= 0 & index < length) return true;
return false;
}
}
What does indexOK(index) mean? What does it do?
This is a method to determine if the index its going to get in the array is valid.
Normally, if a value less than zero or greater than or equal to the length of the array was used as an index, it would cause an error, throwing an IndexOutOfBoundsException, since an array is indexed from 0 to length - 1.
The method avoids that possible outcome by ensuring the index will always be valid before using it, and it does this by comparing the index to see if it's >= 0, then comparing < length, then the & makes sure both are true (if both conditions are true, it can be used as an index to the array without throwing an exception.)
When you call indexOK, your program runs the following method, with an index as an argument:
private boolean indexOK(int index) {
if(index >= 0 & index < length) return true;
return false;
}
}
indexOK returns a boolean value, so the result is either true or false. When is the result true?
if(index >= 0 & index < length) return true;
return false;
If the argument is larger than or equal to zero AND the argument is less than length, the result is true. Otherwise, the result is false.
The purpose of indexOK is to check whether or not a value is an appropriate index for an array. A negative index is invalid, as is an index which equals or exceeds the length of the array it references. So the check
index >= 0
determines whether or not the index is negative, and the check
index < length
determines whether or not the index equals or exceeds the length of the array it references.
Let me rewrite the method in a way that is more understandable:
private boolean indexOK(int index) {
if(index >= 0 & index < length) {
return true;
}
return false;
}
The method will return true, when the value of index is atleast 0 and smaller than length at the same time. You can use an if-statement without its curly brackets, but it will only use the following line as the 'inner block'. This is a rather bad practice, since it's a little unclear. Furthermore, it can be easily the cause of unwanted bugs and errors, since adding lines to the 'inner block' without adding curly brackets around them isn't that uncommon. In my humble opinion, 1 line (or 2 brackets) more of code isn't that much and one should always add them.
Related
I am trying to solve a question in which I am given a String array of words and I have to check whether they have all same length or not. For instance if am given the array {"apple","purple","lemon"} then my method should return true, and when I am given the array {"red","blue"}, it should return false.
This is what I did so far but it is not working. I appreciate any help.
public static boolean allEqualLength(String[] myArray){
int i;
for(i=0;i<myArray.length;i++){
if(myArray[i]!=myArray[i+1])
return false;
}
return true,
}
All items having the same length is equivalent to saying all items must have the same length as the first item:
public static boolean allEqualLength(String[] myArray) {
// zero items => "all" items have same length:
if (myArray.length == 0) return true;
final int expectedLength = myArray[0].length();
for(int i = 0; i < myArray.length; ++i) {
if(myArray[i].length() != expectedLength)
return false;
}
return true,
}
But your original solution was not that far off. You just need to make sure not to exceed the array's bounds and to compare the string lengths, not the strings themselves:
public static boolean allEqualLength(String[] myArray) {
for(int i=0; i < myArray.length - 1; i++) { // -1 to not exceed bounds
if(myArray[i].length() != myArray[i+1].length()) // compare length, not memory addresses
return false;
}
return true,
}
I world do something like that:
public static boolean allEqualLength(String[] myArray) {
int strLength = myArray[0].length();
for (String str :
myArray) {
if (str.length() != strLength)
return false;
}
return true;
}
Like that you can avoid any indexing problems in your loop.
You are trying to compare the strings themselves. You should compare the length only.
myArray[i].length() != myArray[i + 1].length()
By the way, this will throw an ArrayIndexOutOfBoundsException, because you are trying to access index myArray[myArray.length]. Change the for loop to
for (int i = 0; i < myArray.length - 1; i++) {
if (myArray[i].length() != myArray[i + 1].length()) {
return false;
}
}
Also make sure you return true if the array length is 0 or 1, because the loop can't handle those.
For example you have array with length 4 , you have the positions 0,1,2,3 so in your code you run with : myArray[i]!=myArray[i+1] so on the last run you check the positions :
3 and 4 and you will get ArrayIndexOutOfBoundsException , you need to change to : length-1 on the loop condition like this :
public static boolean allEqualLength(String[] myArray){
int i;
for(i=0;i<myArray.length -1;i++){
if(myArray[i].length() != myArray[i+1].length())
return false;
}
return true,
}
If you run on myArray.length ,the positions that check :
0--1
1--2
2--3
3--4 // ERROR !!! ArrayIndexOutOfBoundsException !!
If you run on myArray.length-1 ,the positions that check :
0--1
1--2
2--3 -OK !!!
So on this way if you run the array with : myArray.length-1 , you will not get ArrayIndexOutOfBoundsException .
First things first you are not checking element lengths other issue is your for loop would try to access array index out of bounds since you have i+1, last element is already being checked that way, considering that you just need for until myArray.length - 1.
Using your code it would look something like this:
public static boolean allEqualLength(String[] myArray) {
for (int i = 0; i < myArray.length - 1; i++) {
if (myArray[i].length() != myArray[i + 1].length())
return false;
}
return true;
}
If performance is not an issue and you will not use it in 1 million strings or something, in addition to all these answers, here is an one liner:
boolean allStringsEqualLength = Stream.of(array)
.map(String::length).distinct().count() == 1;
The idea is to map each string to its length. So if distinct() stream contains only one value, that means all strings had the same length.
I was solving this problem, (41 from Project Euler), where I noticed that contains method of HashSet is working differently for Long as compared to Integer (I might be wrong here, please correct me if I am).
The question is -
We shall say that an n-digit number is pandigital if it makes use of
all the digits 1 to n exactly once. For example, 2143 is a 4-digit
pandigital and is also prime.
What is the largest n-digit pandigital prime that exists?
My code for checking whether the number is Pandigital or not is -
private static boolean isPan(Long n) {
HashSet<Long> list = new HashSet<Long>();
int count = 0;
while(n != 0){
list.add(n%10);
count++;
n /= 10;
}
for(int i = 9; i>count; i--){
if(list.contains(i)) return false;
}
for(int i = 1; i<= count; i++){
if(!list.contains(i)) return false;
}
return true;
}
This code gave me an infinite loop. So, I changed my code like this -
private static boolean isPan(Long n) {
HashSet<Integer> list = new HashSet<Integer>();
int count = 0;
while(n != 0){
list.add((int) (n%10));
count++;
n /= 10;
}
for(int i = 9; i>count; i--){
if(list.contains(i)) return false;
}
for(int i = 1; i<= count; i++){
if(!list.contains(i)) return false;
}
return true;
}
I just changed, HashSet<Long> to HashSet<Integer> and list.add(n%10) to list.add((int) n%10).
This gave me the correct answer, 7652413. So, can anyone explain why the contains method works differently for Long when compared to Integer?
contains(Object o) method doesn't work different for Long vs Integer. It works exactly the same, i.e.
Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).
Notice however that method accepts Object as parameter type, not E. That means you can call it with any type of object. Of course, any object type other than E would cause it to return false, since equals() would fail for objects of different types (with some exceptions).
So, when you call contains(x), and x is a primitive, it will be auto-boxed, based on the type of x, not on the type of E. So if x is an int and E is Long, it'll always return false.
It is not contains() that suddenly works different, when you change Long to Integer. It is your code that works different, by correctly matching the type of value passed to contains() to the type of elements in the collection.
UPDATE
Your code is not very efficient:
It takes a Long as a parameter, but max n is by nature 9, and and int can store 9-digit numbers without overflow, so use of Long, and use of boxing, is unnecessary.
It allocates a new HashSet for every value being checked, and autoboxes every digit found, plus 9 times for the contains() calls.
Instead, this can be done using bit-manipulation, since as 32-bit int value can easily store 10 boolean values (flags) indicating whether a digit was present.
The code below will establish two bit-masks, found and expected, which will indicate whether a digit is found, and whether a digit was supposed to be found. Since solution should only use digits 1-n, we'll claim digit 0 is present and expected (makes logic simpler, not having to do special checks for 0).
If a digit is presented twice (or digit 0 is presented once), another expected digit will be missing, and found will not equal expected.
private static boolean isPandigital(int number) {
int found = 1, expected = 1;
for (int n = number; n != 0; n /= 10, expected = (expected << 1) | 1)
found |= 1 << (n % 10);
return (found == expected);
}
If you want your code run correctly,see your code whose list is HashSet<Long>:
for(int i = 1; i<= count; i++){
if(!list.contains(i)) return false;
}
you can change the type of variable i to long,or change if(!list.contains(i)) return false; to the if(!list.contains(Long.valueOf(i))) return false;
Because of the contains will check element in existence by the element's method equals.In above code,the variable i is auto-boxed to Integer instance,because the variable i is primitive int.
And see the Integer equals:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
but your list element's type is Long,so the line if(!list.contains(i)) return false; will return false always.
This is what I have so far, but I'm confused on how to keep track of the index. I would change the parameters of the method, but I'm not allowed.
I can only use a loop to make another array. Those are the restrictions.
public class RecursiveFinder {
static int checkedIndex = 0;
static int largest = 0;
public static int largestElement(int[] start){
int length = start.length;
if(start[length-1] > largest){
largest = start[length-1];
int[] newArray = Arrays.copyOf(start, length-1);
largestElement(newArray);
}
else{
return largest;
}
}
/**
* #param args
*/
public static void main(String[] args) {
int[] array1 = {0,3,3643,25,252,25232,3534,25,25235,2523,2426548,765836,7475,35,547,636,367,364,355,2,5,5,5,535};
System.out.println(largestElement(array1));
int[] array2 = {1,2,3,4,5,6,7,8,9};
System.out.println(largestElement(array2));
}
}
Recursive method doesn't need to keep the largest value inside.
2 parameters method
Start to call with:
largestElement(array, array.length-1)
Here is the method:
public static int largestElement(int[] start, int index) {
if (index>0) {
return Math.max(start[index], largestElement(start, index-1))
} else {
return start[0];
}
}
The 3rd line of method is the hardest one to understand. It returns one of two elements, larges of the one of current index and of remaining elements to be checked recursively.
The condition if (index>0) is similar to while-loop. The function is called as long as the index remains positive (reaches elements in the array).
1 parameter method
This one is a bit tricky, because you have to pass the smaller array than in the previous iteration.
public static int largestElement(int[] start) {
if (start.length == 1) {
return start[0];
}
int max = largestElement(Arrays.copyOfRange(start, 1, start.length));
return start[0] > max ? start[0] : max;
}
I hope you do this for the study purposes, actually noone has a need do this in Java.
Try that for the upper class, leave the main method it's is correct.
public class dammm {
public static int largestElement(int[] start){
int largest = start[0];
for(int i = 0; i<start.length; i++) {
if(start[i] > largest){
largest = start[i];
}
}return largest;
}
If your goal is to achieve this by using recursion, this is the code that you need. It is not the most efficient and it is not the best way to deal with the problem but it is probably what you need.
public static int largestElement(int[] start){
int length = start.length;
if (start.lenght == 1){
return start[0];
} else {
int x = largestElement(Arrays.copyOf(start, length-1))
if (x > start[length-1]){
return x;
} else {
return start[length-1];
}
}
}
Imagine that you have a set of numbers you just have to compare one number with the rest of them.
For example, given the set {1,8,5} we just have to check if 5 is larger than the largest of {1,8}. In the same way you have to check if 8 is larger than the largest of {1}. In the next iteration, when the set one have one value, you know that that value is the bigger of the set.
So, you go back to the previous level and check if the returned value (1) is larger than 8. The result (8) is returned to the previous level and is checked against 5. The conclusion is that 8 is the larger value
One parameter, no copying. Tricky thing is, we need to pass a smaller array to the same method. So a global variable is required.
// Number of elements checked so far.
private static int current = -1;
// returns the largest element.
// current should be -1 when user calls this method.
public static int largestElement(int[] array) {
if (array.length > 0) {
boolean resetCurrent = false;
if (current == -1) {
// Initialization
current = 0;
resetCurrent = true;
} else if (current >= array.length - 1) {
// Base case
return array[array.length - 1];
}
try {
int i = current++;
return Math.max(array[i], largestElement(array));
} finally {
if (resetCurrent) {
current = -1;
}
}
}
throw new IllegalArgumentException("Input array is empty.");
}
If you can create another method, everything would be much simpler.
private static int recursiveFindLargest(int [] array, int i) {
if (i > 0) {
return Math.max(array[i], recursiveFindLargest(array, i-1));
} else {
return array[0];
}
}
public static int largestElement(int [] array) {
// For empty array, we cannot return a value to indicate this situation,
//all integer values are possible for non-empty arrays.
if (array.length == 0) throw new IllegalArgumentException();
return recursiveFindLargest(array, array.length - 1);
}
For this problem you really need to think about working with the base case. Take a look at some of the simple cases you would have to deal with:
If the array is length 1, then you return the only value
If the array is length 2, then you return the maximum of the two values
If the array is length 3, then ?
From the above we can get an idea of the structure of the problem:
if array.length == 1 then
return array[0]
else
return the maximum of the values
In the above if we have only one element, it is the maximum value in the list. If we have two values, then we have to find the maximum of those values. From this, we can then use the idea that if we have three values, we can find the maximum of two of them, then compare the maximum with the third value. Expanding this into pseudo code, we can get something like:
if array.length == 1 then
return array[0]
else
new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
return maximum(array[0], largestElement(new array))
To explain the above a little better, think of execution like a chain (example for {1, 2, 3}).
Array: {1, 2, 3}, maximum(array[0] = 1, largestElement(new array = {2, 3}))
Array: {2, 3}, maximum(array[0] = 2, largestElement(new array = {3}))
Array: {3}, array[0] = 3 => length is 1 so return 3
The above then rolls back up the 'tree' structure where we get:
maximum (1, maximum(2, (return 3)))
Once you have the maximum value, you can use the sample principle as above to find the index with a separate method:
indexOf(array, maximum)
if array[0] == maximum then
return 0
else if array.length == 1 then
return -1
else
new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
result = indexOf(new array, maximum)
return (result == -1) ? result : result + 1
For looking into this more, I would read this from the Racket language. In essence it shows the idea of array made purely from pairs and how you can use recursion to do iteration on it.
If you are interested, Racket is a pretty good resource for understanding recursion. You can check out University of Waterloo tutorial on Racket. It can give you a brief introduction to recursion in an easy to understand way, as well as walking you through some examples to understand it better.
You don't need to keep a largest variable outside your method - that's generally not a good practice with recursion which should return all context of the results.
When you think about recursion try to think in terms of a simple base case where the answer is obvious and then, for all other cases how to break it down into a simpler case.
So in pseduo-code your algorithm should be something like:
func largest(int[] array)
if array has 1 element
return that element
else
return the larger of the first element and the result of calling largest(remaining elements)
You could use Math.max for the 'larger' calculation.
It's unfortunate that you can't change the arguments as it would be easier if you could pass the index to start at or use lists and sublists. But your copying method should work fine (assuming efficiency isn't a concern).
An alternative to the algorithm above is to make an empty array the base case. This has the advantage of coping with empty arrays (by return Integer.MIN_VALUE):
int largest(int[] array) {
return array.length == 0
? Integer.MIN_VALUE
: Math.max(array[0], largest(Arrays.copyOfRange(array, 1, array.length)));
}
Here is working example of code with one method param
public int max(int[] list) {
if (list.length == 2) return Math.max(list[0], list[1]);
int max = max(Arrays.copyOfRange(list, 1, list.length));
return list[0] < max ? max : list[0];
}
private static int maxNumber(int[] arr,int n,int max){
if(n<0){
return max;
}
max = Math.max(arr[n],max);
return maxNumber(arr,n-1,max);
}
Here is my code:
int setElement(int[]array) {
int key;
for (int i=0; i<array.length; i++) {
}
return key;
}
Something is wrong here.
As you said, your method needs to take three parameters, but your method takes just one input array. Also there is no need to loop through the array, array element can be accessed using its index for insertion, also for retrieval. Since the index is passed as parameter you can use it directly in your code.
All you need to do is
public void setValueInArray(int[] array, int index, int value){
if(array != null && index >= 0 && index < array.length){
array[index] = value;
}
}
key should be passed to the method.
The way you're doing it you'll never meet the if condition since key has a garbage value - It's only declared but never defined.
Try to pass the index and the value you are trying to change.
public void setElement(int[] array, int index, int val ) {
if(array!=null && index >-1 && index<array.length ){
array[index]=val ;
} else{
//sorry not possible
}
}
Integer myArray[]= {12,23,10,22,10};
System.out.println(Arrays.asList(myArray).indexOf(23));
use above code
I have troubles in one method. In input we have string, for example (a+-b*i)some sign(c+-d*i). Program must calculate this and output result. I need to take index of sign in the first bracket and index in the second bracket. And than my program will be working. But, when in input (a-b*i)-(c-d*i) or (a-b*i)*(c-d*i) only, method returning wrong result -1.
My methods for two brackets.
public int getSign1(String str)
{
int sign1;
if(str.indexOf("+") < str.indexOf(")"))
sign1 = str.indexOf("+");
else if(str.indexOf("-", 2) < str.indexOf(")"))
sign1 = str.indexOf("-", 2);
else sign1 = -1;
return sign1;
}
public int getSign2(String str)
{
int sign2;
if(str.lastIndexOf("+") > str.lastIndexOf("("))
sign2 = str.lastIndexOf("+");
else if(str.lastIndexOf("-") > str.lastIndexOf("("))
sign2 = str.lastIndexOf("-");
else sign2 = -1;
return sign2;
}
The second method always working, but not the first (Please help me to find error).
Example: (1-2i)*(3-4i)
The first method is returning -1, but not 2. Why?
This happens because in the expression:
(1-2i)*(3-4i) you don't have any + char, and after seeing String#lastIndexOf:
the index of the last occurrence of the character in the character
sequence represented by this object, or -1 if the character does not
occur.
Then you know why str.lastIndexOf("+") will be -1. And it's of course < str.indexOf(")").
So sign1 will be -1.
You can fix it by:
if(str.indexOf("+")!= -1 && str.indexOf("+") < str.indexOf(")"))
For input (a-b*i)-(c-d*i) , here there is no '+' in this string.
public int getSign1(String str){
if(str.indexOf("+") < str.indexOf(")"))
sign1 = str.indexOf("+");
..
}
In this method first if you are checking '+' , hence it is not there its index is -1 which is less than str.indexOf(")") index so its returing -1.