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;
}
Related
i would like if someone can check out this piece of code, the code should transform an array into a list and then into a map. The key should have the value of the list element and the value should be True if it's an even number and False if it's odd. The array is "8, 6, 1, 5, 3, 9, 2". I'm pretty sure this is the right way but when printing the map i get a lot of lines, it's my first time doing with maps so i'm not sure if that's the way it should be or i messed something up huh. Code:
static public void toMap(int x[]) {
List<Integer> list = new ArrayList<>();
Map<Integer, String> map = new HashMap<>();
for (int t : x) {
list.add(t);
}
for(int z : list) {
String tf;
if(z % 2 == 0)
tf = "True";
else
tf = "False";
map.put(z,tf);
for (Map.Entry<Integer, String> mp : map.entrySet()) {
System.out.println(mp.getKey() + "/" + mp.getValue());
}
}
}
Getting this when printing:
Any help/tip would be appreciated, thanks in advance!
You are printing inside the for loop and that is causing the issue. You need to move it outside the for loop. Here is the updated code -
static public void toMap(int[] x) {
List<Integer> list = new ArrayList<>();
for (int t : x) {
list.add(t);
}
Map<Integer, String> map = new HashMap<>();
for(int z : list) {
String tf;
if(z % 2 == 0)
tf = "True";
else
tf = "False";
map.put(z,tf);
}
for (Map.Entry<Integer, String> mp : map.entrySet()) {
System.out.println(mp.getKey() + "/" + mp.getValue());
}
}
Also you can simplify it a bit as below -
public static void main(String[] args) {
Integer[] array = {8, 6, 1, 5, 3, 9, 2};
toMap(array);
}
static public void toMap(Integer[] x) {
List<Integer> list = Arrays.asList(x);
Map<Integer, String> map = new HashMap<>();
list.forEach(i -> {
if (i % 2 == 0)
map.put(i, "True");
else
map.put(i, "False");
});
System.out.println(map);
}
You are putting the loop for printing out the map inside the loop that creates it, so every time you add an entry it reprints the map. You actually do have the correct map -- the last few lines of output.
To fix it you should move that last for loop out to make it
for(int z : list) {
String tf;
if(z % 2 == 0)
tf = "True";
else
tf = "False";
map.put(z,tf);
}
for (Map.Entry<Integer, String> mp : map.entrySet()) {
System.out.println(mp.getKey() + "/" + mp.getValue());
}
This is a clear example of why you should always put the braces in your code, you get lost.
for(int z : list) {
String tf;
if(z % 2 == 0) {
tf = "True";
}
else {
tf = "False";
}
map.put(z,tf);
for (Map.Entry<Integer, String> mp : map.entrySet()) {
System.out.println(mp.getKey() + "/" + mp.getValue());
}
}
If we put the braces there, you can clearly see that you have the printing for-loop inside the other one. This is harder to see without the braces.
Move that printing loop outside the other one and you should be good.
You need to move the printing loop outside of the first loop.
Also, a few observations.
X == Y returns true or false depending on the value. And booleans will print out as true or false. So why not do the following:
for(int z : list) { // you can also replace list with your array here
map.put(z,z % 2 == 0);
}
// or if you want Strings
for (int z : list) {
map.put(z, z % 2 == 0 ? "True":"False");
}
To print them, you can do this.
map.forEach((k,v)->System.out.println(k + "/" + v));
You don't need to iterate twice over the array. Iterate only once, add it to list and even or odd to map.
static public void toMap(int x[]) {
// List which contains all elements of x.
List<Integer> list = new ArrayList<>();
// Map to store element as key and even or not as value
Map<Integer, Boolean> map = new HashMap<>();
for (int value: x) {
list.add(value);
map.put(value, value % 2 == 0);
}
// Printing the map
for (Map.Entry<Integer, Boolean> m : map.entrySet()) {
System.out.println(m.getKey() + "," + m.getValue());
}
}
As others have said, your problem is in the nesting. You are looping through all of your map entries for every integer in the input array. That said, I think the bigger issue is you have over-complicated your method. Using a few tricks, you can simplify your code down to something like this:
public static void toMap(int[] x) {
HashMap<Integer, String> map = new HashMap<>();
ArrayList<Integer> list = new ArrayList<>();
for (int i : x) {
map.put(i, (i & 1) == 0 ? "True" : "False"); //puts "True" if i is even, else "False"
}
list.addAll(map.keySet()); //adds all the map's keys to the ArrayList
map.forEach((k, v) -> System.out.printf("%d/%s%n", k, v)); //prints out all the entries formatted as you specified
}
Or, if you don't actually need the ArrayList for anything specific, you can just get rid of it:
public static void toMap(int[] x) {
HashMap<Integer, String> map = new HashMap<>();
for (int i : x) {
map.put(i, (i & 1) == 0 ? "True" : "False"); //puts "True" if i is even, else "False"
}
map.forEach((k, v) -> System.out.printf("%d/%s%n", k, v)); //prints out all the entries formatted as you specified
}
Or, if you don't actually need any of the functions of the map, you can just get rid of that, too. Just print straight from the for loop, like so:
public static void toMap(int[] x) {
for (int i : x) {
System.out.printf("%d/%s%n", i, (i & 1) == 0 ? "True" : "False");
}
}
Or, if you don't mind the true/false being all lowercase, you can let Java do the string conversion for you:
public static void toMap(int[] x) {
for (int i : x) {
System.out.printf("%d/%s%n", i, (i & 1) == 0);
}
}
Finally, if you're into one-liners, and don't mind it being a bit messy, you can do it all in one line:
public static void toMap(int[] x) {
IntStream.of(x).forEach((i) -> System.out.printf("%d/%s%n", i, (i & 1) == 0));
}
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.
I'm working on emulator of ATM in java. The overall pattern in project is Command.
So I have 4 commands - getInfo, deposit,withdraw and exit.
I'm facing problems with an implementation of greedy algorithm in withdrawal method. It should return Map were first Integer is "denomination" and second Integer is "amount" left in ATM after we withdrew.
public Map<Integer, Integer> withdrawAmount(int expectedAmount)
So it takes expected amount as an argument and has to subtract it from ATM with the least possible amount of bills.
public class CurrencyManipulator
{
// denominations is a map where each denomination and it's quantity stored
private String currencyCode;
private Map<Integer, Integer> denominations = new HashMap<>();
public String getCurrencyCode()
{
return currencyCode;
}
public CurrencyManipulator(String currencyCode)
{
this.currencyCode = currencyCode;
}
public void addAmount(int denomination, int count)
{
if (denominations.containsKey(denomination))
{
denominations.put(denomination, denominations.get(count) + count);
} else
{
denominations.put(denomination, count);
}
}
public int getTotalAmount()
{
int sum = 0;
for (Map.Entry<Integer, Integer> pair : denominations.entrySet())
{
sum = pair.getKey() * pair.getValue();
}
return sum;
}
public boolean hasMoney()
{
return denominations.size() != 0;
}
public boolean isAmountAvailable(int expectedAmount)
{
return expectedAmount <= getTotalAmount();
}
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
{
}
}
So I need this method to return a map or throw exception if amount asked "expectedAmount" is higher then money available in ATM.
If we take $600 it could be - three bills: $500 + $50 + $50 OR $200 + $200 + $200, the preferred option is $500 + $50 + $50
Example, you have to give $600
The ATM has the following bill-count:
500 - 2
200 - 3
100 - 1
50 - 12
The result should be:
500 - 1
100 - 1
This what I came up with:
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
{
denominations.put(50,1);
denominations.put(500,1);
denominations.put(200,3);
HashMap<Integer, Integer> map = new HashMap<>();
TreeMap<Integer, Integer> sortedMap = new TreeMap<>(Collections.reverseOrder());
sortedMap.putAll(denominations);
ArrayList<Integer> bills = new ArrayList<>();
bills.addAll(sortedMap.keySet());
int num;
for (int i = 0; i < bills.size(); i++)
{
if (bills.get(i) <= expectedAmount)
{
num = expectedAmount / bills.get(i);
map.put(bills.get(i), num);
expectedAmount -= num * bills.get(i);
}
}
System.out.println(map);
return map;
}
It returns the map of needed bills and their quantity.
Now my question is..how do i compare it with the "denominations" map i have and subtract new map from it?
seems to be working code if someone ever needs it
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
{
denominations.put(50,2);
denominations.put(500,1);
denominations.put(100,1);
HashMap<Integer, Integer> map = new HashMap<>();
TreeMap<Integer, Integer> sortedDenominations = new TreeMap<>(Collections.reverseOrder());
sortedDenominations.putAll(denominations);
ArrayList<Integer> bills = new ArrayList<>();
bills.addAll(sortedDenominations.keySet());
int num;
for (int i = 0; i < bills.size(); i++)
{
if (bills.get(i) <= expectedAmount)
{
num = expectedAmount / bills.get(i);
map.put(bills.get(i), num);
expectedAmount -= num * bills.get(i);
}
}
System.out.println(map);
for (Map.Entry<Integer,Integer> denominPresent:sortedDenominations.entrySet()){
int value;
for (Map.Entry<Integer,Integer> deominNeeded:map.entrySet()){
if(denominPresent.getKey().equals(deominNeeded.getKey())){
value = denominPresent.getValue()-deominNeeded.getValue();
if (value>=0) sortedDenominations.put(denominPresent.getKey(),value);
else throw new NotEnoughMoneyException();
}
}
}
System.out.println(sortedDenominations);
return sortedDenominations;
}
Another solution. Will work if you initialize the denominations variable using TreeMap
...
private Map<Integer, Integer> denominations = new TreeMap<>(Comparator.reverseOrder());
...
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException {
final Map<Integer, Integer> map = new TreeMap<>(Comparator.reverseOrder());
// calculate denomination map to cash
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int denomination = entry.getKey();
if (denomination <= expectedAmount) {
int num = Math.min(expectedAmount / denomination, entry.getValue());
map.put(denomination, num);
expectedAmount -= num * denomination;
}
if (expectedAmount == 0) {
break;
}
}
if (expectedAmount != 0) {
throw new NotEnoughMoneyException();
}
map.forEach((key, value) -> {
denominations.compute(key, (denomination, count) -> {
return (count == value) ? null : count - value;
});
});
return map;
}
Well im stuck on this point.
im trying to make sort function what does this.
parentarraylist = [1,1,1,2,3,2,3,3,2,2,1];
*magic*
childarraylist1 = [1,1,1,1];
childarraylist2 = [2,2,2,2];
childarraylist3 = [3,3,3];
the magic part is where im stuck.
i have tryied putting it in an for loop(the parent) and checking on the value. like this
int i = 0;
int finder = 0;
ArrayList<int> initArray = new ArrayList();
for(int list : parentarraylist){
if(i == 0){
finder = list
}
if(finder == list){
initArray.add(list);
parentarraylist.remove(list);
}else{
new ArrayList *value of list* = new ArrayList();
finder = list;
*value of list*.add(list);
}
}
this results in a view errors like
java.util.ConcurrentModificationException
and i cant set value of list
what can i do to make this work?
This little snippet should help you achieve your goal:
//maps will hold ALL unique integer as it's key
HashMap<Integer, ArrayList<Integer>> maps = new HashMap<Integer, ArrayList<Integer>>();
//your initial array, written inline for clarity
ArrayList<Integer> parentarraylist = new ArrayList<Integer>(Arrays.asList( new Integer[] {1,1,1,2,3,2,3,3,2,2,1}));
//get the iterator so that we won't need another temporary int variable for loop
Iterator<Integer> iterator = parentarraylist.iterator();
while(iterator.hasNext()){
//next = current integer in our array
Integer next = iterator.next();
//check if we have already have current integer or not
if(!maps.containsKey(next)){
//we don't have it, initialise an arraylist for this specific integer
ArrayList<Integer> x = new ArrayList<Integer>();
x.add(next);
//put it to our map holder
maps.put(next, x);
} else {
//already have it, add directly
maps.get(next).add(next);
}
}
This codes will print something like this:
printMap(maps);
//1 = [1, 1, 1, 1]
//2 = [2, 2, 2, 2]
//3 = [3, 3, 3]
printMap() is taken from this answer: Iterate through a HashMap
public static void printMap(Map mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
You could try something like this:
public static void main(String[] args) {
ArrayList<Integer> parent = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
parent.add(3);
parent.add(1);
parent.add(1);
parent.add(2);
parent.add(3);
parent.add(3);
parent.add(1);
for(int i : parent)
{
boolean check = false;
for(ArrayList<Integer> result : results)
{
if(result.size() > 0)
{
if(result.get(0) == i)
{
check = true;
result.add(i);
break;
}
}
}
if(!check)
{
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(i);
results.add(temp);
}
}
for(ArrayList<Integer> i : results)
{
for(int j : i)
{
System.out.print("" + j);
}
System.out.println();
}
}
Output:
333
111
2
The problem is that you remove an element from an array over which you are iterating. The
parentArrayList.remove(list);
causes the error here. If you remove this line your program will work. At the moment I do not see the benefit of removing the item from the parentArrayList for your sorting algorithm so just delete it and you are good to go.
I got this problem I need to return the key in a hashmap with the largest value, the trick here is that the method must account for edge case scenarios. I can also only use the above imports, so Map.Entry is not allowed. Collections.sort isn't etc. Thanks.
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public class Exercise {
public static String findLargest(HashMap<String, Integer> map) {
// Enter code here
if(that.isEmpty()) return "";
Integer maxInt = Integer.MIN_VALUE;
String maxCity = "";
for(String entry : that.keySet()) {
if (that.get(entry) != null && that.get(entry) < Integer.MAX_VALUE && that.get(entry) > Integer.MIN_VALUE && that.get(entry) > maxInt) {
maxInt = that.get(entry);
maxCity = entry;
}
}
return maxCity;
}
public static void check(String largest, List<String> apples, List<Integer> size) {
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < apples.size(); i++) {
map.put(apples.get(i), size.get(i));
}
assert largest.equals(findLargest(map)) : "expected " + largest + " but was " + findLargest(map);
}
public static void main(String[] arg) {
check("Granny", Arrays.asList("Granny", "Eve", "Rose"), Arrays.asList(5, 1, 2));
}
}
The solution is really inefficient, but if you cannot add any other imports... it works. The first step is to find the maximum value among the integers and then for each of the keys, check if the map.get(key).equals(max):
public static String findLargest(HashMap<String, Integer> map) {
//step 1
int max = Integer.MIN_VALUE;
for (int i : map.values()) {
max = Math.max(max, i);
}
//step 2
for (String str : map.keySet()) {
if (map.get(str).equals(max)) {
return str;
}
}
return null;
}