Building a bag class in Java - java

I'm in dire need of help with this project. I'm trying to implement a Bag class for a programming assignment, and I'm getting hung up on the addAll(), Union(), and equals(), methods.
Edit: According to the assignment, addAll() is supposed to add all of the the objects from the second array into the first. I'm no longer getting an error when I run it, but for some reason it will not add all of the elements from the second array, it will only add the first 2. Thanks guys, this one is working perfectly now!
Edit: For Union(), I'm supposed to create a third bag that will contain all the contents of the first 2 bags. I was getting an ArrayIndexOutOfBoundsException when running this method. I've updated the code following biddulph.r and it's also working great. Thanks again!
Edit: "First attempt" And for equals(), it's supposed to check the size of the bags to make sure they are equal in size, then check to see if they contain the same numbers. So as it's written now, my equals() method will compare sizes and return the boolean value for that, but I'm unsure of how to make it compare the actual values.
import java.util.Arrays;
import javax.swing.*;
public class bag {
int maxSize = 10; //Size of the arrays
int count = 0; //Number of items stored in the array
int[] a;
int[] b;
bag c;
bag d;
public bag() {
//for(int i = 0; i < maxSize; i++){
//a[i] = (int)(1+Math.random()*100);
//}
a = new int[maxSize];
}
public String bagString() {
return Arrays.toString(a);
}
public void add(int b) {
try {
a[count] = b;
count++;
} catch (ArrayIndexOutOfBoundsException n) {
JOptionPane.showMessageDialog(null, "Array is full, element will not be added");
}
}
public void removeRandom() {
int i = (int)(1 + Math.random() * (count - 1));
a[i] = a[count - 1];
a[count - 1] = 0;
count--;
}
public void remove(int b) {
for (int i = 0; i < maxSize; i++) {
if (contains(b)) {
a[i] = a[count - 1];
}
}
}
public boolean isEmpty() {
if (count == 0) return true;
else return false;
}
public boolean contains(int b) {
int tf = 0;
for (int i = 0; i < maxSize; i++) {
if (a[i] == b) tf = 1;
}
if (tf == 1) return true;
else return false;
}
public int size() {
return count;
}
public void addAll(bag c, bag d) {
if (a.length >= c.size() + d.size()) {
for (int i = 0; c.size() <= d.size(); i++) {
c.add(d.a[i]);
}
}
}
public void union(bag c, bag d) {
bag bigger = new bag();
for (int i = 0; i < c.size(); i++) {
bigger.add(c.a[i]);
}
for (int i = 0; count < d.size() - 1; i++) {
bigger.add(d.a[i]);
}
System.out.println(bigger.bagString());
}
public boolean equals(bag c, bag d){
if(c.size() != d.size()){
return false;
}else{
for(int i = 0; i < c.union(c, d).size(); i++){
if(c.union(c, d).contains(c.a[i]) && c.union(c, d).contains(d.a[i])){
return true;
}
}
return false;
}
}
}
I really appreciate any help you guys can give me, thanks.
EDIT: Thanks to everyone for your help, you guys are life savers.

Your problem for addAll() is here
if (a.length >= c.size() + d.size()) {
for (int i = 0; c.size() <= d.size(); i++) {
c.add(d.a[i]);
}
}
You shouldn't be adding elements until your c bag becomes bigger than d, you should be adding all of d's elements to c.
for (int i = 0; i < d.size(); i++) {
c.add(d.a[i]);
}

So the part of the assignment you are having issue with is:
public void addAll(bag c, bag d){
if (a.length >= c.size() + d.size()) {
for (int i = 0; c.size() <= d.size(); i++) {
c.add(d.a[i]);
}
}
}
which you say is supposed to add all of the the objects from the second array into the first.
If you break that down and apply it to your addAll() method, it sounds like you are supposed to be adding all of the items in bag "d" into bag "c".
Your for loop is saying start i at 0, and add 1 to it until the size of c is less than or equal to d.
What it should be saying is start i at 0, and add 1 to it until you have gone through every item in d.
That would look like this:
for (int i = 0; i < d.size(); i++){
c.add(d.a[i]);
}
i is increased every time you go through the for loop, and i will stop increasing when you have got to the size of d (the second condition). At this point you will exit the for loop. You don't have to worry about the size of c.
In fact you can probably get rid of the if (a.length >= c.size() + d.size()) line as well.
I hope my explanation helps you understand why the changes have been made to the method.

