Insert elements into array in sorted order - java

I have written this code for insert and remove elements into and from array. But I want to insert elements into array in sorted order. How can I improve my "add" method? And I also don't know the implementation of the "remove" method. How can I implement remove method
public void add(int index, String str) {
// First make sure the index is valid.
if (index > elements || index < 0) {
throw new IndexOutOfBoundsException();
}
// If the list is full, resize it.
if (elements == list.length) {
resize();
}
// Shift the elements starting at index
// to the right one position.
for (int index2 = elements; index2 > index; index2--) {
list[index2] = list[index2 - 1];
}
// Add the new element at index.
list[index] = str;
// Adjust the number of elements.
elements++;
}
public boolean remove(String str) {
return false;
}

After filling the array, call:
Arrays.sort(array)
You are resizing the array, why dont you simply use a List?
List<Type> list = new ArrayList<Type>();
Collections.sort(list);

I suppose you should sort array not on adding element but when you return it. For decreasing array accesses you may use flag that will indicate that array must be resorted, i.e.
private boolean hasNew = false;
public void add (int index, String str) {
// Your code
hasNew = true;
}
public int[] getArray() {
if (hasNew) Arrays.sort(list);
return list;
}
This is the general idea, but feel free to adopt it.

Related

Recreating Arraylist class

