I wrote this program to find the item and then to remove all elements which are smaller than the item. The are no compilation errors, but when I run the program, the following message appears.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at bb.deleteValues(bb.java:15)
at bb.main(bb.java:33)
Process completed. "
Code:
import java.util.ArrayList;
import java.util.Scanner;
public class bb {
public static boolean deleteValues(ArrayList<Integer> list, int item)
{ int p =list.indexOf(item);
if(!list.contains(item))
return false;
else
for(int i=p; i<list.size();i++ )
{int n=list.get(i);
if (n>list.get(i+1))
list.remove(p);
list.remove(i+1);
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>(8);
a.add(3);
a.add(10);
a.add(4);
a.add(5);
a.add(3);
a.add(2);
a.add(8);
a.add(6);
a.add(4);
if(deleteValues(a,4))
for(int x : a)
System.out.print(x+ " ");
}
}
Your deleteValues method loops i from p to list.size()-1, but the loop's body contains list.get(i+1) and list.remove(i+1), so when i==list.size()-1, list.get(i+1) and list.remove(i+1) will attempt to access an item from an index not present in the list, which is the cause of the exception.
Removing the elements smaller than the passed item requires iterating over all the elements in the list, and comparing each one to the passed item. Note that when you remove the i'th element from the list, the (i+1)'th element becomes the new i'th element. That's why i should be incremented only if you don't remove an element from the list.
public static boolean deleteValues(ArrayList<Integer> list, int item)
{
int p = list.indexOf(item);
if(p<0)
return false;
for(int i=0; i<list.size();) {
if (list.get(i) < item) {
list.remove(i);
} else {
i++;
}
}
return true;
}
list.remove(i+1); will exceed the list size. For ex, when you are passing the 4th element, it will search for the element at 5th postion
The problem is in your deleteValues function, you loop while i is less than the size of the ArrayList, but add 1 when you call the get function, which can and will cause an IndexOutOfBoundsException, because it can make i equal to the size of the ArrayList, which is invalid. Change your for loop, and remove the cases where you have i+1, like so:
for(int i=p; i<list.size();i++ )
{
int n=list.get(i);
if (n>list.get(i))
list.remove(p);
list.remove(i);
}
Also, if your function is meant to remove all copies of a certain value, the code can be much, much simpler, and clearer:
public static boolean deleteValues(ArrayList<Integer> list, int item)
{
if (list.contains(item))
{
for (int i = 0; i < list.size(); i++)
if (list.get(i) == item)
list.remove(i);
return true;
}
return false;
}
import java.util.ArrayList;
import java.util.Scanner;
public class Ex {
public static boolean deleteValues(ArrayList<Integer> list)
{
for(int i=0; i<list.size();i++ )
{int n=list.get(i);
if (n>list.get(i+1))
// list.remove(i);
list.remove(i+1);
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>(8);
a.add(3);
a.add(10);
a.add(4);
a.add(5);
a.add(3);
a.add(2);
a.add(8);
a.add(6);
// a.add(4);
if(deleteValues(a))
for(int x : a)
System.out.print(x+ " ");
}
}
you are adding one extra object to the arraylist with itz size specified and you are using index values wrongly in the deleteValues method so plz check with the both codes.
import java.util.ArrayList;
import java.util.Scanner;
public class Ex {
public static boolean deleteValues(ArrayList<Integer> list, int item)
{ int p =list.indexOf(item);
if(!list.contains(item))
return false;
else
for(int i=0; i<list.size();i++ )
{int n=list.get(i);
if (n>list.get(i+1))
list.remove(p);
//list.remove(i+1);
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>(8);
a.add(3);
a.add(10);
a.add(4);
a.add(5);
a.add(3);
a.add(2);
a.add(8);
//a.add(6);
a.add(4);
if(deleteValues(a,4))
for(int x : a)
System.out.print(x+ " ");
}
}
Related
here's the code for MyArrayList
public void addLast(int number){
if(!isFull())
doubleTheArray();
element[count++] = number;
}
and here's the code for MyOrderedList
public void add(int item){
for(int i = 0; i < count; i++){
for(int j = i+1; j < count; j++){
if(element[i] > element[j]){
item = element[i];
element[i] = element[j];
element[j] = item;
}
}
}
addLast(item);
}
This is the main method
public static void main(String [] args){
MyOrderedList oList = new MyOrderedList();
oList.add(3);
oList.add(5);
oList.add(2);
oList.add(4);
oList.add(7);
oList.add(8);
oList.add(10);
System.out.println("Ordered list of items: "+ oList);
}
Can anyone help me find out what's wrong? We're not allowed to use sort so I made a solution but 2 numbers are outputted twice in the main method for MyOrderedList. We have to add the elements at the right location. Or in ascending order for add(item). isFull() is boolean method that doubles (doubleTheArray()) the array size if it is true.
new to java,I read the answer in the leecode ,and it ask for a array like [1,2,3]and return its permutation [1,3,2],[2,1,3].....and feel confused especially this code
Collections.swap(output, first, i);
backtrack(n, output, res, first + 1);
I do not know why the use Collections.swap(output,first,i) I think in first loop ,the first and i is equal to 0,so why use swap here. they are same vaule. what this recursion actually do,I debug it and can not figure out.code is below:
package com.company;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Main {
public static void main(String[] args) {
int[]arr=new int[]{1,2,3};
Main main1=new Main();
List<List<Integer>> lists = main1.permute(arr);
System.out.println(lists);
}
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> output = new ArrayList<Integer>();
for (int num : nums) {
output.add(num);
}
int n = nums.length;
backtrack(n, output, res, 0);
return res;
}
public void backtrack(int n, List<Integer> output, List<List<Integer>> res, int first) {
if (first == n) {
res.add(new ArrayList<Integer>(output));
}
for (int i = first; i < n; i++) {
Collections.swap(output, first, i);
backtrack(n, output, res, first + 1);
Collections.swap(output, first, i);
}
}
}
According to the documentation, the swap() method of java.util.Collections class is used to swap the elements at the specified positions in the specified list. If the specified positions are equal, invoking this method leaves the list unchanged.
So in a recursive technique, it is ok to have that call even though it does nothing in that particular condition, just to make the logic easier to implement and understand. If you want to avoid that, you will un-necessarily need to bring conditional statements into the logic, which is really not required.
Here is a somewhat simplified and commented version that may help follow what the code does:
import java.util.*;
public class Main {
public static void main(String[] args) {
int[]arr=new int[]{1,2,3};
List<List<Integer>> permutations = new Main().permute(arr);
System.out.println(permutations);
}
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> input = new ArrayList<>();
for (int num : nums) {
input.add(num);
}
backtrack(input, result, 0);
return result;
}
public void backtrack(List<Integer> input, List<List<Integer>> result, int currentIndex) {
if (currentIndex == input.size() ) { //index passed the end of the collection
result.add(new ArrayList<>(input)); //add the permutation to the returned result
//the method return here because when currentIndex == input.size()
//next for loop will not be executed
//you may add a return here. It may improve the readability of the code
}
//iterate over each element of the array form currentIndex to the end
for (int i = currentIndex; i < input.size(); i++) {
Collections.swap(input, currentIndex, i);//create a permutation by swapping
backtrack(input, result, currentIndex + 1); //increment currentIndex and process new permutation
Collections.swap(input, currentIndex, i);//undo permutation before next loop
}
}
}
Any idea what is wrong with this line? outStr[i]=(String) s.pop();
import java.util.ArrayList;
import java.util.Scanner;
public class StringWordReverse {
public String[] StringToWord(){
Scanner sc = new Scanner(System.in);
sc.useDelimiter(" ");
ArrayList<String> wordList= new ArrayList<String>();
String sc_in= sc.nextLine();
String[] sc_split=sc_in.split(" +");
for (int i=0; i<sc_split.length; i++){
wordList.add(sc_split[i]);
}
String[] stringArr= new String[wordList.size()];
for (int i=0; i<wordList.size(); i++){
stringArr[i]= wordList.get(i);
}
return stringArr;
}
public String[] reverseWords(String[] words){
Stack<String> s= new Stack<String>();
String[] outStr=new String[words.length];
for (int i=0; i<words.length; i++){
s.push(words[i]);
}
for (int i=0; i<words.length; i++){
System.out.println(s.stackSize());
outStr[i]=(String) s.pop();
}
return outStr;
}
public static void main(String[] argc){
StringWordReverse swr = new StringWordReverse();
String[] inputWords= swr.StringToWord();
String[] outputWords=swr.reverseWords(inputWords);
for (int i=0; i<outputWords.length;i++)
System.out.println(outputWords[i]);
return;
}
}
And here is my Stack class:
import java.util.ArrayList;
public class Stack<E> {
private ArrayList<E> s = new ArrayList<E>();
private static int size=0;
public void push(E item){
s.add(item);
size++;
return;
}
public E pop(){
size--;
return s.remove(size-1);
}
public int stackSize(){
return size;
}
}
Here's the error I receive:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:400)
at java.util.ArrayList.remove(ArrayList.java:477)
at XYZ.Stack.pop(Stack.java:16)
at XYZ.StringWordReverse.reverseWords(StringWordReverse.java:35)
at XYZ.StringWordReverse.main(StringWordReverse.java:47)
Some wrong things in this code :
you use raw types instead of generics. Let the compiler help you with (most) runtime type error : Stack<String> stack = new Stack<>()
in Stack.pop, you never check you have an element to pop. You should test it and throw an exception such as NoSuchElementException if the stack is empty.
in Stack.pop, you are decrementing the size and then removing item size - 1, so you basically decremented twice. This should be : s.remove(--size);
You are decreasing your size variable before you take the item from the stack using the same size variable. So when you call pop with one item left, you reduce size to 0 and then are trying to remove the item at position -1.
Why maintain your own size variable when you already have one as part of the list?
try changing this part of the code:
public E pop(){
size--;
return s.remove(size-1);
}
to this:
public E pop(){
return s.remove(size--);
}
thats the error.
All was well with this program until I made some changes in my addMainMenu method. Now it seems as though there is an array index out of bounds somewhere. Eclipse is not leading me too it. Does anyone know why this code has an array index out of bounds exception.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.LinkedList.checkElementIndex(Unknown Source)
at java.util.LinkedList.get(Unknown Source)
at Menu.main(Menu.java:58)
import java.util.LinkedList;
import java.util.List;
public class Menu {
LinkedList <LinkedList> mainMenuItems = new LinkedList <LinkedList> ();
public void Menu(){}
public boolean addMainMenuItem(String newItem, String existingItem, int position){
LinkedList <String> subMenuItems = new LinkedList <String> ();
for (int i = 0; i<= mainMenuItems.size(); i++){
if (mainMenuItems.get(i).contains(existingItem)){
subMenuItems.addLast(newItem);
int existingIndex = mainMenuItems.indexOf(existingItem);
if (position == 1){
mainMenuItems.add(existingIndex + 1, subMenuItems);
break;
}
if (position == -1){
mainMenuItems.add(existingIndex, subMenuItems);
break;
}
if (i == mainMenuItems.size()){
subMenuItems.addLast(newItem);
mainMenuItems.add(subMenuItems);
break;
}
}
}
}
return true;
}
public boolean deleteMainMenuItem(String item){
if (mainMenuItems.contains(mainMenuItems.indexOf(item))){
mainMenuItems.remove(mainMenuItems.indexOf(item));
return true;
}
else{
return false;
}
}
public static void main(String[] args){
Menu b = new Menu();
b.addMainMenuItem("h", "b", 1);
b.addMainMenuItem("hi", "h", 1);
b.addMainMenuItem("i", "h", 1);
System.out.println(b.mainMenuItems.get(0));
b.deleteMainMenuItem("hi");
System.out.println(b.mainMenuItems.get(0));
System.out.println(b.deleteMainMenuItem("hi"));
}
There are two possible issues
1. In this line
for (int i = 0; i<= mainMenuItems.size(); i++)
you should have use i < mainMenuItems.size()
2. when you have not assigned any value to your LinkedList, you try to access an index of your LinkedList
Change the <= to < in: i<= mainMenuItems.size()
EDIT:
If mainMenuItems is still empty, the line mainMenuItems.get(i).contains(existingItem) will generate java.lang.IndexOutOfBoundsException because mainMenuItems.get(i) doesn't exist.
First - Change the for loop as shown below
for (int i = 0; i < mainMenuItems.size(); i++)
Also, you need to restructure addMainMenuItem method as shown below -
for (int i = 0; i < mainMenuItems.size(); i++){
if (mainMenuItems.size() == 0) {
//you should put list initialization code here
//means, logic when there is nothing in the mainMenuItems list
} else {
//when the list is not empty
}
}
You are getting IndexOutOfBoundsException because you are doing get(index) on mainMenuItems - which is empty in your for loop.
For example -
List<String> list = new LinkedList<String>();
list.get(0); //will throw the same exception
Write a method, downsize, that will remove every nth element from a LinkedList of employee names.
import java.util.LinkedList;
import java.util.ListIterator;
public class LinkedListDemo
{
public static void main(String[] args)
{
LinkedList<String> staff = new LinkedList<String>();
staff.add("John");
staff.add("Bob");
staff.add("Richard");
staff.add("Alice");
staff.add("Jane");
staff.add("Carlos");
staff.add("Jose");
staff.add("Maria");
downsize(staff, 3);
System.out.println(staff);
System.out.println("Expected: [John, Bob, Alice, Jane, Jose, Maria]");
}
public static void downsize(LinkedList<String> employeeNames, int n)
{
ListIterator<String> iter = employeeNames.listIterator();
for(int i=n; i<employeeNames.size(); i++)
{
iter.next();
}
iter.remove();
}
}
I'm having some troubles to find a perfect loop that can remove any nth element in my ListIterator. thank you!
This will remove every n-th element from the employeeNames LinkedList:
for(int i=0; i<employeeNames.size(); i++)
{
iter.next();
if (i % n == 0) iter.remove();
}
Never ever modify a list that you are currently iterating over. That way madness lies.
public static List<String> downsize(List<String> employeeNames, int n) {
Set<String> employeesToRemove = new HashSet<String>();
for (int index = n; index < employeeNames.size(); index += n) {
employeesToRemove.add(employeeNames.get(index);
}
employeeNames.removeAll(employeesToRemove);
}
If, however, you absolutely must iterate over the array, here is that madness also.
public static List<String> downsize(List<String> employeeNames, int n) {
for (int index = employeeNames.size() - (n -(employeeNames.size() % n)) ; index >= 0; index -= n) {
employeeNames.remove(index);
}
return employeeNames;
}