I think you have a lot of problems with the design of the class that you should address first. If you are representing the bag as a static or dynamic array then you only need one array, not 2. You also don't need two bags inside each bag as attributes, that doesn't make any sense; all you should have left is the size of the bag or count and the array to hold all the elements (which are integers in your case). Also, avoid naming parameters for functions and attributes for the class the same way. Not doing so might confuse the compiler and will require code like self.attributeName to use attributes; otherwise, the compiler assumes you're talking about the parameter.
If you make these changes, the rest should be straight-forward from here. Since it's an assignment, you should make these changes and try again because you won't learn if we provide the answers for you; you'll see it will be much easier once you structure it correctly.
P.S. it's a convention to start a class name with a capital letter. Bag and not bag

addAll
There's a couple of problems with this function as written. First is that it's confusing to the caller. The code using this method would be something like this:
Bag bag1 = ...
Bag bag2 = ...
Bag bag3 = ...
bag1.addAll(bag2, bag3)
...or perhaps bag2.addAll(bag2, bag3). The function is intended to add elements from one bag in to another bag, so why does the caller have to specify three different bags? There's only two involved. You should either make the function static, so it can be called like Bag.addAll(bag1, bag2) or (better) make it totally clear who's getting elements added by making it take a single argument bag1.addAll(bag2).
Second problem is that the function isn't implemented correctly, but I think that's because you're getting confused because you've got three bags involved instead of two. To sketch out how it should be fixed:
Bag target = ...
Bag source = ...
if (target.a.length >= target.size() + source.size()) {
for (int i = 0; i < source.a.length; i++) {
target.add(source.a[i]);
}
}
Good variable naming is your friend.
union
You haven't specified what problem you're having with your implementation, so I'm not going to simply rewrite it for you. Edit your question with the problem, and I'll help.
However, this is an excellent example of a method that should be static (a Factory method, in fact). It should be able ot be called like: Bag biggerBag = Bag.union(bag1, bag2).
EDIT after his comment regarding the .union problem
The problem with .union is that you're looping through each bag using some else's size. It boils down to, if you want add each element from source in to target, you should be only counting elements from source, as so:
bag bigger = new bag();
for (int i = 0; i <= c.size(); i++) {
bigger.add(c.a[i]);
}
note that your method does not protect against the bigger bag not being big enough. You should have a check to make sure that it is BEFORE the loops, or even better just create a big enough bag.
equals
Again, you need to show that you've tried to write it, and then ask a question specifying what you need help with. Update your question and I'll help.

Your method:
public void addAll(bag c, bag d) {
if (a.length >= c.size() + d.size()) {
for (int i = 0; c.size() <= d.size(); i++) {
c.add(d.a[i]);
}
}
}
betrays your lack of understanding of Object Oriented programming.
Remember that the method addAll() is already acting on a bag, and so you should not need to specify 2 bags in the arguments.
Calling example:
mybag.addAll(yourBag);
would demonstrate a possible usage - it would add all contents of yourBag into myBag.
I'll give you this method for free (assuming that the array 'a' contains the contents of the bag - something I'm not sure about because your variable names aren't clear):
public void addAll(Bag otherBag) {
for (int i : otherBag.a) {
add(i);
}
}
The above method will copy all contents of otherBag into this bag.
Another thing I noticed - you also have a b[] instance variable - what's that for?
You also have 2 other bag instance variables. Not sure why.

Related

Remove same subnet proxies from text file

