While finding elements on an array when should I make an else? - java

I am using a while loop with a counter to find an element on an array. I will check that if the returned element is equal to the lenght of the array the element is not found. The loop is like this.
int i = 0;
int returned;
boolean found = false;
while(i < words.length && !found){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
found = true;
}
else{
i++;
}
return i
What I am wondering if it would be better instead of doing an else on every condition to do the following
int i = 0;
int returned;
boolean found = false;
while(i < words.length && !found){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
found = true;
}
i++;
}
if(!found)
i++;
return i-1
I feel that the second one is more efficient because it doesn't have to check the condition on every loop and in case that the array was really long it would have to be done a lot. But I'm not sure on when to decide each because the second looks realy ugly and not intuitive.

There are multiple possible refactoring that avoid the question, but I'll try to answer your question as is :
the else costs nothing : it's just a block that will be executed if and only if the if's condition evaluates to false.
it is easily understood by anyone
Even if it doesn't look the prettiest, I see no reason to avoid it. In your second code, not only do you introduce extra instructions, it is also harder to understand since you have to get why the index needs to be increased when the element isn't found.

extract the code in a method, like this
public int contains(....) {
int i = -1;
while(i < words.length){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
return i;
}
i++;
}
return i;
}
no need for additional variables and clearer structure of the code