I'm working on recreating the ArrayList class. I have a problem with the add method. I want my add method to return the new table and to affect it to my element. But when I want to get into the element of my table element it's always null.
And another question..I wanna Create the constructor that takes objects as the elements of the Arraylist like ArrayListBis(1,2,3)..what's gonna be the parameter of the contractor is it ArrayListBis(Object... args) ?
public class ArrayListBis {
final static int DEFAULTSIZE=50;
private int indexCourant,dernierElement,size;
private Object [] elements;
public ArrayListBis(int size){
elements=creatList(size);
indexCourant=0;
dernierElement=size-1;
this.size=size;
}
public void add(Object o){
add(o,size());
}
public void add(Object o, int index){
Object[] temp;
if(index <0 || index > size())
throw new IndexOutOfBoundsException();
else{
temp=creatList(size()+1);
for(int i=0;i!=size()+1;i++){
if(i<index)
temp[i]=elements[i];
else if(i==index)
temp[i]=elements[index];
else
temp[i]=elements[i+1];
}
this.size++;
elements=temp;
}
}
There a couple issues with your add method. First, you do not need to recreate your list every time a new element is added. The reason is that your list will not start out full, hence this line
add(o,size());
should only be done on the condition that this.size == elements.length. However, I believe you should use size or some variable to reflect the actual count of how many elements were inserted so far into your arraylist. So in your constructor, I would set this.size = 0 instead since it starts out with zero elements. Now in your original add method, only create a new array if you're adding to an array that's full. And like others have said, you weren't adding the new element to begin with. So with those changes it should now look like this,
public void add(Object o, int index){
Object[] temp;
if(index >= 0 && index < elements.length)
temp[index] = o;
size++;
else{
temp=creatList(elements.length * 2);
for(int i=0;i < elements.length;i++){
if(i<index)
temp[i]=elements[i];
else if(i==index)
temp[i]=o;
else
temp[i]=elements[i+1];
}
temp[index] = 0;
size++;
this.elements = temp;
}
}
Only other thing I changed was how much the new list's size should be. I changed it to be double the original array's size because you don't want to make a new array of a size that's only one more bigger than the original because making new arrays and copying all the elements from the old one to the new one is a costly operation that shouldn't be done too often.

Method adding element to array of ints

I need help with creating a method that adds input int to an array, and returning a message if array is already full.
I have class Lista with 3 fields numbers, capacity and size. Than I have a counstructor taking int as parameter and seting the capacity of array for the object of Lista class. So far i have this code:
public class Lista {
private int[] numbers;
private int capacity;
private int size;
public Lista (int capacity) {
this.size = 0;
this.capacity = capacity;
this.numbers = new int[capacity];
}
public void addElement(int element) {
}
public static void main(String[] args) {
Lista lista = new Lista(10);
lista.addElement(1);
lista.addElement(2);
lista.addElement(3);
System.out.println(lista.numbers[1]);
I've tried with loops and ArrayLIst but nothing i wrotr realy worked. WHat would be the best way to do it?
You could implement your addElement method like so:
public void addElement(int element) {
if(size == capacity) {
System.out.println("array is full");
return;
}
numbers[size++] = element;
}
You need to throw exception when list is already full and you try to insert next element to it:
class List {
private int[] numbers;
private int nextIndex;
public List(int capacity) {
this.numbers = new int[capacity];
}
public void addElement(int element) {
if (nextIndex < numbers.length) {
numbers[nextIndex] = element;
nextIndex++;
} else {
throw new RuntimeException("list is full");
}
}
public int capacity() {
return numbers.length;
}
public int size() {
return nextIndex;
}
}
I've tried with loops and ArrayLIst but nothing i wrotr realy worked.
WHat would be the best way to do it?
You use an array to store your values, so you don't need to use ArrayList (it is an alternative).
A loop is for iterating. You don't need it either.
I need help with creating a method that adds input int to an array,
and returning a message if array is already full.
Returning a textual message is not really the way which an API should be designed. It should rather returns a boolean to indicate the result of the invocation.
For example, look at the boolean add(E e) method of the Collection interface.
So, you should change the declaration of addElement() in order to return a boolean to indicate if the element was added or not (the last one when the max capcacity was reached).
public boolean addElement(int element) {
if(size == capacity) {
return false;
}
numbers[size++] = element;
return true;
}
If you want to output a textual message, you could test the value of the boolean :
if (!myLista.addElement(5)){
System.out.println("max capacity added. Cannot add the element");
}

Comparing the values of two arrays using recursion?

I am trying to check if two arrays have the same length, and the same values in the same exact position.
My current code looks like this:
public class MyArray {
private int size;
private int[] array;
private boolean isSorted; //to check if array is sorted
private static int arrCount; //used to identify which MyArray object
public MyArray(){
size = 10;
array = new int[10];
arrCount+=1;
}
public MyArray(int Size){
size = Size;
array = new int[Size];
arrCount+=1;
}
public MyArray(MyArray arrOther){
this.size = arrOther.getSize();
this.array = arrOther.getArray();
arrCount+=1;
}
public int getSize(){
return size;
}
public int[] getArray(){
return array;
}
#Override
public boolean equals(Object other){
if (other instanceof MyArray){
MyArray second = (MyArray) other;
if (second.getSize() == this.getSize())
return equalsHelper(this.getArray(), second.getArray(), 0, (size-1));
}
//else
return false;
}
private boolean equalsHelper(int[] first, int[] second, int iStart, int iEnd) {
if (iStart == iEnd) {
return true;
}
if (first[iStart] == second[iStart]) {
if (equalsHelper(first, second, (iStart + 1), iEnd)) {
return true;
}
}
return false;
}
}//end class
for some reason it always returns true even if the arrays are in different order.
the equals method is called in the main program here:
--main method--
if (MA2.equals(MA1)) //the arrays are identical here
{
System.out.println("The first and second arrays are equal.");
}
else {System.out.println("The first and second arrays are NOT equal.");}
MA2.sort(); //the order of the elements changes
System.out.println("The second array has been sorted in ascending order.");
if (MA2.equals(MA1))
{
System.out.println("The first and second arrays are equal.");
}
else {System.out.println("The first and second arrays are NOT equal.");}
First check (preferably) outside of your helper should be to see if both the arrays have equal lengths. Makes no sense to continue otherwise.
equalsHelper should return true if end of array is reached.
I see no reason to have 2 separate pointers for index since the arrays are required to be of the same size and the same index is being checked.
Invocation:
....
....
if(first.length != second.length)
return false;
return equalsHelper(first, second, 0);
The helper method...
private boolean equalsHelper(int[] first, int[] second, int indx) {
if(indx == first.length)
return true;
if(first[indx] != second[indx)
return false;
return equalsHelper(first, second, indx+1);
}
Firstly, iStart and iEnd are redundant. use .length
String[] array = new String[10];
int size = array.length;
If you're trying to compare contents of arrays that may be identical, you need to pass through it manually.
for(int i = 0: (i > first.length || i > second.length; i++){
if(first[i] != second[i]){
return false;
}
}
return true
Your next problem is
if (iStart == iEnd){
return first[iEnd] == second[iEnd]; //return true or false
Your logic here is wrong. You can't directly compare arrays like this. It's comparing the memory address. This will always be false unless you pass through the exact same array when the method is called - which i don't think is what you're trying to do
Array lengths are set manually, so it's a conscious effort to get a difference.
Let me suggest using an ArrayList if you're expecting differing lengths. They're also more flexible.
ArrayList <Integer> a = new ArrayList <int>();
ArrayList <Integer> b = new ArrayList <int>();
Then you'll need to check their lengths. ArrayList uses the .length() method instead of an Array[].length property
if(a.length() == b.length()){
then if you want to see if each value in each index is identical, you'll need to pass through the array manually as shown above.

Removing a redundant value in an array

I am not sure why my removeDuplicates method refuses to actually get rid of non-unique values. I am not sure if the problem is with the size incrementation or my method call.
// post: places the value in the correct place based on ascending order
public void add(int value) {
size++;
if (size == 1) {
elementData[0] = value;
} else {
int position = Arrays.binarySearch(elementData, 0, size - 1, value);
if (position < 0 ) {
position = (-position) - 1;
}
for (int i = size - 1; i > position; i--) {
elementData[i] = elementData[i - 1];
}
elementData[position] = value;
}
if (unique) {
removeDuplicates();
}
}
//post: removes any duplicate values from the list
private void removeDuplicates() {
for(int i = size - 1; i > 0; i--) {
if (elementData[i] == elementData[i - 1]){
remove(i - 1);
}
}
}
#user98643 -
Jano's suggestion is spot-on correct: the best solution is to simply use the appropriate data structure, for example a TreeSet.
SUGGESTIONS:
1) In general, always consider using a container such a "List<>" in preference to an array
2) In general, look for the container that already has most of the properties you need
3) In this case, A) you want all elements sorted, and B) each element must be unique.
A TreeSet fits the bill beautifully.
IMHO..
http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html
http://math.hws.edu/javanotes/c10/s2.html
http://www.mkyong.com/java/what-is-the-different-between-set-and-list/
Try this..
// Convert it to list as we need the list object to create a
// set object. A set is a collection object that cannot have
// a duplicate values, so by converting the array to a set
// the duplicate value will be removed.
List<String> list = Arrays.asList(data);
Set<String> set = new HashSet<String>(list);
System.out.print("Remove duplicate result: ");
//
// Create an array to convert the Set back to array.
// The Set.toArray() method copy the value in the set to the
// defined array.
//
String[] result = new String[set.size()];
set.toArray(result);
for (String s : result) {
System.out.print(s + ", ");

Could someone give my code for a deque a quick once over please?

Been working on this for a while now and I think I've finally cracked it, it's working for all my tests, but I have a feeling there will be some niggling issues. This is a heavily simplified version of a double sided queue (deque) where every time a value is added, a temporary array is made to store all values, and then the new value appended on. It is easiest to explain this way, I believe. If someone could please just double-check I am correct and there is nothing glaringly wrong here, I would be extremely thankful. Thank you all very much ! :)
public class ArrayBasedDeque<EltType> implements Deque<EltType> {
private final int CAPACITY = 10;
private int capacity;
private int end;
private EltType deque[];
public ArrayBasedDeque() {
this.capacity = CAPACITY;
deque = (EltType[]) (new Object[capacity]);
}
public EltType first() {
return deque[0];
}
public EltType last() {
return deque[end-1];
}
public boolean isEmpty() {
return end == 0;
}
public int size() {
return deque.length;
}
public boolean isFull() {
return end == capacity;
}
public void insertFirst(EltType inserted) {
if (!isEmpty()) {
EltType[] tempArray;
capacity+=1;
tempArray = (EltType[]) new Object[capacity];
for(int i=0;i<end;i++){
tempArray[i+1] = deque[i];
}
deque=tempArray;
}
deque[0] = inserted;
end++;
}
public void insertLast(EltType last) {
if (isFull()){
EltType[] tempArray;
capacity+=1;
tempArray = (EltType[]) new Object[capacity];
for (int i=0;i<end;i++) {
tempArray[i] = deque[i];
}
// System.out.print(deque[end]);
}
deque[end] = last;
end++;
}
public EltType removeFirst() {
EltType[] tempArray;
EltType returned = deque[0];
tempArray = (EltType[]) new Object[capacity];
for (int i=1;i<capacity;i++) {
tempArray[i-1] = deque[i];
}
deque = tempArray;
end--;
return returned;
}
public EltType removeLast() {
EltType[] tempArray;
EltType returned = deque[end-1];
tempArray = (EltType[]) new Object[capacity];
for (int i=0;i<capacity;i++) {
tempArray[i] = deque[i];
}
deque = tempArray;
end--;
return returned;
}
}
A few comments:
I would use T or E as the name of the type parameter, rather than EltType
I'd rename the constant CAPACITY to DEFAULT_CAPACITY, and make it static.
first() will return a value even if the deque is logically empty
last(), removeLast() and removeFirst() should throw an appropriate exception if end is 0
There's no point in having a capacity separate from the size unless you're using that to avoid creating a new array each time. If you're always going to expand/shrink the array on any change, just use the array on its own - you can tell the size just from the array's length
In removeFirst and removeLast your loop bound is capacity instead of end
Use System.arraycopy as a simpler way to copy arrays
You haven't got an assignment to deque in insertLast - hence the exception you're seeing in the comments.
I'm not sure I see the benefit of having this over just using ArrayList<T> though... the main point of having a separate Deque implementation would be to make adding to both head and tail cheap... here we have neither!
... or of course just use ArrayDeque or LinkedList :)
I would suggest
don't create a new Object[] every time you add or remove an entry.
Use System.arrayCopy() instead of manual copy.
You don't need to copy up to the capacity, only up to the end.
you could use a ring buffer to avoid needing to move elements around (no need for copies)
Drop Based from the name ArrayDeque is more consistent with ArrayList, ArrayBlockingQueue, etc.

Categories