I want to remove same subnet proxies from a text file.
txt.file= proxy.txt
19.15.15.90:61234
19.15.15.29:28010
19.15.15.80:8998
19.15.15.102:8998
25.25.24.15:8998
25.25.24.80:8998
210.192.38.25:8998
210.192.38.29:8998
I need output be
19.15.15.90:61234
25.25.24.15:8998
210.192.38.25:8998
It doesn't matter which proxies are removed, I just needs to keep 1 from each subnet.
subnet= first 3 numbers the same.
One potential solution1 is to add all the items to a List, sort the list, and then iterate over the list checking if the first n characters are the same as the previous entry, and if not, print it.
First, we'd need to get the third index of . in this scenario2:
public static int nthIndexOf(String text, char needle, int n) {
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == needle) {
n--;
if (n == 0) {
return i;
}
}
}
return -1;
}
Then simply perform the iteration as mentioned above:
for (int i = 1; i < list.size(); i++) {
int pos = nthIndexOf(list.get(i), '.', 3);
if (!list.get(i).substring(0, pos).equals(list.get(i - 1).substring(0, pos))) {
System.out.println(list.get(i));
}
}
Oh, and just print the first entry too, as it's going to be unique, considering it hasn't been compared to anything yet.
Of course, I am just printing System.out.println(list.get(i));, but do whatever is necessary with it there.
Example
1There may be edge cases I've missed, but that's up to you to check
2Credit where credit is due

Calculating the factorial of every element in an integer array

I need to create a Method that has 2 parameters in Java, upperborder and lowerborder. This method must create an array from the number 2 to the number 10.
Then I must implement another method, that calculates the factorial for a given number.
Then I must implement a third method that calculates the factorial for every element in the created array and test all these methods in a TestClass.
I know how to do this, but apparently I'm making some kind of a mistake in my code and it gives me the StackOverflow exception. I read the code a couple of times, but I can't seem to quite understand where I'm wrong.
package fakultaetinarray;
public final class FakultaetinArray{
private int i;
private int[] a;
private int j;
public FakultaetinArray(){
System.out.println("Given array : ");
createArray(1, 9);
System.out.println("Factorial for every element : ");
FakinArray();
}
public int fakRe(int n){
if(n == 1){
return n;
}
return n * fakRe(n - 1);
}
public void createArray(int untergrenze, int obergrenze){
this.a = new int[obergrenze];
for(this.j = 1; j <= a.length; j++){
a[i] = j + 1;
System.out.println(a[i]);
}
}
public void FakinArray(){
a[0] = 2;
for(i = 1; i < a.length; i++){
int fak = fakRe(a[i]);
a[i] = fak;
System.out.println(fak);
}
}
}
The reason you're getting StackOverflowErrors is due to your recursive method not having a case when n == 0.
The reason that your values are coming in as 0 is due to how you're constructing your loop.
for(this.j = 1; j <= a.length; j++){
a[i] = j + 1;
System.out.println(a[i]);
}
It's unclear why you're using j here at all, and i is initialized to its default value of 0, so in all reality, you're only ever filling one element of your array with a positive value and all of the others are at zero.
You need to reconsider how your loops are constructed. I would strongly encourage you not to make them fields, but declare them as part of the loop construct instead.
if(n == 1){ is not a strong enough condition to block the recursion: n can go below 1. In your particular case, you have a situation where n is 0.
Consider unwinding the recursion to a simple loop in any case. As a rule of thumb, recursion is not good for O(N) stuff.

How do I count how many negative elements are in a circular doubly linked list?

I would like to use list.negativeNumbers(); to call out the part of a code, which counts how many negative numbers are in a list.
public void negativeNumbers(){
int negative = 0;
for (int i = 0; i <= size; i++){
if (i < 0) {
negative = negative + 1;
}
System.out.println("There are "+ negative +" negative elements in the list!");
}
}
Can you help me in creating a method, that could count negative numbers in the list the correct way?
public void negativeNumbers(){
int negative = 0;
for (int i = 0; i <= size; i++){
if (i < 0) {
negative = negative + 1;
}
System.out.println("There are "+ negative +" negative elements in the list!");
}
}
You will learn better by working out the solution for yourself.
Your code as presented is a good start but lacks:
a defined list of values to test.
a definition of the size of the list (use list.size()).
proper indexing of the list to access values to test (use list.get(i) or list[i]).
a test of each element in the list to determine its negativity. Your code tests whether the list increment variable is < 0.
negative = negative + 1 is ok, but simpler to write ++negative.
Here's a simple example:
import java.util.ArrayList;
public class negnum {
public static void main(String [] args) {
ArrayList<Integer> nums = new ArrayList();
nums.add(0);
nums.add(10);
nums.add(-10);
nums.add(20);
nums.add(-20);
nums.add(30);
nums.add(-30);
nums.add(40);
nums.add(-40);
nums.add(50);
int negs = 0;
for (int i = 0; i < nums.size(); i++){
int n = nums.get(i);
if (n < 0) {
++negs;
System.out.println(n);
}
}
System.out.println(negs +" negatives");
}
}
c:\dev>java negnum
-10
-20
-30
-40
4 negatives
If it is a list of integers you should not be doing "i < 0" but rather the number at index of i. If you were to do that, you would also want to do "< size" rather than "<= size" or else you would run into an IndexArrayOutOfBounds.
It depends on how your double linked list is implemented, but if it extends the normal List<Integer> interface it would look like:
final Integer ZERO = Integer.valueOf(0);
int countNegativeElements() {
return stream().filter(MyList::isNegative).count();
}
static boolean isNegative(Integer i) {
return i.compareTo(ZERO) < 0;
}
with streams. More traditionally with an collection for-each (or an iterator for-each):
int countNegativeElements() {
int count = 0;
for(Integer i : this) { // or iterator()
if (isNegative(i)) count++;
}
return count;
}
This does not expect concurrent modifications and is optimized for collections where iterating is the fastest access. If you have a simple type list then you can replace isNegative with a simple < 0.
This article here talks about different ways to iterate a collection.
In my code I assumed you will add the method directly to your list implementation class. Replace this or this.iterator() or this.stream() with your actual list instance if it is external.
Update:
I just saw your link to the actual linked list you are using, this would look like this (hand made iteration):
int countNegativeElements() {
Node n = start;
int count = 0;
while(n != null) {
if (n.getData() < 0) count++;
n = n.getLinkNext();
}
return count;
}
Using null since there is no hasLinkNext() which would be typical for homework :)
I don't think it is a particular good idea to work with implementations which do not fit in the Collections framework, but maybe it is required to keep the lessons simple.

