I need help to make a main method to test this program I've made for an assignment
Write a method to merge two linked lists of integers that are sorted into descending order. The result should be a third linked list that is the sorted combination of the original lists. Do not destroy the original lists.
import java.util.Iterator;
import java.util.LinkedList;
public class Exercise6
{
public static LinkedList<Integer> merge(LinkedList<Integer> a,LinkedList<Integer> b)
{
//Initialize variables
LinkedList<Integer> result = new LinkedList<Integer>();
Iterator<Integer> aI = a.iterator();
Iterator<Integer> bI = b.iterator();
int aTemp = 0;
int bTemp = 0;
//Get the first values from both lists using the next method
aTemp = aI.next();
bTemp = bI.next();
while(aI.hasNext() && bI.hasNext())
{
//Comparing the two elements
if(aTemp > bTemp)
{
result.add(bTemp);
bTemp = bI.next();
}
}
if(!aI.hasNext())
{
result.add(aTemp);
}
while(aI.hasNext())
{
result.add(aTemp);
aTemp = aI.next();
}
while(bI.hasNext())
{
result.add(bTemp);
bTemp = bI.next();
}
if(!aI.hasNext())
{
result.add(aTemp);
}
else
{
result.add(bTemp);
}
return result;
}
}
I think this is all you are asking for:
LinkedList<Integer> list1 = new LinkedList<Integer>();
list1.add(9);
list1.add(7);
list1.add(3);
LinkedList<Integer> list2 = new LinkedList<Integer>();
list1.add(8);
list1.add(5);
list1.add(1);
Exercise6 test = new Exercise6();
test.merge(list1,list2)
First, you are missing an else for your if in while(aI.hasNext() && bI.hasNext()). Next, I would strongly recommend you program to the List interface (instead of the concrete LinkedList type). Also, I would make the merge method generic on some comparable type T. Something like,
public static <T extends Comparable<? super T>> List<T> merge(List<T> a, List<T> b) {
// Initialize variables
List<T> result = new LinkedList<>();
Iterator<T> aI = a.iterator();
Iterator<T> bI = b.iterator();
// Get the first values from both lists using the next method
T aTemp = aI.hasNext() ? aI.next() : null;
T bTemp = bI.hasNext() ? bI.next() : null;
while (aI.hasNext() && bI.hasNext()) {
// Comparing the two elements
if (aTemp.compareTo(bTemp) < 0) {
result.add(bTemp); // <-- add the right-hand side
bTemp = bI.next();
} else {
result.add(aTemp); // <-- add the left-hand side
aTemp = aI.next();
}
}
// Add the final two values from the loop.
if (aTemp.compareTo(bTemp) < 0) {
result.add(bTemp);
result.add(aTemp);
} else {
result.add(aTemp);
result.add(bTemp);
}
while (aI.hasNext()) { // Add any remaining values from a
result.add(aI.next());
}
while (bI.hasNext()) { // Add any remaining values from b
result.add(bI.next());
}
return result;
}
Then you can test merge like
public static void main(String[] args) {
System.out.println(merge(Arrays.asList(6, 4, 2), Arrays.asList(5, 3, 1)));
System.out.println(merge(Arrays.asList("bat", "ant"),
Arrays.asList("dog", "cat")));
}
I get
[6, 5, 4, 3, 2, 1]
[dog, cat, bat, ant]
So do you write your code without ever testing it? I would suggest you get familiar with writing driver classes since as your code gets bigger you will need to test it along the way.
Create another class in the same package of your Exercise class: you can call it ExerciseDriver. Import classes as needed.
Declare Initialize and populate two linked lists. Declare a third linked lost to store the result.
Call the static method of your Exercise6 class
Print the result to verify
You could do something like:
import java.util.LinkedList;
public Class ExcerciseDriver{
public static void main (String[] args){
LinkedList<Integer> list1 = new LinkedList<>();
LinkedList<Integer> list2 = new LinkedList<>();
LinkedList<Integer> resultList;
list1.add(77);
list1.add(7);
list1.add(6);
list2.add(100);
list2.add(43);
list2.add(8);
resultList = Excercise6.merge(list1, list2);
System.out.println(resultList);
}
}
Now all you have to do is running the main method and verify the correctness of your algorithm
Related
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
}
}
}
I have found a few questions similar to the problem I am facing, but I couldn't find solution.
Example: Incompatible types List of List and ArrayList of ArrayList, Not able to understand how to define a List of List in java
The program should return list of lists. So, I declared a list of lists and then trying to add arraylists to it.
allsubsets = new ArrayList<List<Integer>>();
But, when I am trying to access each arraylist item from the list of lists as below, I get the error: incompatible types: List<Integer> cannot be converted to ArrayList<Integer>
for(ArrayList<Integer> subset:allsubsets)
When I try to convert the line to for(List<Integer> subset:allsubsets), it throws error that add, addAll don't exist for List type, which makes sense. Please help me understand how to access elements of list of lists in this case.
public List<List<Integer>> subsets(int[] nums) {
List<Integer> arrayList = new ArrayList<Integer>();
for(int i:nums) {
arrayList.add(i);
}
return subsets(arrayList,nums.length);
}
public List<List<Integer>> subsets(List<Integer> arrayList, int index) {
List<List<Integer>> allsubsets;
if(index == -1) {
allsubsets = new ArrayList<List<Integer>>();
allsubsets.add(new ArrayList<Integer>());
}
else {
allsubsets = subsets(arrayList, index-1);
int item = arrayList.get(index);
List<List<Integer>> moresubsets = new ArrayList<List<Integer>>();
for(ArrayList<Integer> subset:allsubsets) {
//The line above throws error as I created list of lists
List<Integer> newsubset = new ArrayList<Integer>(); //create new subset
newsubset.addAll(subset); // add all old items
newsubset.add(item); // add new item
moresubsets.add(newsubset); //add subset to moresubsets
}
allsubsets.add(moresubsets); // add to actual one
}
return allsubsets;
}
Note: If I change the return type to arraylist of arraylists, it works for me. But, I want to make it work for the list of lists
Correct way to iterate your list of list should be:
for(List<Integer> subset:allsubsets) {
instead of:
for(ArrayList<Integer> subset:allsubsets) {
List<List<Integer>> allsubsets is declared as List of List, but the implementation is unknown.
Only you know the type of nested List is ArrayList, so either change foreach to use List<Integer> or manually cast your List<Integer> to ArrayList<> (this is not preferred)
One more thing:
allsubsets.add(moresubsets); // add to actual one
This try to add a List of List (List<List<Integer>>) as element which should be List<Integer> hence compile error.
Change that statement to:
allsubsets.addAll(moresubsets);
Let's try expanding that enhanced for loop into more basic components:
for(ArrayList<Integer> subset:allsubsets) {
//The line above throws error as I created list of lists
}
// this is roughly equivalent to
Iterator<List<Integer>> it = allsubsets.iterator();
while(it.hasNext()) {
ArrayList<Integer> subset = it.next(); // Error
// Since the iterator was defined as an iterator to a List<List<Integer>>,
// it.next() will return the next element in allsubsets
// which happens to be an List<Integers>.
// You can't assign a reference of a parent type to a child. However
// the opposite is perfectly fine, assigning a reference of a child type
// to a parent.
// If we change subset to be a List<Integer> i.e.
// for(List<Integer> subset : allsubsets)
// then we are assigning a reference of a List<Integer> to a List<Integer>
// so no problem.
}
I prefer to share with you the code I did for managing the same type of Object List you are trying to handle. Hope this helps.
public static void main(String[] args) {
List<List<Integer>> allsubsets = setSubsets();
List<List<Integer>> allsubsets2 = new ArrayList<>();
allsubsets2.addAll(allsubsets);
int i= 0;
for (List<Integer> test : allsubsets2) {
System.out.println(i + " Lista");
for (Integer integer : test) {
System.out.println(integer);
}
i++;
}
}
public static List<List<Integer>> setSubsets() {
List<List<Integer>> allsubsets = new ArrayList<List<Integer>>();
List<Integer> listInteger1 = new ArrayList<>();
List<Integer> listInteger2 = new ArrayList<>();
for (int i = 0; i < 100; i++) {
listInteger1.add(i);
}
for (int i = 1010; i < 1110; i++) {
listInteger2.add(i);
}
allsubsets.add(listInteger1);
allsubsets.add(listInteger2);
return allsubsets;
}
I was wondering if anyone would be able to point me in the correct direction in regards to creating my own array list methods. For instance, the current project I am assigned to does not allow for me to use the methods given to me for free like in the following example.
package com.tutorialspoint;
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// create an empty array list with an initial capacity
ArrayList<Integer> arrlist = new ArrayList<Integer>(5);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(22);
arrlist.add(30);
arrlist.add(40);
// adding element 25 at third position
arrlist.add(2,25);
// let us print all the elements available in list
for (Integer number : arrlist) {
System.out.println("Number = " + number);
}
}
}
This example shows the add() method. For my project I have to create this method myself and call it from a different file within my package.
I find this as an interesting problem. I am always curious about how things work at the raw level.
If you think about it, an ArrayList is basically just an array that you can expand. So you can either have a really big array (which would take a lot of memory for one ArrayList) or every time you add something, you make a new bigger array and copy the contents and add the new item (which I think the performance is O(N)).
This is my attempt without using any libraries:
public class MyArrayList<T>
{
private T[] asArray;
#SuppressWarnings("unchecked")
public MyArrayList()
{
asArray = (T[]) new Object[0];
}
public void add(T t)
{
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length + 1];
// copy everything over to the new array
for (int i = 0; i < asArray.length; i++)
{
temp[i] = asArray[i];
}
// add the new element
temp[asArray.length] = t;
asArray = temp;
}
public void remove(int index)
{
if (index < 0 || index >= asArray.length) return;
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length - 1];
boolean found = false;
// copy everything over to the new element
for (int i = 0; i < asArray.length; i++)
{
// don't copy if the indices are the same
if (i == index)
{
found = true;
continue;
}
temp[i - (found ? 1 : 0)] = asArray[i]; // it's i - 1 after the removed object so then it doesn't leave a gap and it doesn't go over the array's length
}
asArray = temp;
}
public T get(int index)
{
return asArray[index];
}
}
I am quite proud of this code. :) I consider Short_Teeth's code cheating because the class is a subclass and, well, doesn't add anything. I hope I helped.
This is very easy to understand; However, I explained a little bit in comments.
public class MyArrayList<E extends Object> {
private static int initialCapacity = 5;
private static int currentSize;
private Object[] myArrayList = {}, temp = {};
private static int currentIndex = 0;
public static void main(String[] args) {
MyArrayList arrList = new MyArrayList();
arrList.add("123"); //add String
arrList.printAllElements();
arrList.add(new Integer(111)); //add Integer
arrList.printAllElements();
arrList.add(new Float("34.56")); //add Integer
arrList.printAllElements();
arrList.delete("123");
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
}
public MyArrayList() { //creates default sized Array of Objects
myArrayList = new Object[initialCapacity]; //generic expression
/* everytime I cross my capacity,
I make double size of Object Array, copy all the elements from past myObject Array Object
*/
}
public MyArrayList(int size) { //creates custom sized Array of Objects
myArrayList = new Object[size];
}
public void add(Object anyObj) {
//add element directy
myArrayList[currentIndex] = anyObj;
currentSize = myArrayList.length;
currentIndex++;
if (currentIndex == currentSize) {
createDoubleSizedObjectArray(currentSize);
}
}
//print all elements
public void printAllElements() {
System.out.println("Displaying list : ");
for (int i = 0; i < currentIndex; i++) {
System.out.println(myArrayList[i].toString());
}
}
private void createDoubleSizedObjectArray(int currentSize) {
temp = myArrayList.clone();
myArrayList = new MyArrayList[2 * currentSize]; //myObject pointer big size data structure
// myObject = temp.clone(); //probably I can do this here as well. Need to check this
System.arraycopy(temp, 0, myArrayList, 0, currentSize);
}
void delete(Object object) {
//if already empty
if (currentIndex == 0) {
System.out.println("Already empty!");
return;
}
//you don't need to delete anything. I can simply override the storage
currentIndex--;
}
}
import java.util.ArrayList;
public class MyArrayList<E> extends ArrayList<E>{
private static final long serialVersionUID = -5164702379587769464L;
public void newMethod(){
// No implementation
}
}
This is a class which extends from ArrayList and a method called newMethod() was added to this class.
Below we are calling this newly created method in your case you must implement the add to this newly created method.
public class Hello {
public static void main(String args[]) {
MyArrayList<Integer> myList = new MyArrayList<Integer>();
// It has the ArrayList add() method as this new class extends from ArrayList (all the ArrayList methods are included)
myList.add(2);
// The newly created method in your case you need to implement the add yourself
myList.newMethod();
}
}
This could also be a good link for what you need.
http://www.java2novice.com/java-interview-programs/arraylist-implementation/
I also recomend that you try to implement and solve your problems first and then ask questions about a specific problem, and only after you done a good research about what may be causing this problem (There are lots of resources out there). If you done some research before you asked this question, I'm pretty sure that you would have been able to solve everything on your own.
Hope you find this information useful. Good luck.
Say I have several List<T>s, I will put them into another list or other collections, so I don't know how many list<T> I have until I call List<List<T>>.size()
Take below List<Integer> as an example:
list1=[1,2]
list2=[3,4]
list3=[5,6]
....
listn=[2*n-1,2n];
How can I get the result of list1*list2*list3*...listn as a Cartesian product?
For example:
list1*list2*list3
should be:
[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]
You can use recursion to achieve it, your base case of recursion is when input is empty then return empty list, else process the remaining elements. E.g.
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class CartesianProduct {
public static <T> List<List<T>> calculate(List<List<T>> input) {
List<List<T>> res = new ArrayList<>();
if (input.isEmpty()) { // if no more elements to process
res.add(new ArrayList<>()); // then add empty list and return
return res;
} else {
// we need to calculate the cartesian product
// of input and store it in res variable
process(input, res);
}
return res; // method completes , return result
}
private static <T> void process(List<List<T>> lists, List<List<T>> res) {
//take first element of the list
List<T> head = lists.get(0);
//invoke calculate on remaining element, here is recursion
List<List<T>> tail = calculate(lists.subList(1, lists.size()));
for (T h : head) { // for each head
for (List<T> t : tail) { //iterate over the tail
List<T> tmp = new ArrayList<>(t.size());
tmp.add(h); // add the head
tmp.addAll(t); // and current tail element
res.add(tmp);
}
}
}
public static void main(String[] args) {
//we invoke the calculate method
System.out.println(calculate(Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4),
Arrays.asList(5, 6))));
}
}
Output
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
Thanks to #sol4me 's answer using tail recursion, here is another version which is not using tail recursion but I think is easier to understand.
public class CartesianProduct {
public static <T> List<List<T>> calculate(List<List<T>> input) {
List<List<T>> result = new ArrayList<List<T>>();
if (input.isEmpty()) { // If input an empty list
// add empty list and return
result.add(new ArrayList<T>());
return result;
} else {
// get the first list as a head
List<T> head = input.get(0);
// recursion to calculate a tail list
List<List<T>> tail = calculate(input.subList(1, input.size()));
// we merge every head element with every tail list.
for (T h : head) {
for (List<T> t : tail) {
List<T> resultElement = new ArrayList<T>();
resultElement.add(h);
resultElement.addAll(t);
result.add(resultElement);
}
}
}
return result;
}
public static void main(String[] args) {
List<List<Integer>> bigList = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4),
Arrays.asList(5, 6),
Arrays.asList(7, 8));
System.out.println(calculate(bigList));
}
}
The map-and-reduce approach using nested loops
Prepare a list of lists List<List<T>> populated with a single empty value. This list is used further as a storage of intermediate results and as a final result.
Sequentially append the data from incoming lists List<List<T>> to the intermediate result and obtain the final result. Schematically, this iterative process looks as follows:
result0: [[]]
list1: [1,2]
-------
result1: [[1],[2]]
list2: [3,4]
-------
result2: [[1,3],[1,4],[2,3],[2,4]]
list3: [5,6]
-------
result3: [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
Try it online!
/**
* #param lists an arbitrary number of lists
* #param <T> the type of the elements
* #return the Cartesian product
*/
public static <T> List<List<T>> cartesianProduct(List<List<T>> lists) {
// check if incoming data is not null
if (lists == null) return Collections.emptyList();
// Cartesian product, intermediate result
List<List<T>> cp = Collections.singletonList(Collections.emptyList());
// iterate through incoming lists
for (List<T> list : lists) {
// non-null and non-empty lists
if (list == null || list.size() == 0) continue;
// intermediate result for next iteration
List<List<T>> next = new ArrayList<>();
// rows of current intermediate result
for (List<T> row : cp) {
// elements of current list
for (T el : list) {
// new row for next intermediate result
List<T> nRow = new ArrayList<>(row);
nRow.add(el);
next.add(nRow);
}
}
// pass to next iteration
cp = next;
}
// Cartesian product, final result
return cp;
}
public static void main(String[] args) {
List<List<Integer>> lists = prepareLists(3);
List<List<Integer>> cp = cartesianProduct(lists);
// output without spaces
System.out.println(lists.toString().replace(" ", ""));
System.out.println(cp.toString().replace(" ", ""));
}
// supplementary method, prepares lists for multiplication
public static List<List<Integer>> prepareLists(int n) {
List<List<Integer>> lists = new ArrayList<>(n);
for (int i = 1; i <= n; i++)
lists.add(Arrays.asList(i * 2 - 1, i * 2));
return lists;
}
Output:
[[1,2],[3,4],[5,6]]
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
See also: Generate all combinations from multiple lists
This is my first time working with linked lists and I've created both of my lists from two separate files and tokenized the data.
Now I need to compare the data and look for similarities, by that I mean the same data.
Such has list 1: 1, 3, dog and list 2: 1, dog, cat. Both have 1 and dog.
I am unsure how to approach this, and would love some tips, input, or hints.
The code which compares two Lists only in case when their elements are comparable (i.e. implements Comparable interface).
This is parametrized so you can provide any type of List element which implements Comparable (<T extends Comparable<T>>)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ComparatorTest {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>(Arrays.asList(new Integer[]{1, 2, 3, 6, 7}));
List<Integer> list2 = new ArrayList<>(Arrays.asList(new Integer[]{1, 2, 3, 6}));
final int result = new ComparatorTest().compareTo(list1, list2);
System.out.println("result = " + result);
}
<T extends Comparable<T>> int compareTo(List<T> list1, List<T> list2) {
int minLength = Math.min(list1.size(), list2.size());
for (int i = 0; i < minLength; i++) {
final int compareValue = list1.get(i).compareTo(list2.get(i));
if (compareValue != 0) {
return compareValue; // They are already not equal
}
}
if (list1.size() == list2.size()) {
return 0; // They are equal
} else if (list1.size() < list2.size()) {
return -1; // list 1 is smaller
} else {
return 1;
}
}
}