I don't think that you need to use an else part or another if condition to check whether its found or not cause you are already checking the condition in while loop.
int i = 0;
int returned;
boolean found = false;
while(i < words.length && !found){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
found = true;
}
i++;
}
return i;
So here the loop will go on until the value of found becomes true (means that till the required element is found. Then in next iteration it will check whether the found value is false. As it's not false anymore the loop will not be executed and the i will be returned.
There you can check the value of i and decide whether the element is found or not.

Related

I need help trying to know when a user enters a duplicated number, without collections

So I am having trouble trying to find duplicates in an array where a user enters the numbers. I want to display a dialog when they enter a number that is already in the array. It sounds simple but is confused on how to go on about this.
//Convert the string into an int
num = Integer.parseInt(inputField.getText());
// Add it to the an index
array[index] = num;
// Increment the index variable
index++;
// If the the duplicate exists
for(int i = 0; i < array.length;i++){
if(array[index] == num){
if(array[i - 1] == num){
JOptionPane.showMessageDialog(null,"Array may not contain duplicates ","Array Duplicate",JOptionPane.ERROR_MESSAGE );
break;
}
}
}
Trying to fix your code here
//Convert the string into an int
num = Integer.parseInt(inputField.getText());
boolean exsist = false;
// If the the duplicate exists
for(int i = 0; i < array.length;i++){
if(array[i] == num){
exsist = true;
JOptionPane.showMessageDialog(null,"Array may not contain duplicates ","Array Duplicate",JOptionPane.ERROR_MESSAGE );
break;
}
}
if(!exsist)
{
// Add it to the an index
array[index] = num;
// Increment the index variable
index++;
}
something like this should work
The reasoning is
not using the variable i from the for loop, this results in checking the same value all the time
the checks in the if statements are broken, the checks simply don't make sense, try to use the ior other variables that change each loop to check multiple values
there is no need to add the value before testing if it exsist, if you do so you will have to remove it after, doing it after therefore result in a faster code (even if only very very little) and a safer code since you can't fail to delete the value
After some thinking and some suggestion. I managed to solve it.
// Set orginal to true
boolean orginal = true;
//Convert the string into an int
num = Integer.parseInt(inputField.getText());
// Loop to find the duplicate
for(int i = 0; i < array.length; i++){
// Check if there's a duplicate
for(int j = 0; j < array.length; j++){
// Check if the num is equal to any of the numbers in the array
if(array[j] == num){
// Set orginal to false
orginal = false;
// Throw the duplicate exception
throw new DuplicateValueException(result);
}
}
// If there is no duplicates
if(orginal){
// Add the number to the array
array[index] = num;
// Break out the loop
break;
}
}
// Print the message
System.out.println("array["+index+"] = "+ num);
// Increment the index variable
index++;
for(int i = 0; i < array.length-1;i++){
if(array[i] == num){
JOptionPane.showMessageDialog(null,"Array may not contain duplicates ","Array Duplicate",JOptionPane.ERROR_MESSAGE );
break;
}
}
Try this!
But your code will add that number to array anyway as you are adding it before checking it.
This code makes no sense :
// Add it to the an index
array[index] = num;
// Increment the index variable
index++;
for(int i = 0; i < array.length;i++){
if(array[index] == num){
You add the num int at the index index of the array and then in the loop you want to check if index+1 == num.
In your logic you should rather check if index == num.
And anyway it is useless, you have done : array[index] = num;.
So if(array[index] == num) can be only true.
I want to display a dialog when they enter a number that is already in
the array
You should rather do the check of duplication number before adding it in the array.
The general idea would be iterating the array and if during the iteration, a element of the array is equals to num, you have not add num.
In the contrary case, if no element is equals to num, you have to add it.
It seems to be a school working, so I will not detail further the solution.
I think this will work for sure even for the case of [5->5]
index++;
// If the the duplicate exists
if (index > 0) {
for (int i = 0; i < array.length; i++) {
if (array[i] == num) {
JOptionPane.showMessageDialog(null, "Array may not contain duplicates ", "Array Duplicate", JOptionPane.ERROR_MESSAGE);
break;
}
}
}

java - referencing elements in an arraylist whilst removing some

I have a for loop looping through each element in an arrayList performing someMethod() on them, depending on the result of that method I either want to keep or remove that element from the list. for example:
int returnResult;
for (int i=0;i<4;i++){
returnResult = someMethod(arrayList.get(i));
if (returnResult == -1){
arrayList.remove(i);
}
}
My question is; if i have say 5 elements in the list and on the second iteration through the loop (so when i=1), I remove that element, when I go through the 3rd iteration will arrayList.get(2) be referencing what was actually the 4th element? i.e. does it immediately reduce the stack size?
Yes, it does. In order to get around this, you can iterate through the array in reverse.
int returnResult;
for (int i=3;i>=0;i--){
returnResult = someMethod(arrayList.get(i));
if (returnResult == -1){
arrayList.remove(i);
}
}
This pops them off from the end, and doesn't affect the elements left to go through.
Replace your code with this :
int returnResult, limit = 4;
for (int i=0; i < limit; i++){
returnResult = someMethod(arrayList.get(i));
if (returnResult == -1){
arrayList.remove(i);
limit--;
}
}

View if a word's letters are in ascending order

I've been at this for a while, but as the title says, I'm trying to create a method that will compare each letter to the letter after it and see if the word is ascending. The method should then return a boolean value. But when it's implemented in my code, it will fail with:
java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(Unknown Source)
and multiple other lines of error code.
Here's my source code:
public static boolean ascending(String word){
int i = 0;
boolean ascend;
do {
if (word.charAt(i) <= word.charAt(i+1))
ascend = false;
else
ascend = true;
} while (i <= word.length());
i = 0;
return (ascend);
}
I can't see where I'm going wrong?
condition should be
i < word.length()-1
and the i = 0; at the end should be in side the loop as i++, else it will be infinite loop.
also, you have actually put the reverse check. once you fix ArrayIndexOutOfBoundsException you will return false for ascending string and true otherwise
public static boolean ascending(String word){
if(word == null || word.length <2) return false;
int i = 0;
boolean ascend = false;
while(i < word.length()-1){
if (word.charAt(i) <= word.charAt(i+1))
ascend = true;
else{
ascend = false;
break;
}
i++;
}
return (ascend);
}
In pseudo code:
take the first letter (F) => store it
take the next letter (N) => check against first => stop here if not OK
is there another next letter => stop here if not
update first letter (F) with next letter (N)
repeat starting from 2
Few things needs to be fixed here:
You need to increment "i" to traverse through the word.
Restrict your while loop till (i < word.length() )
You may break at any point when you find ascend is false. No need to continue with the looping.
I would not use a do while because there is an opportunity to run this on an empty string causing it to crash. I would instead use a regular while and at the beginning test for while (i < word.length()-1). You never want to test past the end of the string. You always want to check to see for a string length of n that charAt(n-1) < charAt(n). Also I don't see an incrementer to increase the value of i. Loop will never continue on to the next letter and will run forever.
public static boolean ascending(String word){
int i = 0;
boolean ascend;
while (i < word.length()-1)
{
if (word.charAt(i) <= word.charAt(i+1))
ascend = false;
else
ascend = true;
i++;
}
i = 0;
return (ascend);
}
Do not use do-while loop. Even if you do you need to run some checks beforehand to make sure your word has length more than 1 otherwise your code will raise an IndexOutOfBounds Exception. If you insist on using it, change your condition to i
Here is a working code example:
public boolean isAscending(String word){
if (word==null || word.length==0){
return false;
}
for (int i=1; i<word.length(); i++){
if (word.charAt(i) < word.charAt(i-1))
return false;
}
return true;
}

How to check an entire array?

I want my program to check whether every element in the entire int[] array is non-zero.
What I currently have:
for(int i=0; i<myArray.length; i++)
{
if(myArray[i] == 0)
{
completed = false;
}
else
{
completed = true;
}
}
But the loop keeps doing else statement, if only one array in the middle is non-zero and won't check the rest of the array.
You need to have it break out of the for loop once you've found a 0:
if(myArray[i] == 0)
{
completed = false;
break;
}
This way, if you find a non-0 element later, you won't falsely set completed back to true.
You can use a break statement to break the loop on first occurrence of a zero value as:
boolean completed = true;
for(int i=0; i<myArray.length; i++) {
if(myArray[i] == 0) {
completed = false;
break;
}
}
if(!completed){
//array has zero values
}
Other important pointers:
Arrays.binarySearch(): works only on sorted array so not useful in your case.
Searches the specified array of bytes for the specified value using the binary search algorithm. The array must be sorted (as by the sort(byte[]) method) 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.
indexOf method internally does the same loop and comparison. So I don't see much difference in your original pattern and new syntax. Though it may make your code look compact.
You can put break; statement after finding the first 0 element, so that it will jump out the loop.
There is no need to loop through each elements: JSBIN Demo
Use IndexOf();
var myArray = [1,2,1,3];
var completed = myArray.indexOf(0) != -1
Alternately, you could do
var completed = true;
for(int i=0; i<myArray.length; i++)
{
if(myArray[i] == 0)
{
completed = false;
}
}
Which would do the same.

Variable not initialized in for loop

So I've been practicing my Java programming skills on the CodingBat website, when I came across this problem. In it, you have to make a simple method that takes in an array of integers of dynamic length, check to see if the elements in the array are in increasing order (1, 2, 3, 15678, etc), and return "true" if true, or "false" if there is an integer out of order.
Firstly, I initialize a boolean variable named "result". Then, I iterate through the array of integers passed by the method. If the current index value is less than the next index value, I set "result" to "true", and repeat the loop. Else, I'll set "result" to "false", break out of the loop and set "result" to "false". After the FOR loop, I return "result".
However, I've been receiving an error message that "result" has not been initialized properly. I can kinda understand the confusing with the JVM, however I thought that setting the value for "result" inside of the IF/ELSE statements would solve that.
Here is a copy of the code that I have done so far:
public boolean scoresIncreasing(int[] scores) {
boolean result;
for (int i = 0; i < scores.length; i++) {
if (i < (i + 1)) {
result = true;
}
else {
result = false;
break;
}
}
return result;
}
First of all, i < i+1 will always be true, unless i = Integer.maxValue, in which case you'll wrap around to Integer.minValue.
What you want is scores[i] < scores[i+1] , and you'll need to adjust your loop values to avoid an index out of bounds on the last iteration.
So, your code fixed:
public boolean scoresIncreasing(int[] scores) {
boolean result;
for (int i = 0; i < scores.length-1; i++) // fix loop end
{
if (scores[i] < scores[(i + 1)]) {
result = true;
}
else {
result = false;
break;
}
} // missing brace
return result;
}
Try this as an alternative. It works on the principle that once you get a false, you can get out immediately.
public boolean scoresIncreasing(int[] scores) {
boolean result = true; // assume true
for (int i = 0; i < scores.length-1; i++) // fix loop end
{
if (scores[i] > scores[(i + 1)]) return false;
} // missing brace
return result;
}
Of course, you may want to introduce bounds checking at the beginning to ensure that there are at least two values.
You are simply missing a closing brace (}) before return result.
As a suggestion to simplify the code (and deal with arrays of 0 elements!), you may want to initialize result to true. Then, as you loop over the array, change result to false if and only if you find an element out of order.
One other word of caution. You use element i + 1 in your for loop. Think about what will happen when you get the last element in the array (i == scores.length - 1).
if (i < (i + 1)) will always evaluate to true. You need to compare the contents of the array at those indexes, not the indexes themselves.
Something like:
public boolean scoresIncreasing(int[] scores) {
for(int i = 0; i < scores.length-1; i++) {
if(scores[i] > scores[i+1]) return false;
}
return true;
}
What if scores has 0 elements? ;]
in your code, you are returning result inside the for loop (after the if-else statement).
Add another bracket before the return statement (to close the for loop)

Categories

Resources