How would you check if all integers in a 2d array are unique?

I am looking to verify if all of the integers in a 2d array are unique, return true if they are unique otherwise false.
The below code is what I have for a simple array. But I am not sure how to go about modifying it.
public boolean verifyUniqueIntegers(int array []){
boolean result = true;
for (int i = 0; i < array.length; i++) {
if(array[i] <= 0 || array[i] > n*n){
result = false;
}
for (int j = 0; j < i; j++)
if (array[i] == array[j]) {
result = false;
}
}
return result;
}
The best way to approach this problem is to use a mathematical construct called a set. The key property of a set for your purposes is that they can not contain duplicates by definition. Java provides a data structure allowing us to create sets found in java.util.Set. This is the generic interface that specifies how sets should behave. However, interfaces provide only specification, not implementation, so you'll have to use Set in conjunction with another class java.util.HashSet, which implements Set. You seem like a novice programmer, so I wrote a test program to show you how this works.
import java.util.*;
public class SetTest {
public static void main(String[] args) {
int[] set = {1,2,3,4,5,6,7};
int[] nonSet = {1,2,3,4,5,4};
System.out.println(verifyUniqueIntegers(set));
System.out.println(verifyUniqueIntegers(nonSet));
}
public static boolean verifyUniqueIntegers(int[] array) {
Set<Integer> set = new HashSet<Integer>();
for(int i : array) // This is a construction called a for-each loop
if(!set.add(i)) // This is an example of what's called autoboxing
return false;
return true;
}
}
Here I've used a static method for convenience, but you can of course change this into an instance method for your purposes once you give it a try.
First, I create a for-each loop to iterate over all the elements in the array that's passed into verifyUniqueIntegers(). For each loops use what are called iterators to create a reference to each element, one at a time, and make it available in the body of the loop. When the end of the body is reached, the for-each loop automatically resets i to the next element in the array, as long as there are elements left in the arry. You can ready more about for-each loops in the Oracle Java Tutorials.
Then, the method calls set.add(i). This attempts to add i to the set that we previously defined. This is an example of what's called autoboxing. Since the Set interface is generic, it can contain elements of any object type. Since int is a primitive, we must use the wrapper class Integer to specify the elements in our set. When we call set.add(i) you don't have to convert the int into an Integerbecause the java compiler does it for you.
This method returns true if i is not a duplicate, then adds it to the Set. It returns false if i is a duplicate and does nothing. Thus, we can take advantage of the method check the uniqueness of each element in your array. The method returns false as soon as a duplicate is found, and otherwise returns true. Hope this helps, good luck!
Your algorithm is slow. To make it faster, you should use something like HashMap.
Create empty HashMap<Integer>.
Iterate on all 2d-array elements (for-for loop).
For every element check if your HashMap contains it.
If yes then return false, it means that not all elements in your array are unique.
If no, add element to HashMap.
After for-for loop return true.
As a beginning programmer, choose basic solutions without the sophistication of more complex parts of the library that do in truth offer more power. The main thing for you here is to learn how to use 2D arrays.
You can do it very simply because of the hidden specification that you did not mention but is in the code. None of the numbers can be greater than N * N.
Start with pseudo-code. The basic algorithm is to have a checking array of length N * N. Put a marker in each element as you find the number in the source array, using the number as the index into the checking array. If there is already an element there, then the number is not unique. The code becomes something like this:
final int N = 10; // Your choice of N, or perhaps input it.
int [][] needsChecking = new int [N] [N]; // fill it up.
public boolean arrayIsGood (int [][] src) {
final int N2 = N * N;
boolean [] checker = new boolean [N2];
for (int i = 0; i < N2; i++) { // Initialize Checker
checker [i] = false;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int value = src [i][j];
if ((value <= 0) || (value > N2))
return false;
if (checker [value - 1]) // already found
return false;
checker [value - 1] = true;
} // for j
} // for i
return true; // if we get here every element has passed.
} // arrayIsGood (int [][])
Some of the other answers are more elegant or more extensible or handle space usage better or may find the result faster, etc. But master the basics first.
public boolean verifyUniqueIntegers(int array []){
Set<Integer> set = new HashSet<>(array.length);
for (int i : array)
{
if (set.contains(i))
return false;
set.add(i);
}
return true;
}
or maybe:
public boolean verifyUniqueIntegers(Integer array []){
return new HashSet<>(Arrays.asList(array)).size() == array.length;
}

