i am trying to create method named split that divides a list into 2 lists according to a key. If list_1 and list_2 are the resulting lists, list_1 should contain all the items of the original list whose keys are less than or equal to the key passed and list_2 should contain all the items of the original list whose keys are larger than the key passed. I will post my code so far and what other people have suggested
public class UnorderedArrayList extends ArrayListClass {
public UnorderedArrayList() {
super();
}
public UnorderedArrayList(int size) {
super(size);
}
//Bubble Sort
public void bubbleSort() {
for (int pass = 0; pass < length - 1; pass++) {
for (int i = 0; i < length - 1; i++) {
if (list[i] > list[i + 1]) {
int temp = list[i];
list[i] = list[i + 1];
list[i + 1] = temp;
}
}
}
}
//implementation for abstract methods defined in ArrayListClass
//unordered list --> linear search
public int search(int searchItem) {
for(int i = 0; i < length; i++)
if(list[i] == searchItem)
return i;
return -1;
}
public void insertAt(int location, int insertItem) {
if (location < 0 || location >= maxSize)
System.err.println("The position of the item to be inserted is out of range.");
else if (length >= maxSize)
System.err.println("Cannot insert in a full list.");
else {
for (int i = length; i > location; i--)
list[i] = list[i - 1]; //shift right
list[location] = insertItem;
length++;
}
}
public void insertEnd(int insertItem) {
if (length >= maxSize)
System.err.println("Cannot insert in a full list.");
else {
list[length] = insertItem;
length++;
}
}
public void replaceAt(int location, int repItem) {
if (location < 0 || location >= length)
System.err.println("The location of the item to be replaced is out of range.");
else
list[location] = repItem;
}
public void remove(int removeItem) {
int i;
if (length == 0)
System.err.println("Cannot delete from an empty list.");
else {
i = search(removeItem);
if (i != -1)
removeAt(i);
else
System.out.println("Cannot delete! The item to be deleted is not in the list.");
}
}
public void merge(UnorderedArrayList list2,UnorderedArrayList list1){
int num=0;
for(int j=0; j<list1.length;j++){
num= list1.retrieveAt(j);
insertEnd(num);
}
for(int i=0; i<list2.length-1;i++){
num=list2.retrieveAt(i);
insertEnd(num);
}
}
public void split(UnorderedArrayList list2, UnorderedArrayList list1, UnorderedArrayList list, int item){
int listItem = item;
while(!list.isEmpty()){
list.retrieveAt(listItem);
if(listItem>item){
if(!list2.isFull()){
list2.insertAt(listItem);
}
}
}
}
//what i got so far from the internet
/* void UnsortedType::SplitLists(ItemType item, UnsortedType& list1, UnsortedType& list2){
ItemType listItem;
list.ResetList();
while ( !list.IsLastItem()) {
list.GetNextItem(listItem);
if(listItem > item) {
if (!list2.IsFull())
list2.InsertItem(listItem);
}
else {
if ( !list1.IsFull())
list1.InsertItem(listItem);
} }}
*/
You have a lot of code, most unrelated to your requirement. Given the list and the key, I would simply:
create the two result lists
iterate through the original list, copying the element to one of the result lists depending on its value relative to key
return the two result lists
That's all you need.
Had this same problem. You will want to clear the two lists you have already done away with(list1 and list2) so that they are available to receive values. Look at the following code I put together, which worked in my program, as a guide. For the method call in your client, your parameters should be: (list_1, list_2, result, split) . Your new lists will be available to you in the client in accordance with their names there.
public void split(UnorderedArrayList list1, UnorderedArrayList list2, UnorderedArrayList list3, int key) {
int num = 0;
list1.clearList();
list2.clearList();
for(int x = 0; x < list3.length; x++) {
num = list3.retrieveAt(x);
if(num <= key)
list1.insertEnd(num);
else
list2.insertEnd(num);
}
}
Hope this helps.
Related
I wrote this function to insert an element into a sorted array such that array would still be sorted after adding the element.
But something is wrong. I know that my code has a lot of edge cases and probably I'm over complicating the algorithm but I really want to fix it.
My Code :
private static <E> void insert(E e, E[] arr, int count, Comparator<E> comp) {
if (count == 0) arr[0] = e;
for (int i = 0; i < count; i++) {
if (comp.compare(arr[i], e) >= 0) {
// we found an element that is >= to e
// we want to add new element at index i, currently arr[i] is occupied
// by larger element, so we need to adjust
if (i != 0) {
i--;
} else {
// do nothing
}
} else if (i + 1 == count) {
// this is the last iteration of the loop so we want to add element at i + 1
i++;
} else {
// keep looping to find an element
continue;
}
// we need to move elements to the right to make space
for (int j = count; j > i; j--) {
arr[j] = arr[j - 1];
}
arr[i] = e;
break;
}
}
My repo
I fixed the code, I should have not decremented i
private <E> void insert(E e, E[] arr, int count, Comparator<E> comp) {
if (count == 0) {
arr[0] = e;
return;
}
for (int i = 0; i < count; i++) {
if (comp.compare(arr[i], e) >= 0) {
// we found an element that is >= to e
// we want to add new element at index i, currently arr[i] is occupied
// by larger element, so we need to adjust
} else if (i + 1 == count) {
// this is the last iteration of the loop so we want to add element at i + 1
i++;
} else {
// keep looping to find an element
continue;
}
// we need to move elements to the right to make space
for (int j = count; j > i; j--) {
arr[j] = arr[j - 1];
}
arr[i] = e;
break;
}
}
I am writing a bin packing program in one dimension. I want only one possible bin. So it does not include a lot of bin its only one. This program is only searching quad groups and explode if quad groups are not equal to the searching number. I want to search every possible group that is bigger than quads.
In example we have 60 60 50 40 45 35 25 15 and we are looking for summing equal to 180 and answer is 60 60 45 15 that's fine but if we search 250 it will not working.
Can you help me?
That's the link for program https://github.com/omerbguclu/BinPacking1D
That's the code for the algorithm o array is the numbers, a array is the location of answers
public BinPacking() {
}
public void binpack(ArrayList<Integer> o, ArrayList<Integer> a, int wanted) {
int sum = 0;
if (wanted > 0) {
control(o, a, wanted);
if (is) {
return;
}
for (int i = 0; i < o.size(); i++) {
sum += o.get(i);
summing(o, a, wanted - sum, i + 1);
if (is) {
a.add(i);
return;
}
for (int j = i; j < o.size(); j++) {
if (i != j) {
sum += o.get(j);
summing(o, a, wanted - sum, j + 1);
if (is) {
a.add(i);
a.add(j);
return;
}
sum -= o.get(j);
}
}
sum -= o.get(i);
// "/////////////*******************////////////////////");
}
if (wanted != sum) {
System.out.println("There is not an answer with quad summing method");
}
}
}
public void summing(ArrayList<Integer> o, ArrayList<Integer> a, int wanted, int loop) {
int sum = 0;
if (loop < o.size() && wanted > 0) {
for (int i = loop; i < o.size(); i++) {
if (wanted == o.get(i)) {
a.add(i);
is = true;
return;
}
for (int j = loop; j < o.size(); j++) {
if (i != j) {
sum = o.get(i) + o.get(j);
if (wanted != sum) {
sum = 0;
} else {
a.add(i);
a.add(j);
is = true;
return;
}
}
// System.out.println("///////////////////////////////////");
}
}
System.out.println("There is not an answer with binary summing method");
}
}
public void control(ArrayList<Integer> o, ArrayList<Integer> a, int wanted) {
for (int i = 0; i < o.size(); i++) {
if (o.get(i) == wanted) {
a.add(i);
is = true;
break;
}
}
}
There is a pretty well established and efficient mechanism for getting every possible combination of a set of objects. Essentially you treat membership of the combination as a BitSet which represents whether each member of the set is in the combination. Then visiting every combination is just visiting every BitSet combination.
Here's how I tend to implement it:
public class Combo<T> implements Iterable<List<T>> {
private final List<T> set;
public Combo(List<T> set) {
this.set = set;
}
public Iterator<List<T>> iterator() {
BitSet combo = new BitSet(set.size());
return new Iterator<List<T>>() {
public boolean hasNext() {
return combo.cardinality() < set.size();
}
public List<T> next() {
int i = 0;
while (combo.get(i))
combo.clear(i++);
combo.set(i);
return combo.stream().mapToObj(set::get).collect(Collectors.toList());
}
};
}
}
So your solution would become:
for (List<Integer> combo: new Combo<>(...)) {
if (combo.size >= 4 && combo.stream.reduce(0, Integer::sum) == total)
....
}
A hackier version of the same idea would be:
for (long l = 0; l < 1 << (input.size() - 1); l++) {
List<Integer> combo = BitSet.valueOf(new long[]{l}).stream()
.mapToObj(input::get).collect(Collectors.toList());
if (combo.stream().mapToInt(n -> n).sum() == total) {
System.out.println(combo);
}
}
Our instructor told us to add a max method to return the largest element on the list and write the definition of the method max, The problem is since it already have a maxListSize which returns the maximum size of the list do I need to put a a max method again?
public abstract class ArrayListClass {
protected int length;
protected int maxSize;
protected DataElement[] list;
public ArrayListClass(){
length = 0;
maxSize = 100;
list = new DataElement[maxSize];
}
public ArrayListClass(int size){
if(size < 0){
System.out.println("The array size must be positive. Creating an array of size 100...");
}else{
maxSize = size;
}
length = 0;
list = new DataElement[maxSize];
}
//copy constructor
public ArrayListClass(ArrayListClass otherList){
maxSize = otherList.maxSize;
length = otherList.length;
list = new DataElement[maxSize];
for(int j = 0; j < length; j++){
list[j] = otherList.list[j].getCopy();
}
}
public boolean isEmpty(){
return (length == 0);
}
public boolean isFull(){
return (length == maxSize);
}
/*
* method that returns the number of elements
* in the list
*/
public int listSize(){
return length;
}
/*
* method that returns the maximum size
* of the list
*/
public int maxListSize(){
return maxSize;
}
/*
* method that prints the elements of the list
*/
public void print(){
for(int index = 0; index < length; index++){
System.out.print(list[index].getCopy() + " ");
}
System.out.println();
}
/*
* method that determines whether an item is the
* same as the item in the list at the position
* specified by location
*/
public boolean isItemAtEqual(int location, DataElement item){
return (list[location].equals(item));
}
/*
* method that inserts insertItem in the list
* at the position specified by location
*/
public void insertAt(int location, DataElement insertItem){
if(location < 0 || location >= maxSize){
System.out.println("The position of the item to be inserted is out of range.");
}else{
if(length >= maxSize){
System.out.println("Cannot insert in a full list");
}else{
for(int index = length; index > location; index--){
list[index] = list[index-1];
}
list[location] = insertItem.getCopy();
length++;
}
}
}
public void insertEnd(DataElement insertItem){
if(length >= maxSize){
System.out.println("Cannot insert in a full list");
}else{
list[length] = insertItem.getCopy();
length++;
}
}
public void removeAt(int location){
if(location < 0 || location >= length){
System.out.println("The location of the item to be removed is out of range.");
}else{
for(int index = location; index < length; index++){
list[index] = list[index + 1];
}
list[length-1] = null;
length--;
}
}
/*
* method that retrieves the element from the list
* at the position specified by location
*/
public DataElement retrieveAt(int location){
if(location < 0 || location >= length){
System.out.println("The location of the item to be retrieved is out of range.");
return null;
}else{
return list[location].getCopy();
}
}
public void replaceAt(int location, DataElement repItem){
if(location < 0 || location >= length){
System.out.println("The location of the item to be replaced is out of range.");
}else{
list[location].makeCopy(repItem);
}
}
public void clearList(){
for(int index = 0; index < length; index++){
list[index] = null;
}
length = 0;
}
public void copyList(ArrayListClass otherList){
if(this != otherList){
for(int index = 0; index < length; index++){
list[index] = null;
}
maxSize = otherList.maxSize;
length = otherList.length;
list = new DataElement[maxSize];
for(int index = 0; index < length; index++){
list[index] = otherList.list[index].getCopy();
}
}
}
public abstract int seqSearch(DataElement searchItem);
public abstract void insert(DataElement insertItem);
public abstract void remove(DataElement removeItem);
public abstract void removeAll (DataElement removeAllItem);
}
I think you missunderstood the code you provide.
maxListSize() is actually the size of the largest array that can be built : the number of elements contained (it is simply a getter, giving the maxSize property).
Your instructor wants you to write a method giving the largest element contained in your array, regardless the size of your array. You have to define : "How can i say this element is larger than another element ?"
Then write your code and you are done.
Okay, this is probably going to come across as a really easy question, but honestly I'm new to coding and I've run up against a brick wall here. I need to insert a value into an array, shift the data to the right, and update the size of the array. The professor provided comments for us to structure our code around, and I've got most of it, but this last part is killing me. Can anyone help? Here's the code (the relevant portion is under //insert value and shift data...etc):
public class List {
// Declare variables
private int size = 0;
private int maxSize = 100;
private int[] data;
Scanner keyboard = new Scanner(System.in);
// constructors
public List() {
data = new int[maxSize];
}
public List(int maxSize) {
this.maxSize = maxSize;
data = new int[maxSize];
}
// methods
// Adds a value into the array and updates the size
public boolean add(int value) {
if (size == maxSize) {
System.out.println("Cannot add value since the list is full");
return false;
}
data[size] = value;
size++;
return true;
}
// add multiple values to the list obtained from the keyboard
public void addValues() {
// declare local variables
int count = 0;
System.out.println("Enter multiple integers separated by spaces");
String line = keyboard.nextLine();
Scanner scanLine = new Scanner(line);
try {
while (scanLine.hasNext()) {
data[size] = scanLine.nextInt();
count++;
size++;
}
} catch (ArrayIndexOutOfBoundsException aiobe) {
System.out.println("Only " + count + " values could be added before the list is full");
return;
} catch (InputMismatchException ime) {
System.out.println("Only " + count + " values could be added due to invalid input");
return;
}
}
// This will print all the elements in the list
public void print() {
System.out.println();
for (int i = 0; i < size; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
// This methods returns the index of the key value if found in the list
// and returns -1 if the key value is not in the list
public int find(int key) {
for (int i = 0; i < size; i++) {
if (data[i] == key) {
return i;
}
}
return -1;
}
// This methods deletes the given value if exists and updates the size.
public boolean delete(int value) {
int index = find(value);
if (index == -1) {
System.out.println("The specified value is not in the list");
return false;
}
for (int i = index; i < size - 1; i++) {
data[i] = data[i + 1];
}
size--;
return true;
}
// This methods inserts the value at the given index in the list
public boolean insertAt(int index, int value) {
// validate index value and insertability
if (index < 0 || index > size || size == maxSize) {
System.out.println("Invalid index or list is already full");
return false;
}
// insert value and shift data to the right and update the size
return true;
}
// This method removes the value at given index and shifts the data as needed
public boolean removeAt(int index) {
if (index >= 0 && index < size) {
for (int i=index+1; i<size; i++)
data[i-1] = data[i];
size--;
return true;
}
return false;
}
// This method sorts the values in the list using selection sort
public void sort() {
int temp;
for (int j=size; j>1; j--) {
int maxIndex = 0;
for (int i=1; i<j; i++)
if (data[maxIndex] < data[i])
maxIndex = i;
temp = data[j-1];
data[j-1] = data[maxIndex];
data[maxIndex] = temp;
}
}
}
I apologize if the code is structured really horribly as well, by the way, I was unsure how to format it on this site so it looked right.
// insert value and shift data to the right and update the size
// I think the size is globally declared right?
size++;
for(int i=size - 1; i < 0; i--) {
data[i] = data[i - 1];
}
data[index] = value;
If you have a max size there will also be a check for size <= maxSize. Hope it helps
Think below answer should help. As there is already a size check, no need to check it again
public boolean insertAt(int index, int value) {
// validate index value and insertability
if (index < 0 || index > 5) {
System.out.println("Invalid index or list is already full");
return false;
}
// insert value and shift data to the right and update the size
for(int i=index;i<size;i++) {
data[++i] = data[i];
}
data[index] = value;
return true;
}
public boolean insertAt(int index, int value) {
// validate index value and insertability
if (index < 0 || index > size || size == maxSize) {
System.out.println("Invalid index or list is already full");
return false;
}
// insert value and shift data to the right and update the size
for (int i=size - 1; i > index; i--)
data[i+1] = data[i];
data[index] = value
size++;
return true;
}
I'm having trouble with a bubbleSort method for my very unique homework assignment.
We are supposed to use a sorting method of our choice to sort, get this, a linked list of int arrays. Not an ArrayList not just a LinkedList. It works like a linked list but the each Node contains an array of a capacity of 10 ints.
I am stuck on the sorting method. I chose bubbleSort just because it was used in the last assignment and I felt most familiar with it. Any tips for a better sorting method to try would be considered helpful as well.
Here is my code:
public void bubbleSort() {
current = head; // Start at the head ArrayNode
for (int i = 0; i < size; i++) { // iterate through each ArrayNode
currentArray = current.getArray(); // get the array in this ArrayNode
int in, out;
for (out = size-1; out > 1; out--) { // outer loop (backwards)
for (in = 0; in < out; in++) { // inner loop (forwards)
if (currentArray[in] > currentArray[in+1]) // out of order?
swap(in, in+1); // swap them!
}
}
current.setArray(currentArray);
current = current.getNext();
}
}// End bubbleSort() method
// A helper method for the bubble sort
private void swap(int one, int two) {
int temp = currentArray[one];
currentArray[one] = currentArray[two];
currentArray[two] = temp;
} // End swap() method
This is a picture example of what I am supposed to be doing.
I have found a solution with selectionsort. There are a few test values, just run it to see it.
I can provide further information if needed.
import java.util.ArrayList;
import java.util.Random;
public class ArrayedListSort {
int listsize = 5; // how many nodes
int maxValue = 99; // the highest value (0 to this)
int nodeSize = 3; // size for every node
public static void main(String[] args) {
// run non static
new ArrayedListSort().runTest();
}
/**
* Log function.
*/
public void log(Object s) {
System.out.println(s);
}
public void logNoBR(Object s) {
System.out.print(s);
}
/**
* Output of list we have.
*/
public void logMyList(ArrayList<ListNode> listNode, String name) {
log("=== LOG OUTPUT " + name + " ===");
for ( int i=0; i < listNode.size(); i++) {
logNoBR(" node <" + i + ">");
logNoBR(" (");
for (int j=0; j < listNode.get(i).getSize(); j++) {
if ( j != (listNode.get(i).getSize()-1)) // if not last add ","
logNoBR( listNode.get(i).getValueAt(j) + "," );
else
logNoBR( listNode.get(i).getValueAt(j) );
}
log(")");
}
log("=====================================\n");
}
public void runTest() {
// create example List
ArrayList<ListNode> myList = new ArrayList<ListNode>();
// fill the nodes with random values
for ( int i = 0; i < listsize; i++) {
myList.add(new ListNode(nodeSize));
for (int j=0; j < nodeSize; j++) {
int randomValue = new Random().nextInt(maxValue);
myList.get(i).addValue(randomValue);
}
}
logMyList(myList, "myList unsorted"); // to see what we have
// now lets sort it
myList = sortListNode(myList);
logMyList(myList, "myList sorted"); // what we have after sorting
}
/**
* Selectionsort
*/
public ArrayList<ListNode> sortListNode(ArrayList<ListNode> myList) {
ArrayList<ListNode> retList = new ArrayList<ListNode>();
for ( int i = 0; i < listsize; i++) {
retList.add(new ListNode(nodeSize));
}
int lastSmallest = myList.get(0).getValueAt(0);
while ( !myList.isEmpty() ) {
int lastJ=0, lastI=0;
for ( int i = 0; i < myList.size(); i++) {
for (int j=0; j < myList.get(i).getSize(); j++) {
if ( myList.get(i).getValueAt(j) <= lastSmallest ) {
lastSmallest = myList.get(i).getValueAt(j);
lastJ = j;
lastI = i;
//log("Found smallest element at <"+i+","+j+"> (" + lastSmallest + ")");
}
}
}
myList.get(lastI).removeValue(lastJ);
if ( myList.get(lastI).getSize() == 0 )
myList.remove(lastI);
// add value to new list
for ( int i = 0; i < listsize; i++) {
if ( retList.get(i).getSize() < retList.get(i).getMaxSize() ) {
retList.get(i).addValue(lastSmallest);
break;
}
}
lastSmallest = Integer.MAX_VALUE;
}
return retList;
}
public class ListNode {
private ArrayList<Integer> values = new ArrayList<Integer>();
private int maxSize;
public ListNode(int maxSize) {
this.maxSize = maxSize;
}
public ArrayList<Integer> getValues() {
return values;
}
public int getMaxSize() {
return maxSize;
}
public int getSize() {
return values.size();
}
public int getValueAt(int position) {
if ( position < values.size())
return values.get(position);
else
throw new IndexOutOfBoundsException();
}
public void addValue(int value) {
values.add(value);
}
public void removeValue(int position) {
if ( position < values.size()) {
values.remove(position);
} else
throw new IndexOutOfBoundsException();
}
}
}
Here we go. The trivial solution consist in extracting all the elements of each array node and store them in a single big array, sort that big array (using Bubble Sort, Quick Sort, Shell Sort, etc.) and finally reconstruct the linked list of arrays with the the sorted values. I am almost sure that is not exactly what are you looking for.
If you want to sort the numbers in place, I can think of the following algorithm:
As others have commented, you need a comparison function that determines if a node A goes before a node B. The following algorithm use the first idea but for each pair of nodes, e.g. A->[3, 9, 7] and B->[1, 6, 8] becomes [1, 3, 6, 7, 8, 9] and finally A->[1,3, 6] and B->[7, 8, 9]. If we apply this rearrangement for each possible pair will end up with a sorted linked list of arrays (I have no proof, though).
A = head;
while (A.hasNext()) {
arrayA = A.getArray();
B = A.getNext();
while (B.hasNext()) {
arrayB = B.getArray();
// concatenate two arrays
int[] C = new int[arrayA.size() + arrayB.size()];
int i;
for (i = 0; i < arrayA.size(); i++)
C[i] = arrayA[i];
for ( ; i < arrayA.size() + arrayB.size(); i++)
C[i] = arrayB[i-arrayA.size()];
// sort the new arrays using agains Bubble sort or any
// other method, or Arrays.sort()
Arrays.sort(C);
// now return the sorted values to the two arrays
for (i = 0; i < arrayA.size(); i++)
arrayA[i] = C[i];
for (i = 0; i < arrayB.size(); i++)
arrayB[i] = C[i+arrayA.size()];
}
}
This is kind of pseudo code because I haven't worked with linked lists in Java but I think you get the idea.
NOTE: I haven't tested the code, it may contain horrors.