Why is my Java function returning null? - java

class Solution {
Map<List<Integer>, Integer> map = new HashMap<>();
List<List<Integer>> ret = new ArrayList<>();//Created An ArrayList
public void dfs(int index, int target, List<Integer> choosen, int[] nums)
{
if(choosen.size()==3 && target==0 && !map.containsKey(choosen)){
ret.add(choosen);
map.put(choosen,0);
for(int j=0;j<list.size();j++)
System.out.print(list.get(j)+" ");
System.out.println();
//map.put(choosen,0);
return;
}
for(int i=index;i<nums.length;i++)
{
int x = nums[i];
choosen.add(x);
target-=x;
dfs(i+1,target,choosen,nums);
target+=nums[i];
choosen.remove(choosen.size()-1);
}
}
public List<List<Integer>> threeSum(int[] nums) {
List<Integer> choosen = new ArrayList<>();
Arrays.sort(nums);
dfs(0,0,choosen,nums);
return ret; //Returning Null
}
}
Why am i not able to add in "ret"? It's returning null.
I just want to add my choosen list into ret when the condition is true and return ret List.

I think the problem is that the if statement is checked before 'choosen' value change (when it is empty).
Try to have the if statement inside the for loop.

Related

How to save permutation in a Set Java

I have this method that prints my permutations of a Set I'm giving with my parameters. But I need to save them in 2 separate sets and compare them. So, for instance I have [5,6,3,1] and [5,6,1,3], by adding them in two separate BST, I can compare them by using the compareTo function to check whether their level order is the same. But I am having trouble with saving these permutations from my method into a set in my main. Does anyone know how to save these into a set?
What I have now:
import edu.princeton.cs.algs4.BST;
import java.util.*;
public class MyBST {
public static void main(String[] args) {
int size = 4;
BST<Integer, Integer> bst1 = new BST<Integer, Integer>();
BST<Integer, Integer> bst2 = new BST<Integer, Integer>();
Random r = new Random();
Set<Integer> tes = new LinkedHashSet<>(size);
Stack<Integer> stack = new Stack<>();
while (tes.size() < size) {
tes.add(r.nextInt(10));
}
System.out.println(tes);
System.out.println("possible combinations");
Iterator<Integer> it = tes.iterator();
for (int i = 0; i < tes.toArray().length; i++) {
Integer key = it.next();
bst1.put(key, 0);
}
combos(tes, stack, tes.size());
}
}
and here is the method I use:
public static void combos(Set<Integer> items, Stack<Integer> stack, int size) {
if (stack.size() == size) {
System.out.println(stack);
}
Integer[] itemz = items.toArray(new Integer[0]);
for (Integer i : itemz) {
stack.push(i);
items.remove(i);
combos(items, stack, size);
items.add(stack.pop());
}
}
And this is the output:
I'm not sure if I understood your idea but maybe this will help:
Yours combos method will return set of all permutations (as Stacks)
...
for (int i = 0; i < tes.toArray().length; i++) {
Integer key = it.next();
bst1.put(key, 0);
}
Set<Stack<Integer>> combos = combos(tes, stack, tes.size()); //there you have set with all Stacks
}
}
public static Set<Stack<Integer>> combos(Set<Integer> items, Stack<Integer> stack, int size) {
Set<Stack<Integer>> set = new HashSet<>();
if(stack.size() == size) {
System.out.println(stack.to);
set.add((Stack) stack.clone());
}
Integer[] itemz = items.toArray(new Integer[0]);
for(Integer i : itemz) {
stack.push(i);
items.remove(i);
set.addAll(combos(items, stack, size));
items.add(stack.pop());
}
return set;
}

Java Calculate all possible combinations of given int array