A Sorted Integer List

So the original code is
// An (unsorted) integer list class with a method to add an
// integer to the list and a toString method that returns the contents
// of the list with indices.
//
// ****************************************************************
public class IntList {
private int[] list;
private int numElements = 0;
//-------------------------------------------------------------
// Constructor -- creates an integer list of a given size.
//-------------------------------------------------------------
public IntList(int size) {
list = new int[size];
}
//------------------------------------------------------------
// Adds an integer to the list. If the list is full,
// prints a message and does nothing.
//------------------------------------------------------------
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
list[numElements] = value;
numElements++;
}
}
//-------------------------------------------------------------
// Returns a string containing the elements of the list with their
// indices.
//-------------------------------------------------------------
public String toString() {
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
}
and
// ***************************************************************
// ListTest.java
//
// A simple test program that creates an IntList, puts some
// ints in it, and prints the list.
//
// ***************************************************************
import java.util.Scanner ;
public class ListTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
IntList myList = new IntList(10);
int count = 0;
int num;
while (count < 10) {
System.out.println("Please enter a number, enter 0 to quit:");
num = scan.nextInt();
if (num != 0) {
myList.add(num);
count++;
} else {
break;
}
}
System.out.println(myList);
}
}
I need to change the add method to sort from lowest to highest. This is what I tried doing.
// An (unsorted) integer list class with a method to add an
// integer to the list and a toString method that returns the contents
// of the list with indices.
//
// ****************************************************************
public class IntList {
private int[] list;
private int numElements = 0;
//-------------------------------------------------------------
// Constructor -- creates an integer list of a given size.
//-------------------------------------------------------------
public IntList(int size) {
list = new int[size];
}
//------------------------------------------------------------
// Adds an integer to the list. If the list is full,
// prints a message and does nothing.
//------------------------------------------------------------
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
list[numElements] = value;
numElements++;
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
list[i] = value;
break;
}
}
}
for (in i = 0; i < list.length; i++) {
}
}
}
//-------------------------------------------------------------
// Returns a string containing the elements of the list with their
// indices.
//-------------------------------------------------------------
public String toString() {
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
}
The outcome is very wrong. Any one able to steer me in the right direction? I can sort of see why what I have doesn't work, but I can't see enough to fix it.
So I realize I was not very descriptive here the first time. With the exception of the add method modifications the code was not my doing. My assignment is to only touch the add method to sort the array to print out smallest to largest. This is a beginners class and we do little to no practice my only tools for this are some basic understandings of loops and arrays.
I tried redoing it again and came up with this:
if(list[numElements-1] > value){
for(int i=0; i<numElements; i++){
if(list[i]>value){
for(int j = numElements; j>i; j-- ){
list[j] = list[j-1];
}
list[i] = value;
break;
}
}
numElements++;
}
else
{
list[numElements] = value;
numElements++;
}
my input was:8,6,5,4,3,7,1,2,9,10
the output was: 1,10,1,9,10,1,1,2,9,10
this thing is kicking my butt. I understand I want to check the input number to the array and move all numbers higher than it up one space and enter it behind those so it is sorted on entry, but doing so is proving difficult for me. I apologize if my code on here is hard to follow formatting is a little odd on here for me and time only allows for me to do my best. I think break is not breaking the for loop with i like i thought it would. Maybe that is the problem.
The biggest bug I see is using list.length in your for loop,
for(int i = 0; i <list.length; i++)
you have numElements. Also, I think it's i that needs to stop one before like,
for(int i = 0; i < numElements - 1; i++)
and then
for (int j = numElements; j > i; j--)
There are two lines that have to be moved out of the inner loop:
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
// list[i] = value;
// break;
}
list[i] = value;
break:
}
}
In particular, the inner break means that the loop that is supposed to move all larger elements away to make room for the new value only runs once.
You might want to include Java.util.Arrays which has its own sort function:
http://www.tutorialspoint.com/java/util/arrays_sort_int.htm
Then you can do:
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
}
else {
list[numElements] = value;
numElements++;
Arrays.sort(list);
//Or: Java.util.Arrays.sort(list);
}
}
As Eliott remarked, you are getting confused between list.length (the capacity of your list) and numElements (the current size of your list). Also, though, you do not need to completely sort the list on each addition if you simply make sure to insert each new element into the correct position in the first place. You can rely on the rest of the list already to be sorted. Here's a simple and fast way to do that:
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
int insertionPoint = Arrays.binarySearch(list, 0, numElements);
if (insertionPoint < 0) {
insertionPoint = -(insertionPoint + 1);
}
System.arrayCopy(list, insertionPoint, list, insertionPoint + 1,
numElements - insertionPoint);
list[insertionPoint] = value;
numElements += 1;
}
}
That will perform better (though you may not care for this assignment), and it is much easier to see what's going on, at least for me.
Here are some hints.
First, numElements indicates how many elements are currently in the list. It's best if you change it only after you have finished adding your item, like the original method did. Otherwise it may confuse you into thinking you have more elements than you really do at the moment.
There is really no need for a nested loop to do proper adding. The logic you should be following is this:
I know everything already in the list is sorted.
If my number is bigger then the biggest number (which is the one indexed by numElements-1, because the list is sorted) then I can just add my number to the next available cell in the array (indexed by numElements) and then update numElements and I'm done.
If not, I need to start from the last element in the array (careful, don't look at the length of the array. The last element is indexed by numElements-1!), going down, and move each number one cell to the right. When I hit a cell that's lower than my number, I stop.
Moving all the high numbers one cell to the right caused one cell to become "empty". This is where I'm going to put my number. Update numElements, and done.
Suppose you want to add the number 7 to this array:
┌─┬──┬──┬─┬─┐
│3│14│92│-│-│
└─┴──┴──┴─┴─┘
⬆︎ Last element
You move everything starting from the last element (92) to the right. You stop at the 3 because it's not bigger than 7.
┌─┬─┬──┬──┬─┐
│3│-│14│92│-│
└─┴─┴──┴──┴─┘
(The second element will probably still contain 14, but you're going to change that in the next step so it doesn't matter. I just put a - there to indicate it's now free for you to enter your number)
┌─┬─┬──┬──┬─┐
│3│7│14│92│-│
└─┴─┴──┴──┴─┘
⬆︎ Updated last element
This requires just one loop, without nesting. Be careful and remember that the array starts from 0, so you have to make sure not to get an ArrayIndexOutOfBoundsException if your number happens to be lower than the lowest one.
One problem I spotted is that: you are trying to insert the newly added number into the array. However your loop:
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
list[i] = value;
break;
}
}
}
is always looped through the total length of the array, which is always 10 in your test, rather than the actual length of the array, i.e. how many numbers are actually in the array.
For example, when you add the first element, it still loops through all 10 elements of the array, although the last 9 slots does not have value and are automatically assigned zero.
This caused your if statement always returns true:
if (list[i] > value)
if you have to write the sort algorithm yourself, use one of the commonly used sorting algorithm, which can be found in Wikipedia.
If any one was curious I finally worked it out. Thank you to everyone who replied. This is what i ended up with.
public void add(int value)
{
if(numElements == 0){
list[numElements] = value;
numElements++;
}
else{
list[numElements] = value;
for(int check = 0; check < numElements; check++){
if(list[check] > value){
for(int swap = numElements; swap> check; swap--){
list[swap] = list[swap-1];
}
list[check] = value;
break;
}
}
numElements++;
}
}
so my original is the same but we have to make another class
A Sorted Integer List
File IntList.java contains code for an integer list class. Save it to your project and study it; notice that the only things you can do are create a list of a fixed size and add an element to a list. If the list is already full, a message will be printed. File ListTest.java contains code for a class that creates an IntList, puts some values in it, and prints it. Save this to your folder and compile and run it to see how it works.
Now write a class SortedIntList that extends IntList. SortedIntList should be just like IntList except that its elements should always be in sorted order from smallest to largest. This means that when an element is inserted into a SortedIntList it should be put into its sorted place, not just at the end of the array. To do this you’ll need to do two things when you add a new element:
Walk down the array until you find the place where the new element should go. Since the list is already sorted you can just keep looking at elements until you find one that is at least as big as the one to be inserted.
Move down every element that will go after the new element, that is, everything from the one you stop on to the end. This creates a slot in which you can put the new element. Be careful about the order in which you move them or you’ll overwrite your data!
Now you can insert the new element in the location you originally stopped on.
All of this will go into your add method, which will override the add method for the IntList class. (Be sure to also check to see if you need to expand the array, just as in the IntList add() method.) What other methods, if any, do you need to override?
To test your class, modify ListTest.java so that after it creates and prints the IntList, it creates and prints a SortedIntList containing the same elements (inserted in the same order). When the list is printed, they should come out in sorted order.

Categories

Resources