I'm writing a method in a class that retrieves an array and a set value from main. The aim is to locate the position of that given value and return this to main (if the value does not exist in the array it returns -1).
To my problem: when i run my code Java says: int cannot be converted to boolean. And points me to the if-statement in the code below. I tried switching the "="-sign to a ">=", and then it runs smoothly (but then it doesn't work like it's supposed to...).
Can anyone see why it thinks i want to convert it to a boolean?
public static int containsIntElement(int[] A, int val)
{
int pos = -1;
for (int i = 0; i < 10; i++)
{
if(A[i] = val)
{
pos = i;
}
}
return pos;
}
The correct way to evaluate two ints is ==, not =:
public static int containsIntElement(int[] A, int val)
{
int pos = -1;
for (int i = 0; i < 10; i++)
{
if(A[i] == val) //Note this
{
pos = i;
}
}
return pos;
}
The = operator is for assignments, so in
if(A[i] = val)
You're assigning the value val to the variable A[i], that is not a condition
Please pay attention to minor details
if(A[i] = val) // is incorrect .. in some programming language it is correct. but boy o boy it would make you cry.
if(A[i] == val) // is correct.
You use = (the assignment operator) where you intended to use == (the comparison operator).
What your if does is:
Assign val to A[i] then try (and fail) to make a logical value from A[i]
(naming conventions also say A should be lowercase)
Related
public int lookFor(String s) {
final int EXIST = 1;
final int NOT_EXIST = -1;
int thisIndex = 0;
int otherIndex = 0;
char thisNext;
char otherNext;
if (s == null || s.length() == 0)
return NOT_EXIST;
for(; thisIndex < this.mainString.length() ; ) {
thisNext = this.mainString.charAt(thisIndex);
otherNext = s.charAt(otherIndex);
if (thisNext == otherNext) {
thisIndex++;
otherIndex++;
}
else if (thisNext != otherNext)
thisIndex++;
if (otherIndex == s.length()-1)
return EXIST;
}
return NOT_EXIST;
}
This is my attempt so far.
mainString = the main string I want to find the substring in.
s = the substring.
So my idea was to get the first chars of both strings, see if they equal. if they don't, i'll get the second char of mainString, see if they equal (mainString second char to s first char). If they're not equal, i'll get the third char of mainString and so forth. Once they're equal, i'll get the next char of both strings and see if they both equal.
Basically the loops knows that mainString contains s when index of s equals to s length minus one (that means the loop looped all the way to the last char inc, of s, so s index == s length -1).
Is the logic I'm trying to work with incorrect? or I just executed it not good? i'll happy to get answers!
Here's my naïve approach:
private final int EXIST = 1;
private final int NOT_EXIST = -1;
private int lookFor(String a, String b, int index) {
for (int i = 0; i < b.length(); i++) {
if ((index + i) >= a.length()) return NOT_EXIST;
if (a.charAt(index + i) != b.charAt(i)) return NOT_EXIST;
}
return EXIST;
}
public int lookFor(String a, String b) {
char start = b.charAt(0);
for (int i=0; i < a.length(); i++) {
if (a.charAt(i) == start) {
if (lookFor(a, b, i) == EXIST) return EXIST;
}
}
return NOT_EXIST;
}
Though, I'm not sure why you would do this when you could just do:
int ret = a.contains(b) ? EXIST : NOT_EXIST
However I wanted to actually answer your question.
Here's a slightly improved version that satisfies your "all in one method" requirement.
public static int lookFor(String a, String b) {
// Fancy way of preventing errors when one of the strings is empty
boolean az = a.length() == 0;
boolean bz = b.length() == 0;
if (az ^ bz) return NOT_EXIST;
// Need this next line if you want to interpret two empty strings as containing eachother
if (az && bz) return EXIST;
char start = b.charAt(0);
// This is known as a "label". Some say it's bad practice.
outer:
for (int i=0; i < a.length(); i++) {
if (a.charAt(i) == start) {
// Instead of using two methods, we can condense it like so
for (int q = 0; q < b.length(); q++) {
if ((i + q) >= a.length()) continue outer;
if (a.charAt(i + q) != b.charAt(q)) continue outer;
}
return EXIST;
}
}
return NOT_EXIST;
}
To find a substring "by hand", you need a nested loop; i.e. a loop inside a loop.
The outer loop tries all of the possible start positions for the substring in the string.
For a given start position, the inner loop tests all of the characters of the string that you are looking for against the string you are searching in.
In the naive substring search algorithm, the outer loop steps starts at index zero, and increments the index by one until it gets to the end of the string being searched. This can be improved on:
Every non-null string "contains" the empty string. It may be worth treating this as a special case.
It is easy to see that the outer loop can usually stop before the final. If you are searching for a string of length (say) 3, then the outer loop can stop at 3 from the end. (Think about it ....)
There are some clever algorithms which allow the outer loop to skip over some indexes. If you are interested, start by Googling for "Boyer-Moore string search".
(Note: the looping could be replaced with / written using recursion, but it is still there.)
Your code doesn't have a nested loops. By my reading, it is only going to find a match if the string you are searching for is at the start of the string you are searching. That is not correct.
I'm trying to retrieve the item at the specified index in an array as shown in the body of the forloop.
public int arrayCount9(int[] nums) {
int count = 0;
for (int i = 0; i < nums.length; i ++) {
if (Array.get(nums, i) == 9) {
count ++;
}
}
return count;
}
However, the correct code in this problem is actually this:
public int arrayCount9(int[] nums) {
int count = 0;
for (int i = 0; i < nums.length; i ++) {
if (nums[i] == 9) {
count ++;
}
}
return count;
}
Is there a difference between Array.get(nums, i) == 9) and (nums[i] == 9)? The documentation for get(Object array,int index) seems suitable for this problem. In addition, I've actually never encountered (nums[i] == 9) before so if you could explain that code as well, much appreciated!
As far as I can tell from the documentation, the most important difference between the two is that Array.get(myArray, myIndex) will return a raw Object, whereas myArray[myIndex] will return a value of the type that myArray stores.
For example, if you have an array of Strings named myStringArray, Array.get(myStringArray, 4) will give you a nondescript Object value, whereas myStringArray[4] will give you a String value.
In general, people tend to use the myArray[myIndex] syntax unless they have a compelling reason not to. It essentially means "get the item in the array named myArray at index myIndex."
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;
}
The assignment is to create a method that finds the second largest even int in an array of ints. I am restricted from using any methods from any libraries.
Here is my code that works for all cases:
public static int getSecondLargestEven(int[] ary) {
int i;
aryLength = ary.length;
int largestEven = -1;
int secondLargestEven = -1;
for (i = 0; i < aryLength; i++) {
if (ary[i] % 2 == 0) {
if (ary[i] > largestEven) {
if (largestEven != -1)
secondLargestEven = largestEven;
largestEven = ary[i];
} else {
if (ary[i] != largestEven) {
if (secondLargestEven == -1 || ary[i] >= secondLargestEven) {
secondLargestEven = ary[i];
}
}
}
}
}
Prior to calling the methodI require the array to have more than one even else no method call.
So, when secondLargestEven == -1, I know there is a duplicate.
Is there a more efficient (less use of operators, less loops used, less memory allocation) way to accomplish the objective? How can I improve the logic of my code? How can I improve my code overall?
I don't like that I have to assign the magic number -1 to secondLargestEven and largestEven because they are technically named to hold EVENS. Would it be efficient to use a loop to assign a valid even integer in the array to both secondLargestEven and largestEven and THEN proceed to search? Thanks in advance.
You can make the code cleaner by not explicitly checking for the case when the largest and second variables are equal to -1.
Just set these variables to Integer.MIN_VALUE before the loop - this is the same as assuming that there were two additional values in your array that come before all the others, and they both have the value Integer.MIN_VALUE.
public static int secondLargestEven(int[] x) {
int largest = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 0) {
if (x[i] > largest) {
second = largest;
largest = x[i];
} else if (x[i] > second) {
second = x[i];
}
}
}
return second;
}
Edit -- I thought I'd throw in that you can remove one level of nesting by using a continue statement inside the loop to skip the cases where you have an odd integer, although some people would consider this more difficult to understand than the code above.
It's a tradeoff - you use explicit control flow inside the loop (bad) but you remove a nesting level (good).
public static int secondLargestEven(int[] x) {
int largest = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 != 0)
continue;
if (x[i] > largest) {
second = largest;
largest = x[i];
} else if (x[i] > second)
second = x[i];
}
}
return second;
}
Just a fun thought... in Haskell, this function can be written in one line
import Data.List (sort)
secondLargestEven = (!! 1) . reverse . sort . filter even
or, if you want to be more efficient
import Data.List (sortBy)
import Data.Ord (comparing)
secondLargestEven = (!! 1) . sortBy (comparing negate) . filter even
This is just-for-fun implementation:
public static int secondLargestEven(int[] array) {
Set<Integer> evenSet = new TreeSet<>(Collections.reverseOrder());
for (int n : array) if (n % 2 == 0) evenSet.add(n);
return new ArrayList<>(evenSet).get(1);
}
This method is extremely inefficient (I cant look at it) but returns second largest even number :)
Method works only if array has second largest even number.
public static int findLargestMark(ArrayList<Result> array)
{
int last = 0;
int largestPOS = 0;
for (int i = 1; i <= array.size(); i++)
{
for (Result s : array)
{
int num = s.getMark();
if (num > last)
{
last = num;
largestPOS = i++;
}
}
}
Does anyone have any idea why this isn't returning the position of the largest value?
I'm sorry but I'm a bit of a newbie to Java.
largestPOS = i++;
This is incrementing i which means it skips the next number. If that next number is the biggest, you'll miss it.
Your code won't compile. You need a return statement.
Your outer loop skips the first element because it starts at 1 instead of 0. Arrays and lists are 0 based.
You only need one loop to accomplish this. I'd remove the inner loop since you're trying to return the index and a foreach loop doesn't give you the index.
If your array is empty, it will set largestPOS to 0. That is not correct. Other algorithms in this situation would return -1 to mean "index not found". See String.indexOf for example.
If you want to find the largest mark, no need to reinvent the wheel. Use Collections.max and provide a custom Comparator :
Result r = Collections.max(array, new Comparator<Result>() {
#Override
public int compare(Result o1, Result o2) {
return Integer.compare(o1.getMark(), o2.getMark());
}
});
Then if you really want to find the position of this object in the list you can use indexOf :
array.indexOf(r);
Note that will return the index of the first occurrence of the specified element in the list.
If you want to get the index of the last occurrence, you can use :
array.lastIndexOf(r);
There are several reasons to this program's failure:
You need to check that your array has at least one item
You need to start the last at the initial mark, not at zero
You need to loop from one, inclusive, to array.size(), exclusive
You do not need a nested loop
You need to add a return statement
Here is how you can fix your code:
public static int findLargestMark(ArrayList<Result> array) {
if (array.size() == 0) return -1; //
int last = array.get(0).getMark();
int largestPOS = 0;
for (int i = 1; i < array.size(); i++) {
int num = array.get(i).getMark();
if (num > last) {
last = num;
largestPOS = i;
}
}
return largestPOS;
}
Because you're iterating through the same array using two nested loops. Keep it simple. Iterate only once through the entire array and find the maximum value and its index.
Try this..
public static int findLargestMark(ArrayList<Result> array)
{
int last = array.get(0).getMark();
int largestPOS = 0;
for (int i = 1; i <= array.size(); i++)
{
Result s = array.get(i);
int num = s.getMark();
if (num > last)
{
last = num;
largestPOS = i;
}
}
return largestPOS;
}
Your code even not compile, java is 0 index based. you should have received a ArrayIndexOfBoundException. However, i would just use Collections.max(array, Comparator):
Result x = Collections.max(array, new Comparator<Result>(){
#Override
public int compare(Result o1, Result o2) {
return Integer.compare(o1.getMark(), o2.getMark());
}
});
And then the index by array.indexOf(x) function, where array is an instance of type ArrayList<Result>