I've got a string array, and I should check i element and i + 1, for some coincidence, except the last element, because it allready checked by previous element.
String[] somearr = new {"first, second"};
arr[i] && arr[i+1], allready checked the last element, and when arr[i] = second I've got ArrayIndexOutOfBoundsException.
if (arr[i].equals("first") && arr[i + 1].equals("second"){
//do something;
}
My question is how not to check the last element because I allready checked it in previous?
Check if index + 1 out of bound:
if ((index + 1) < somearr.length && somearr[index].equals("first") && somearr[index + 1].equals("second")) {
// do something
}
You can try following
if(i< arr.length()-1 && arr[i].equals("first") && arr[i + 1].equals("second"))
Related
I have an ArrayList of integers, I want to remove all the leading zeroes, code seems all right but U am getting unusual output.
Input:
0 0 0 1 9 9
Output:
0 1 9 9
Expected output:
1 9 9
public class Solution {
public ArrayList<Integer> plusOne(ArrayList<Integer> a) {
int flag=0;
//System.out.println(a.size()+" "+a.get(2));
for(int i=0;i<a.size();i++)
{
if(flag==0)
{
//System.out.println("val of i="+i+" "+a.get(i));
if(a.get(i)==0){
a.remove(i);
//System.out.println(flag);
}
else
{
//System.out.println("flag="+flag+" i="+i+" value"+a.get(i));
flag=1;
//System.out.println("flag="+flag+" i="+i+" value"+a.get(i));
}
}
if(flag==1)
break;
}
System.out.println();
return a;
}
}
You can remove the leading zeros by just searching for the first non-zero value, and then clearing the preceding sublist:
Iterator<Integer> it = list.iterator();
int i = 0;
while (it.hasNext() && it.next() == 0) {
++i;
}
list.subList(0, i).clear();
Removing a block of the list like this can be more efficient than removing the elements one at a time. e.g. if you removed them one at a time, ArrayList would shift all of the tail elements one position along each time, so the removal would be O(n^2).
The problem is that you're removing elements from the list while you're iterating over it. When i = 0:
a.remove(i);
removes the first element of the list and all elements are shifted: the 2nd becomes the 1st, etc. Then in the for loop, i is set to 1 after that. Hence, the second element is ignored: it became the first after the remove operation and i jumped over it because it was incremented.
The ugly solution would be to have i--; right after a.remove(i); to account for that shift.
However, a better solution would be to use a ListIterator:
public ArrayList<Integer> plusOne(ArrayList<Integer> a) {
ListIterator<Integer> it = a.listIterator();
while (it.hasNext() && it.next() == 0) {
it.remove();
}
return a;
}
This code retrieves it with listIterator(). While there are still elements and the next element is 0, we remove it with remove().
The problem is that i is incrementing while a.size() is shrinking. When i==0 you remove element 0 so all the values shift down 1, and next you remove element 1 but element 0 is also 0 so you skip this. i.e. you are only removing half the leading zeros.
BTW You should be able to confirm this by stepping through your code in your debugger. Helping you understand your code and find bugs is what it is for.
The simplest change is
for (int i = 0, max = a.size(); i < max; i++)
and
// you only want to check the first element.
if (a.get(0) == 0)
a.remove(0);
A more efficient way of doing this is to find the first element which is not 0 and return a sub list
public static List<Integer> trimLeadingZeros(List<Integer> list) {
for (int i = 0; i < list.size(); i++)
if (list.get(i) != 0)
return list.subList(i, list.size());
return Collections.emptyList();
}
Logic: anytime you see 0, loop from that point to the end, if inside that loop you see anything other than 0, break out from that loop.
Code:
//a is arrayList;
int count = 0;
for(int c = b; c < size; c++){
if(a.get(c) == 0 )
{
count++;
}
}
//size = 10,saw zero at 6th position that means leading zeros has to be 4,
// b is when I first saw 0
if(count == (size -b)) {}
else {
//else we just copy
ret.add(b, a.get(b));
}
Loop through the ArrayList and if you encounter 0 just remove it.
while (i < a.size() - 1 && a.get(i) == 0) {
a.remove(i);
}
Best Solution:
while(a.get(0)==0) { a.remove(0); }
I'm looking for the equivalent word in the database by the ContextQuery method, and when a equivalent word is null the program must try to use the next index from words and add it up to the current to make it a two word, if the two word is still null the program will make it a three word looking for the next 2 value, the equivalent is now being printed in console but i have the error IndexOutOfBoundsExpection after running
for (int i = 0; i < words.size(); i++){
temp = QueryWithContext.query(words.get(i));
if((temp == null || temp.isEmpty()) && words.size() >= i+1)
{
QueryWithContext.query(words.get(i)+" "+words.get(i+1));
temp = QueryWithContext.query(words.get(i)+" "+words.get(i+1));
System.out.println("1st if");
if((temp == null || temp.isEmpty()) && words.size() >= i+2)
{
temp = QueryWithContext.query(words.get(i)+" "+words.get(i+1)+" "+words.get(i+2));
}
else
{
temp = words.get(i);
}
}
System.out.println(temp);
if((temp == null || temp.isEmpty()) && words.size() >= i+1)
must be
if((temp == null || temp.isEmpty()) && words.size() > i+1)
otherwise
words.get(i+1)
throws the IndexOutOfBoundsExpection.
The problem is most likely in this line: temp = QueryWithContext.query(words.get(i)+" "+words.get(i+1)+" "+words.get(i+2));. You are looping until i is less than the size of words, so i will range from 0 to n - 1.
The problem is that in your code, you keep going till i + 2 (and previously, i + 1). This is what is most likely causing your error. To fix this, see if you can do the following: for (int i = 0; i < (words.size() - 2); i++){
Alternatively, do as #Uli recommends.
I'm writing an algorithm that compares a number n with elements n+1 and n-1.
This means that the first and last check fail because array.length + 1 would be out of bounds and so would array[0-1]. I'm trying to find a way to stop the program from throwing the array index out of bounds exceptions but I am not sure how to do this. My initial plan was to check that array[0-1] and length+1 are always null like so:
numbers[x-1] == null
But this doesn't work because of a mismatch from int to null. Any ideas on how to remedy this would be very appreciated.
Iteration starts with index 1 and ends with index array.length - 1.
for(int i=1;i<array.length-1;i++){
int prev = array[i-1];
int current = array[i];
int next = array[i+1];
}
I'd just a checks for the edges of the array :
int prev = -1;
int next = -1;
for (int i=0; i<array.length; i++) {
if (i>0)
prev = array[i-1];
if (i < array.length - 1)
next = array[i+1];
else
next = -1;
// now do whatever you wish to do with array[i], prev and next
}
In that case I chose -1 to represent a "null" value. You can use something else, depending on the range of the values that can be in your array.
You should use "if" statements to check that your index is within the bounds:
if (x >= 0 && x < numbers.length)
numbers[x] = someNumber
Besides the length checks the other answers suggest, you also could create the array one element bigger, so that the last element n+1 is still a valid array position but marks the end of the array. This way you can forget all the length checks which would improve the speed of your algorithm - if this is important. Otherwise I would implement a length check.
Something you could use to compare arrays with last and next element:
for(int index=1;index<array.length-1;index++){
if (number > numbers[index - 1] && number < numbers[index + 1]) {
System.out.println("Number is between " + (index - 1) + " and " + (index + 1));
}
}
i don't know how to do something specific at the last loop of this for loop:
String msg = "---Player List, Count:" + users.size() + "---" + brln;
for (int i = 0; i < users.size(); i++) {
if((i - 1) == users.size()){
msg += "--::" + users.get(i).name; //Do this at the last loop
return; //returns the void
}
msg += "--::" + users.get(i).name + brln; // do this by default
}
Can you help me get this to work?
Your condition is wrong: instead of (i - 1) == users.size() use (i + 1) == users.size() or i == users.size() - 1.
Basically (i - 1) == users.size() would match the element after the last (which clearly doesn't exist), i.e. for a list of size 5 you'd get (i - 1) == 5 or i == 6.
In the example above (i + 1) == users.size() and i == users.size() - 1 would resolve to (i + 1) == 5 and i == 5 - 1 which both result in i == 4, which is the last index in the list.
Edit: Btw, your loop is still quite odd. You basically seem to add a line break after each but the last element. Why don't you change it to something like this:
String msg = "---Player List, Count:" + users.size() + "---" + brln;
for (int i = 0; i < users.size(); i++) {
if( i > 0){
msg += brln;
}
msg += "--::" + users.get(i).name;
}
This would add a line break before every line except the first. Note how the condition is much easier.
Change this
from:
if((i - 1) == users.size()){
to:
if((i + 1) == users.size()){
What you want in effect is a string of entries separated by a delimiter, where the delimiter is a line break. Use this idiom:
String delimiter = "", result = "";
for (...loop init...) {
result += delimiter;
...append one entry...
delimiter = brln;
}
Other than that, building a large string by creating new string in each iteration is bad for performance as it is an O(n^2) operation. You should prefer a StringBuilder.
If you need last index just use if( i == users.size()-1)
In the example you provide you should use a StringBuilder for string concatenation. Then you only need to loop without asking anything and you can use for-each loop.
StringBuilder msg =new StringBuilder().append("---Player List, Count:").append(users.size()).append("---");
for (User user : users) {
msg.append(brln)
.append("--::").append(user.name)
.append(brln);
}
If you change your code a little, you can avoid a special case:
StringBuilder msg = new StringBuilder("---Player List, Count:" + users.size()
+ "---"); // Note a lack of brln
for (int i = 0; i < users.size(); i++) {
msg.append(brln + "--::" + users.get(i).name);
}
return msg.toString();
Ideally you should use a StringBuilder for concatenating strings in a loop, as I've done above.
(This solution works in your case, since you had a header including a line break. See other solutions for a generic way to insert string X between every occurence but the last in a loop).
you are doing it wrong. Change your line:
if((i - 1) == users.size())
by this one:
if(i == (users.size()-1))
Change your condition to
i == users.size() - 1
Why? In Java (and other languages) the first element in a list is at index 0, and the last element at N-1 (if N is the number of elements currently in the list), so users.size() - 1 is the index of the last element. For example, if there are 10 elements in users list, the last will be at index 9.
Full code:
String msg = "---Player List, Count:" + users.size() + "---" + brln;
for (int i = 0; i < users.size(); i++) {
//if i equals to the last index, do your special handling of the loop
if(i == (users.size() - 1)) {
msg += "--::" + users.get(i).name; //Do this at the last loop
break;
}
msg += "--::" + users.get(i).name + brln; // do this by default
}
Although this might not help you right now (when you don't use Java 8), all this messy code will have an end with Java 8:
// requires Java 8
String msg = users.stream().map(User::name).collect(Collectors.joining(brln));
What is the best way to check if a string index is in bounds? Let's say we are checking a String for index i-1 or i+1 because you cannot say != null.
Example:
for (int i = 0; i < string.length(); i++)
{
if (string.charAt(i+1) == '#' && string.charAt(i - 1) != '1')
{
}
}
Should you just check the length of the string and see if it is within it?
string.charAt(i+1) == '#'
Yes, I think you need to make sure i+1 is not greater than String length.
Example:
if( (i+1) < string.length() && (i-1) >= 0 && (yourcode))
{
}
Why not just check the length of the string?
if(myString.length() - 1 > i)
I've always modified the length (and/or start) of the loop in these cases... these are all good answers - there's no one way to do it, but this is how I would do it:
for (int i = 1; i < string.length() - 1; i++)
{
if (string.charAt(i+1) == '#' && (i != 1 || string.charAt(i - 1) != '1'))
{
}
}
EDIT: After considering all of the situations that this code entails, I wouldn't necessarily do this in this manner, but find a cleaner way to express exactly what I'm trying to accomplish
The simplest way is to change your for loop like this:
for (int i = 1; i < string.length() - 1; i++)
{
if (string.charAt(i+1) == '#' && string.charAt(i - 1) != '1')
{
}
}
Explanation:
string.charAt(i - 1) implies that you might read position i-1 of the string. Since 0 is the lowest valid value you can start the iteration with i = 1
string.charAt(i + 1) implies that you might read position i+1 of the string. Since string.length() - 1 is the highest valid value you need to end your iteration at i == string.length() - 2. Since the for-loop checks the condition before entering the loop using i < string.length() - 1 will be just right.
I would try with this code.
for (int i = 1; string!= null && string.length() >= 3 && i < string.length() - 1; i++)
//it solve the case of String == null and string too short
//it optimize the max number of cycles
{
if (string.charAt(i+1) == '#' && string.charAt(i - 1) != '1')
{
}
}