I am trying to construct a program that would take an array of int({1,2,3} and a length value and calculate all possible combinations of this array.
For example:
int[] arr= new char[] {0,1};
int[] tes = new int[3];
possiblecomb(2, arr,tes,0);
This will output:
00
10
01
11
But i keep getting a Stack overflow error when i try to call the possiblecomb in the for loop
import java.util.Arrays;
public class Program {
public static void main(String[] args) {
// Create an arr to work with
int[] test = new int[] {0,1};
int[] tes = new int[3];
// Find all possible combinations of this arr in the string size of 3
possiblecomb(3, test,tes,0);
}
public static void possiblecomb(int maxLength, int[] nums, int[] curr,int end) {
// If the current array has reached it's maximum length
if(end == maxLength) {
System.out.println(Arrays.toString(curr));
// Else add each number from the numbs to new array and process these new arrays again
} else {
for(int i = 0; i < nums.length; i++) {
int[] oldCurr = curr.clone();
curr[end]= nums[i];
possiblecomb(maxLength,nums,curr,end++);
curr = oldCurr.clone();
}
}
}
}
Try moving your recursive call outside of the for.
You are using the for in order to copy contents.
Your end variable will eventually increment above max lenght, and your (==) comparison won't be a stopper.
Take the example where num.Length = 2 and end is 2 :
You will call your function once with end = 3 which will stop and print inside the recursive call, and next, when i == 1 your end will be 4 and the recursive call won't break.
If you want to avoid the infinite recurssion with your current code in order to better debug with output, put the break condition
if (end>=maxLength)
As #MichaelCMS said you never stop the recursion, hence a stack overflow.
If you don't mind using Lists instead of arrays this is a solution:
import java.util.*;
public class Program {
private static List<List<Integer>> combinations(List<Integer> list, int maxLength) {
return combinations(list, maxLength, new ArrayList(), new ArrayList());
}
private static List<List<Integer>> combinations(List<Integer> list, int length, List<Integer> current, List<List<Integer>> result) {
if (length == 0) {
List<List<Integer>> newResult = new ArrayList<>(result);
newResult.add(current);
return newResult;
}
List<List<List<Integer>>> res3 = new ArrayList<>();
for (Integer i : list) {
List<Integer> newCurrent = new ArrayList<>(current);
newCurrent.add(i);
res3.add(combinations(list, length - 1, newCurrent, result));
}
List<List<Integer>> res2 = new ArrayList<>();
for (List<List<Integer>> lst : res3) {
res2.addAll(lst);
}
return res2;
}
public static void printCombinations(List<Integer> list, int maxLength) {
List<List<Integer>> combs = combinations(list, maxLength);
for (List<Integer> lst : combs) {
String line = "";
for (Integer i : lst) {
line += i;
}
System.out.println(line);
}
}
public static void main(String[] args) {
List<Integer> l = Arrays.asList(0, 1);
printCombinations(l, 2);
}
}
That gives you:
00
01
10
11

Problems with calling a member of array of strings

With the help of the community i managed to get this problem solved: How to convert String to the name of the Array?
But now i get 'nullPointerExceptions'. Here is the code i use:
public class IroncladsAdder
{
public static String weaponId = null;
public static String ship = null;
public static String wing = null;
//map code
private static Map<String, List<Integer>> arrays = new HashMap<String, List<Integer>>();
public void Holder(String... names) {
for (String name : names) {
arrays.put(name, new ArrayList<Integer>());
}
}
//adds weapons to fleets and stations
public static void AddWeapons(CargoAPI cargo, String fac, int count, int type) {
String arrayName = null;
int quantity = (int) (Math.random()*5f + count/2) + 1;
if (count == 1) {quantity = 1;}
if (type == 0) {arrayName = fac+"_mil_weps";}
else if (type == 1) {arrayName = fac+"_civ_weps";}
else {arrayName = fac+"_tech_weps";}
List<Integer> array = arrays.get(arrayName);
for (int j = 0; j <= count; j++)
{
weaponId = valueOf(arrays.get(arrayName).get((int) (Math.random() * arrays.get(arrayName).size())));
cargo.addWeapons(weaponId, quantity);
}
}
Here is an example of the array:
//high-tech UIN weapons
private static String [] uin_tech_weps =
{
"med-en-uin-partpulse",
"lrg-en-uin-partacc",
"med-bal-uin-driver",
"lrg-bal-uin-terminator",
"lrg-bal-uin-hvydriver",
"lrg-bal-uin-shotgundriver",
"lrg-en-uin-empbeam",
};
Error indicates that something is wrong with this construction:
weaponId = valueOf(arrays.get(arrayName).get((int) (Math.random() * arrays.get(arrayName).size())));
NOTE: i`m using Intellij IDEA and Java 6. Application most of the time has advices/fixes for some errors and in this case shows that everything is ok.
What i need is to get a String out of the specific array (that is using a code-generated name) and assign it to 'weaponId'.
When your application start the map with the arrays is empty, then when you try to get the array with name X you get back a null value.
First solution: at startup/construction time fill the map with empty arrays/List for all the arrays names.
Second solution: use this method in order to obtain the array.
protected List<Integer> getArray(String arrayName) {
List<Integer> array = map.get(arrayName);
if (array == null) {
array = new ArrayList<Integer>();
map.put(arrayName, array);
}
return array;
}
P.s.
You can change this code:
weaponId = valueOf(arrays.get(arrayName).get((int) (Math.random() * arrays.get(arrayName).size())));
into
weaponId = valueOf(array.get((int) (Math.random() * array.size())));
Ok. Now there is a different error - 'java.lang.IndexOutOfBoundsException: Index: 0, Size: 0'
Made the code look like this:
private static Map <String, List<Integer>> arrays = new HashMap<String, List<Integer>>();
public static List<Integer> getArray(String arrayName) {
List<Integer> array = arrays.get(arrayName);
if (array == null) {
array = new ArrayList<Integer>();
arrays.put("rsf_civ_weps", array);
arrays.put("rsf_mil_weps", array);
arrays.put("rsf_tech_weps", array);
arrays.put("isa_civ_weps", array);
arrays.put("isa_mil_weps", array);
arrays.put("isa_tech_weps", array);
arrays.put("uin_mil_weps", array);
arrays.put("uin_tech_weps", array);
arrays.put("uin_civ_weps", array);
arrays.put("xle_civ_weps", array);
arrays.put("xle_mil_weps", array);
arrays.put("xle_tech_weps", array);
}
return array;
}
This is how i now call the array and weaponId:
List<Integer> array = arrays.get(arrayName);
for (int j = 0; j <= count; j++)
{
weaponId = valueOf(array.get((int) (Math.random() * array.size())));
cargo.addWeapons(weaponId, quantity);
}
What`s wrong?

Cannot count number in ArrayList using java

I am using the List as shown below:-
List<Integer> integerlist = new ArrayList<Integer>();
integerlist=primeFactors(numberToBERadical);
The primeFactors method return me some number when i sysOut as:-
System.out.println("integer list=="+integerlist);
integer list==[2, 2, 2, 3, 5]
My Problem is i want to count how many time that each number appears so that i can show Like this:-
2^3 * 3 * 5
You need to associate each factor with the number of times it occurs (the exponent).
To do that, a better data structure than a List would be a Map<Integer,Integer>.
Let's assume you still get a List from your primeFactors(numberToBERadical); (assuming you can't change it or don't want to for some reason).
You can do something like:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(2);
list.add(2);
list.add(3);
list.add(3);
list.add(5);
Map<Integer, Integer> factors = new HashMap<>();
for(Integer fact: list){
if(!factors.containsKey(fact)) { factors.put(fact, 1);}
else {
Integer value = factors.get(fact);
factors.put(fact, ++value);
}
}
System.out.println(factors);
}
Prints: {2=3, 3=2, 5=1}
If the array is sorted, you can count them like:
int count = 0;
int last = 0; // zero is not possible for prime-factors
for(int i=0;i<list.size();i++) {
if(i == 0 || last == list.get(i)) count++;
else {
if(last > list.get(0)) {
System.out.print(" * ");
}
System.out.print(last + (count > 1 ? "^" + count: ""));
count = 1;
}
last = list.get(i);
}
//print last sequence.
if(last > 0) {
if(last > list.get(0)) {
System.out.print(" * ");
}
System.out.print(last + (count > 1 ? "^" + count: ""));
}
You need to use a Map<Integer, Integer> which you can override the put method in in order to count the instances of each Integer.
final Map<Integer, Integer> myStringMap = new HashMap<>(){
#override
public String put(final Integer key, final Integer value) {
if(contains(key)) {
return put(key, get(key) + 1);
} else {
return put(key, 1);
}
}
};
You could even use a TreeMap to have the prime factors sorted by size. I answered a very similar question here. Simply loop over your List and dump it into the map
for(final Integer integer : myList) {
myCountingMap.put(integer, 1);
}
Even better would be to change your factorising method to return a Map to begin with.
List<Integer> inputList = new ArrayList<Integer>();
inputList.add(2);
inputList.add(2);
inputList.add(2);
inputList.add(3);
inputList.add(3);
inputList.add(4);
Map<Integer, Integer> resultMap = new HashMap<Integer, Integer>();
boolean flag = false;
for(int val : inputList)
{
if(resultMap.get(val) == null)
{
resultMap.put(val, 1);
}
else
{
resultMap.put(val, (resultMap.get(val).intValue())+1);
}
}
for(int key : resultMap.keySet())
{
if(resultMap.get(key) == 1)
{
if(!flag)
{
System.out.print(key);
flag = true;
}
else
{
System.out.print("*"+key);
}
}
else
{
if(!flag)
{
System.out.print(key+"^"+resultMap.get(key));
flag = true;
}
else
{
System.out.print("*"+key+"^"+resultMap.get(key));
}
}
}
System.out.println();
One possible, but not the simplest solution:
public Map<Integer, AtomicInteger> primeFactors(List<Integer integerList) {
final Map<Integer, AtomicInteger> count = new HashMap<Integer, AtomicInteger>();
for (final Integer number : integerlist) {
if (count.containsKey(number)) {
count.get(number).incrementAndGet();
} else {
count.put(number, new AtomicInteger(1));
}
}
return count;
}

Getting unique elements of List

all I have list containing Duplicate values I want somehow to get only Unique values from it and store it another list or set.So that I can perform some operation on it.
My code:
{
List<Integer[]> list1 = new ArrayList<Integer[]>();
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 2,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 3,10 });
for(int i=0;i<list1.size();i++)
{
System.out.println("I - 0 :"+list1.get(i)[0]+"\t I - 1 :"+list1.get(i)[1]+"\n");
}
Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);
for(Integer[] number: uniquelist){
System.out.println(number[0]+"\t"+number[1]);
}
}
I want the result {1,10;2,10;3,10} to be in separate list.When i googled I got to know for unique we should use set as in Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1); But after doing this I dont know how to access each elements Thanks in advance
Output:
1 10
2 10
1 10
3 10
1 10
1 10
You won't get the result you want using the normal Set approach. As your List contains Integer[], and then won't be considered unique by default. All the array objects are distinct. So, your Set will contain the same elements as your list. However, you can define your Custom Comparator, and use it with a TreeSet constructor.
Another way of doing it can be, define a method contains(List<Integer[]> list, Integer[] value), which checks whether your list contains that array. Define a list named uniqueList. Now, iterate over your original list, and then for each value, call contains method passing uniqueList and that value, as parameters.
Here's how your contains method would look like: -
public static boolean contains(List<Integer[]> list, Integer[] value) {
for (Integer[] arr: list) {
// We can compare two arrays using `Arrays.equals` method.
if (Arrays.equals(arr, value)) {
return true;
}
}
return false;
}
So, you can see that, checking for containment is not the same as, how it would look for just Integer.
Now, from your main method, use this code: -
List<Integer[]> unique = new ArrayList<Integer[]>();
for (Integer[] arr: list1) {
// Use your method here, to test whether this value - `arr`
// is already in `unique` List or not. If not, then add it.
if (!contains(unique, arr)) {
unique.add(arr);
}
}
for (Integer[] arr: unique) {
System.out.println(arr);
}
I would rather use a Set implementation in this case. Use LinkedHashSet if you want your elements to be ordered.
You could declare a class IntegerPair to hold your pairs:
class IntegerPair {
private int key;
private int value;
public IntegerPair(int k, int v) {
key = k;
value = v;
}
public int getKey() {
return key;
}
public int getValue() {
return value;
}
public int hashCode() {
return key * value;
}
public boolean equals(Object o) {
if (!(o instanceof IntegerPair)) {
return false;
}
IntegerPair other = (IntegerPair) o;
return key == other.key && value == other.value;
}
}
Declare it this way:
Set<IntegerPair> set = new LinkedHashSet<IntegerPair>();
Instead of putting new Integer[] values, just do set.add(new IntegerPair(1, 10));
You can loop through your elements using the foreach approach:
for (IntegerPair value : set) {
System.out.println(value.getKey() + " = " + value.getValue());
}
You can access elements by Iterator or by using for each loop
for(Integer number: setOfNumbers){
System.out.println(number);
}
Put them into set using your custom comparator like following:
new TreeSet(list1, new Comparator<Integer[]>() {
public int compare(Integer[] one, Integer[] two) {
int n = one.length;
for (int i = 0; i < n; i++) {
int comp = one.compareTo(two);
if (comp != 0) {
return comp;
}
}
return 0;
}
});
Pay attention that I used TreeSet that can accept custom comparator. It is because you are dealing with arrays. If however you define your own class that holds 2 int values you can make it to implement equals() and hashCode() that allows using any Set implementation.
the Integer[] number in your for loop is an array. to get the values inside you have to use number[index] instruction. to do that you can either do a classic while or for loop using a variable as an index
for(int i=0;i<number.length;i++) {
...
}
or a foreach loop:
for(Integer num : number){
...
}
This may help you...
public static void main(String [] args){
Set<Integer []> set = new TreeSet<Integer []>(new Comparator<Integer[]>(){
public int compare(Integer[] o1, Integer[] o2) {
if(o1.length == o2.length){
for(int i = 0; i < o1.length; i++){
if(o1[i] != o2[i]){
return -1;
}
}
return 0;
}
return -1;
}
});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,3});
int j = 0;
for(Integer[] i: set){
System.out.println("\nElements: "+j);
j++;
for(Integer k : i){
System.out.print(k+" ");
}
}
}
You need to use Comparator to compare two elements of same. As we don't have comparator for Array, Set will use actual object to compare.. using comparator you will have to tell set that this two arrays are same and do not add other same array
Try Table collection in Google-guava.
Example :
Table<Integer, Integer, Integer[]> sampleTable = HashBasedTable.create();
sampleTable.put(1, 10, new Integer[] { 1,10 });
sampleTable.put(2, 10, new Integer[] { 2,10 });
sampleTable.put(1, 10, new Integer[] { 1,10 });
So it will overwrite the duplicate values. Finally you have only unique values.

Categories

Resources