Java - Counting numbers in array - java

I've written a java prog that stores some values:
public class array05 {
public static void main(String[] args) {
//placement of value
int arryNum[] = {2,3,4,5,4,4,3};
//placement of index, to start at 0
for(int counter=0;counter<arryNum.length;counter++){
System.out.println(counter + ":" + arryNum[counter]);
}
}
}
which generate such output:
0:2
1:3
2:4
3:5
4:4
5:4
6:3
and now I need to count numbers in this output #1.
Output #2 should be this:
1: 0
2: 1
3: 2
4: 3
5: 1
It means it counts ONE 2, TWO 3, THREE 4, and only One 5.
I am not sure how to write the code for output 2.
Is a binary search needed here?
can anybody shed a light?

if you are expecting in your array values between 1-5 (i assuming this from your expected output)
int arryNum[] = { 2, 3, 4, 5, 4, 4, 3 };
int[] counter = new int[] { 0, 0, 0, 0, 0 };
for (int i = 0; i < arryNum.length; i++) {
counter[arryNum[i] - 1]++;
}
for (int i = 0; i < counter.length; i++)
System.out.println((i + 1) + ":" + counter[i]);

I advise you to use a Map:
If a number doesn't exist in it, add it with the value of 1.
If the number exists, add 1 to the its value.
Then you print the map as a key and value.
For example, for your array {2,3,4,5,4,4,3} this will work as follows:
Does the map contains the key 2? No, add it with value 1. (The same for 3, 4 and 5)
Does the map contains 4? Yes! Add 1 to its value. Now the key 4 has the value of 2.
...

If you don't want to use Map, this is how you would do it with Arrays only(if you have numbers from 1 to 9 only)
Integer[] countArray = new Integer[10]
// Firstly Initialize all elements of countArray to zero
// Then
for(i=0;i<arryNum.length();i++){
int j = arryNum[i];
countArray[j]++;
}
This countArray has number of 0's in 1st position, number of 1s in 2nd position and so on

This is a solution to this problem:
import java.util.Arrays;
public class array05 {
public static void main(String[] args) {
//placement of value
int arryNum[] = {2,3,4,5,4,4,3};
// Sort the array so counting same objects is easy
Arrays.sort(arryNum);
int index = 0; // The current index
int curnum; // The current number
int count; // The count of this number
while (index < arryNum.length) {
// Obtain the current number
curnum = arryNum[index];
// Reset the counter
count = 0;
// "while the index is smaller than the amount of items
// and the current number is equal to the number in the current index,
// increase the index position and the counter by 1"
for (; index < arryNum.length && curnum == arryNum[index]; index ++, count++);
// count should contain the appropriate amount of the current
// number now
System.out.println(curnum + ":" + count);
}
}
}
People posted good solutions using Map, so I figured I'd contribute a good solution that will always work (not just for the current values), without using a Map.

Something like this:
//numbers to count
int arryNum[] = {2,3,4,5,4,4,3};
//map to store results in
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
//Do the counting
for (int i : arryNum) {
if (counts.containsKey(i) {
counts.put(i, counts.get(i)+1);
} else {
counts.put(i, 1);
}
}
//Output the results
for (int i : counts.keySet()) {
System.out.println(i+":"+counts.get(i));
}

Use Map to store count values:
import java.util.HashMap;
import java.util.Map;
class array05{
public static void main(String[] args){
// Container for count values
Map <Integer, Integer> result = new HashMap<Integer, Integer>();
int arryNum[] = {2,3,4,5,4,4,3};
for(int i: arryNum){ //foreach more correct in this case
if (result.containsKey(i)) result.put(i, result.get(i)+1);
else result.put(i, 1);
}
for (int i: result.keySet()) System.out.println(i + ":" + result.get(i));
}
}
Result below:
2:1
3:2
4:3
5:1

One approach is to use a map. When you read the first array on each number check if it exists in the map, if it does then just increment the value assigned to the number(key), if not then create a new key in the map with value "1".
Check out http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

You can try this way too
int arrayNum[] = {2,3,4,5,4,4,3};
Map<Integer,Integer> valMap=new HashMap<>();
for(int i:arrayNum){ // jdk version should >1.7
Integer val=valMap.get(i);
if(val==null){
val=0;
}
valMap.put(i,val+1);
}
Arrays.sort(arrayNum);
for(int i=0;i< arrayNum[arrayNum.length-1];i++){
System.out.println(i+1+" : "+((valMap.get(i+1)==null) ? 0:valMap.get(i+1)));
}
Out put
1 : 0
2 : 1
3 : 2
4 : 3
5 : 1
But following way is better
int arrayNum[] = {2,3,4,5,4,4,3};
Arrays.sort(arrayNum);
int countArray[]=new int[arrayNum[arrayNum.length-1]+1];
for(int i:arrayNum){
countArray[i]= countArray[i]+1;
}
for(int i=1;i<countArray.length;i++){
System.out.println(i+" : "+countArray[i]);
}
Out put
1 : 0
2 : 1
3 : 2
4 : 3
5 : 1

I would prefer some generic solution like this one:
public static <T> Map<T, Integer> toCountMap(List<T> itemsToCount) {
Map<T, Integer> countMap = new HashMap<>();
for (T item : itemsToCount) {
countMap.putIfAbsent(item, 0);
countMap.put(item, countMap.get(item) + 1);
}
return countMap;
}

//Count the times of numbers present in an array
private HashMap<Integer, Integer> countNumbersInArray(int[] array) {
HashMap<Integer, Integer> hashMap = new HashMap<>();
for (int item : array) {
if (hashMap.containsKey(item)) {
hashMap.put(item, hashMap.get(item) + 1);
} else {
hashMap.put(item, 1);
}
}
return hashMap;
}

Related

Question is to find repeated elements in an array?

Example
N = 5
arr[] = {1,2,3,3,4}
Output: 3 2
Explanation: In the given array, 3 is
occuring two times.
class Solution
{
//Function to find repeated element and its frequency.
public static Point findRepeating(Integer arr[],int n)
{
//Your code here
int slow=arr[0],fast=arr[0];int count=0;
do
{
slow=arr[slow];
fast=arr[arr[fast]];
}
while(slow!=fast);
slow=arr[0];
while(slow!=fast)
{
fast=arr[fast];
slow=arr[slow];
count++;
}
System.out.println(slow+" "+count);
return new Point();
}
};
If I am applying "return new Point()",My output is coming 3 2
plus additional two zeroes after that, shown below
3 2
0 0
You haven't mentioned what 'n' is. However, repeated elements and their frequencies can be also found this way using a Hashmap.
int[] arr = {2,6,4,4,8,7,2,2,8,8,8,8};
Map<Integer, Integer> count = new HashMap<>();
for (Integer c : arr) {
if (count.containsKey(c)) {
count.put(c, count.get(c) + 1);
} else
count.put(c, 1);
}
count.values().removeIf(value -> value.equals(1));
System.out.println(count);

finding non duplicate integer from give array with odd number of items

Trying to figure the error with this code. This works for small samples but fails for huge numbers (I don't have a large sample in my hand though).
The solution worked for the following tests.
private static final int[] A = {9,3,9,3,9,7,9};
private static final int[] A2 = {9,3,9};
private static final int[] A3 = {9,3,9,3,9,7,7,2,2,11,9};
#Test
public void test(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A);
assertEquals(7,odd);
}
#Test
public void test2(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A2);
assertEquals(3,odd);
}
#Test
public void test3(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A3);
assertEquals(11,odd);
}
when an array is given with an odd number of integers (except one integer other integers can be repeated). The solution is to find the non-repeating integer. Any other better ideas (Time and space optimized) to implement this as well, welcome.
public int solution(int[] A) {
// write your code in Java SE 8
Map<Integer, List<Integer>> map = new HashMap<>();
int value = 0;
//iterate throught the list and for each array value( key in the map)
// set how often it appears as the value of the map
for (int key : A) {
if (map.containsKey(key)) {
map.get(key).add(value);
} else {
List<Integer> valueList = new ArrayList<>();
valueList.add(value);
map.put(key, valueList);
}
}
Set<Map.Entry<Integer, List<Integer>>> entrySet = map.entrySet();
// en
for (Map.Entry<Integer, List<Integer>> entry : entrySet) {
if (entry.getValue().size() == 1) {
return entry.getKey();
}
}
return 0;
}
Update
Looking at failed outputs
WRONG ANSWER, got 0 expected 42
WRONG ANSWER, got 0 expected 700
It seems it didn't even go to the for loop but just return 0
It's a standard problem, if the actual statement is the following:
each number except one appears even number of times; the remaining number appears once.
The solution is to take xor of all numbers. Since every repeating number occures even number of times, it will cancel itself. The reason is that xor is commutative:
a xor b xor c = a xor c xor b = c xor b xor a = etc.
For example, in case of 1, 2, 3, 1, 2
1 xor 2 xor 3 xor 1 xor 2 =
(1 xor 1) xor (2 xor 2) xor 3 =
0 xor 0 xor 3 =
3
One approach would be to create a new array containing the frequency of each value. You could start by looping through your initial array to calculate the maximum value in it.
For example, the array {9,3,9,3,9,7,7,2,2,11,9} would have a maximum value of 11. With this information, create a new array that can store the frequency of every possible value in your initial array. Then, assuming there is only one integer that repeats once, return the index of the new array that has a frequency of 1. This method should run in O(n) where n is the size of the input array.
Here's an implementation:
public int solution(int[] inp)
{
int max = inp[0];
for(int i = 1; i < inp.length; i++)
{
if(inp[i] > max)
max = inp[i];
}
int[] histogram = new int[max + 1]; //We add 1 so we have an index for our max value
for(int i = 0; i < inp.length; i++)
histogram[inp[i]]++; //Update the frequency
for(int i = 0; i < histogram.length; i++)
{
if(histogram[i] == 1)
return i;
}
return -1; //Hopefully this doesn't happen
}
Hope this helps
It's hard to know why yours failed without the actual error message. Regardless, as your array input gets very large, your internal data structure grows accordingly, but doesn't need to. Instead an array of Integer as the value, we can just use one Integer:
public int solution(int[] a) {
Integer ONE = 1;
Map<Integer, Integer> map = new HashMap<>();
for (int key : a) {
Integer value = (map.containsKey(key)) ? map.get(key) + ONE : ONE;
map.put(key, value);
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue().equals(ONE)) {
return entry.getKey();
}
}
return -1;
}
I'm assuming the odd array length requirement is to avoid an array of length of two, where the items would both be unduplicated or duplicated.
Since we don't need the actual total, we can simplify this further and just consider parity. Here's a rework that does and uses the evolving new rules of this question, looking for the odd man out:
public int solution(int[] a) {
Map<Integer, Boolean> odd = new HashMap<>();
for (int key : a) {
odd.put(key, (odd.containsKey(key)) ? ! odd.get(key) : Boolean.TRUE);
}
for (Map.Entry<Integer, Boolean> entry : odd.entrySet()) {
if (entry.getValue()) {
return entry.getKey();
}
}
return 0;
}
Returns zero on failure as we now know:
A is an integer within the range [1..1,000,000,000]

choose a random value from a inverse weigthed map

I'm using a Map with eligible words for a hangman game I'm developing. The Integer in the Map stores the times a word has been chosen, so in the beginning the Map looks like this:
alabanza 0
esperanza 0
comunal 0
aprender 0
....
After some plays, the Map would look like this
alabanza 3
esperanza 4
comunal 3
aprender 1
....
I'd like to choose the next word randomly but having the less chosen word a bigger probability of been chosen.
I've read Java - Choose a random value from a HashMap but one with the highest integer assigned but it's the opposite case.
I''ve also thought I could use a list with repeated words (the more times a word appears in the list, the more the probabilities of been chosen) but I've only managed to get to this:
int numberOfWords=wordList.size(); //The Map
List<String> repeatedWords=new ArrayList<>();
for (Map.Entry<String,Integer> entry : wordList.entrySet()) {
for (int i = 0; i < numberOfWords-entry.getValue(); i++) {
repeatedWords.add(entry.getKey());
}
}
Collections.shuffle(repeatedWords); //Should it be get(Random)?
String chosenWord=repeatedWords.get(0);
I think this fails when the amount of words chosen equals the amount of words.
Edit
Finally there's a problem with the probability of each word once they have different numbers. I've changed the point of view so I first put a probability of 1000 (It could be any number) and every time I choose a word, I reduce the probability a certain amount (let's say, 20%), so I use:
wordList.put(chosen,(int)(wordList.get(chosen)*0.8)+1);
After that I choose the word with the recipe Lajos Arpad or Ahmad Shahwan gave.
If the game were to be played many many times, all the probabilities would tend to 1, but that's not my case.
Thanks all who answered.
Try this:
import java.util.Map;
import java.util.HashMap;
import java.util.Random;
public class MyClass {
public static void main(String args[]) {
Map<String, Integer> wordList = new HashMap<>();
wordList.put("alabanza", 3);
wordList.put("esperanza", 4);
wordList.put("comunal", 3);
wordList.put("aprender", 1);
Map<String, Integer> results = new HashMap<>(4);
for (int i = 0; i < 100; i++) {
String name = randomize(wordList);
Integer old = results.getOrDefault(name, 0);
results.put(name, old + 1);
}
for (Map.Entry<String, Integer> e : results.entrySet()) {
System.out.println(e.getKey() + "\t" + e.getValue());
}
}
private static String randomize(Map<String, Integer> wordList) {
final Integer sum = wordList.values().stream().reduce(Integer::sum).orElse(0);
final int grandSum = (wordList.size() - 1) * sum;
final int random = new Random().nextInt(grandSum + 1);
int index = 0;
for (Map.Entry<String, Integer> e: wordList.entrySet()) {
index += (sum - e.getValue());
if (index >= random) {
return e.getKey();
}
}
return null;
}
}
Out put is the times a name was chosen over 100 trial:
aprender 37
alabanza 25
comunal 23
esperanza 15
You can try it yourself here.
I won't provide exact code, but basic idea.
Iterate over wordList.values() to find the maximum weight M and sum of weights S.
Now let each word w have likelihood (like probability, but they don't have to sum to 1) to be chosen M + 1 - wordList.get(w), so a word with weight 1 is M times more likely to be chosen than a word with weight M.
The sum of likelihoods will be (M + 1) * wordList.size() - S (that's why we need S). Pick a random number R between 0 and this sum.
Iterate over wordList.entrySet(), summing likelihoods as you go. When the sum passes R, that's the word you want.
Your map values are your weights.
You need to pick an integer lower than the weights sum.
You pick each String entry, with its weight. When the weight sum passes the random integer, you are on THE String.
This will give you :
public static void main(String ... args){
Map<String, Integer> wordList = new HashMap<>();
wordList.put("foo", 4);
wordList.put("foo2", 2);
wordList.put("foo3", 7);
System.out.println(randomWithWeight(wordList));
}
public static String randomWithWeight(Map<String, Integer> weightedWordList) {
int sum = weightedWordList.values().stream().collect(Collectors.summingInt(Integer::intValue));
int random = new Random().nextInt(sum);
int i = 0;
for (Map.Entry<String, Integer> e : weightedWordList.entrySet()){
i += e.getValue();
if (i > random){
return e.getKey();
}
}
return null;
}
For the sake of simplicity let us suppose that you have an array called occurrences, which has int elements (you will easily translate this into your data structure).
Now, let's find the maximum value:
int max = 0;
for (int i = 0; i < occurrences.length; i++) {
if (max < occurrences[i]) max = occurrences[i];
}
Let's increment it:
max++;
Now, let's give a weight of max to the items which have 0 as value, a weight of max - 1 to the items which occurred once, and so on (no item will have a weight of 0 since we incremented max):
int totalWeight = 0;
for (int j = 0; j < occurrences.length; j++) {
totalWeight += max - occurrences[j];
}
Note that all items will have their weight. Now, let's suppose you have a randomized integer, called r, where 0 < r <= totalWeight:
int resultIndex = -1;
for (int k = 0; (resultIndex < 0) && k < occurrences.length; k++) {
if (r <= max - occurrences[k]) resultIndex = k;
else r -= max - occurrences[k];
}
and the result is occurrences[resultIndex]

Find numbers present in at least two of the three arrays

How might I approach solving the following problem:
Create an array of integers that are contained in at least two of the given arrays.
For example:
int[] a1 = new int[] { 1, 2, 3, 4, 5 };
int[] a2 = new int[] { 5, 10, 11, 8 };
int[] a3 = new int[] { 1, 7, 6, 4, 5, 3, 11 };
must give a result array
int[] result = new int[] {1, 3, 4, 5, 11}
P.S. i'm interested in suggestions on how I might approach this ("algorithm"), not what Java utils might give me the answer
put a1 numbers in a Map<Integer,Integer> count, using the value as the key, and setting the count to 1
Put a2 numbers into the same map. If an item does not exist, assign the count of 1, otherwise assign it the existing count + 1
Put a3 numbers into the same map. If an item does not exist, assign the count of 1, otherwise assign it the existing count + 1
Go through the entries in a map, and output all keys where the value is greater than one.
This algorithm is amortized linear time in the combined number of elements in the three arrays.
If the numbers in the three arrays are limited to, say, 1000 or another relatively small number, you could avoid using collections at all, but use a potentially more expensive algorithm based on the upper limit of your numbers: replace the map with an array counts[MAX_NUM+1], and then run the same algorithm, like this:
int[] counts = new int[MAX_NUM+1];
for (int a : a1) counts[a]++;
for (int a : a2) counts[a]++;
for (int a : a3) counts[a]++;
for (int i = 0 ; i != MAX_NUM+1 ; i++) {
if (counts[i] > 1) {
System.out.println(i);
}
}
You can look at the 3 arrays as sets and find each element that is in the intersection of some pair of sets.
basically, you are looking for (set1 [intersection] set2) [union] (set2 [intersection] set3) [union] (set1 [intersection] set2)
I agree that it might not be the easiest way to achieve what you are after, but being able to reduce one problem to another is a technique every programmer should master, and this solution should be very educating.
The only way to do this without collections would be to take an element from an array, iterate over the remaining two arrays to see if a duplicate is found (and then break and move to the next element). You need to do this for two out of the three arrays as by the time you move to the third one, you would already have your answer.
Mathematically this can be solved as follows:
You can construct three sets using each of the three arrays, so duplicated entries in each array will only occur once in each set. And then the entries that appear at least in two of the three sets are solutions. So they are given by
(S_1 intersect S_2) union (S_2 intersect S_3) union (S_3 intersect S_1)
Think about the question and the different strategies you might use:
Go through each entry in each array, if that entry is NOT already in the "duplicates" result, then see if that entry is in each of the remaining arrays. Add to duplicates if it is and return to next integer
Create an array of non-duplicates by adding an entry from each array (and if it is already there, putting it in the duplicates array).
Use another creative strategy of your own
I like drawing Venn diagramms. You know that diagram with three intersecting circles, e.g. see here.
You then see that the complement is easier to describe:
Those elements which only exist in one array, are not interesting.
So you could build a frequency list (i.e. key = element, value = count of in how many arrays you found it [for the first time]) in a hash map, and then in a final pass pick all elements which occured more than once.
For simplicity I used sets. If your arrays contain multiple entries of the same value, you have to ignore those extra occurences when you build the frequency list.
An approach could be like this:
1.Sort all the arrays.
2.For each combination of arrays do this
Let us consider the first two arrays A,B. Let a be A's size.
Also take a third array or vector to store our result
for i=0-->a-1 {
Search for A[i] in B using binarySearch.
if A[i] exists in B then insert A[i] into our result vector
}
Repeat the same process for (B,C) and (C,A).
Now sort & Traverse the result vector from the end, remove the elements which have the property
result[i] = result[i-1]
The final vector is the required result.
Time Complexity Analysis:
T(n) = O(nlog(n)) for Sorting where n is the highest array size among the given three
For searching each element of an array in other sorted array T(n) = n * O(log n)
T(n) = O(n (log n)) for sorting the result and O(n) for traversing
So overall time complexity is O(n log(n)); and space complexity is O(n)
Please correct me of I am wrong
In Java:
Will write one without using java.utils shortly.
Meantime a solution using java.utils:
public static void twice(int[] a, int[] b, int[] c) {
//Used Set to remove duplicates
Set<Integer> setA = new HashSet<Integer>();
for (int i = 0; i < a.length; i++) {
setA.add(a[i]);
}
Set<Integer> setB = new HashSet<Integer>();
for (int i = 0; i < b.length; i++) {
setB.add(b[i]);
}
Set<Integer> setC = new HashSet<Integer>();
for (int i = 0; i < c.length; i++) {
setC.add(c[i]);
}
//Logic to fill data into a Map
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer val : setA) {
map.put(val, 1);
}
for (Integer val : setB) {
if (map.get(val) != null) {
int count = map.get(val);
count++;
map.put(val, count);
} else {
map.put(val, 1);
}
}
for (Integer val : setC) {
if (map.get(val) != null) {
int count = map.get(val);
count++;
map.put(val, count);
} else {
map.put(val, 1);
}
}
for (Map.Entry<Integer, Integer> entry2 : map.entrySet()) {
//if (entry2.getValue() == 2) { //Return the elements that are present in two out of three arrays.
if(entry2.getValue() >= 2) { //Return elements that are present **at least** twice in the three arrays.
System.out.print(" " + entry2.getKey());
}
}
}
Change condition in last for loop in case one need to return the elements that are present in two out of three arrays. Say:
int[] a = { 2, 3, 8, 4, 1, 9, 8 };
int[] b = { 6, 5, 3, 7, 9, 2, 1 };
int[] c = { 5, 1, 8, 2, 4, 0, 5 };
Output: { 3, 8, 4, 5, 9 }
Here goes without any java.util library:
public static void twice(int[] a, int[] b, int[] c) {
int[] a1 = removeDuplicates(a);
int[] b1 = removeDuplicates(b);
int[] c1 = removeDuplicates(c);
int totalLen = a1.length + b1.length +c1.length;
int[][] keyValue = new int[totalLen][2];
int index = 0;
for(int i=0; i<a1.length; i++, index++)
{
keyValue[index][0] = a1[i]; //Key
keyValue[index][1] = 1; //Value
}
for(int i=0; i<b1.length; i++)
{
boolean found = false;
int tempIndex = -1;
for(int j=0; j<index; j++)
{
if (keyValue[j][0] == b1[i]) {
found = true;
tempIndex = j;
break;
}
}
if(found){
keyValue[tempIndex][1]++;
} else {
keyValue[index][0] = b1[i]; //Key
keyValue[index][1] = 1; //Value
index++;
}
}
for(int i=0; i<c1.length; i++)
{
boolean found = false;
int tempIndex = -1;
for(int j=0; j<index; j++)
{
if (keyValue[j][0] == c1[i]) {
found = true;
tempIndex = j;
break;
}
}
if(found){
keyValue[tempIndex][1]++;
} else {
keyValue[index][0] = c1[i]; //Key
keyValue[index][1] = 1; //Value
index++;
}
}
for(int i=0; i<index; i++)
{
//if(keyValue[i][1] == 2)
if(keyValue[i][1] >= 2)
{
System.out.print(keyValue[i][0]+" ");
}
}
}
public static int[] removeDuplicates(int[] input) {
boolean[] dupInfo = new boolean[500];//Array should not have any value greater than 499.
int totalItems = 0;
for( int i = 0; i < input.length; ++i ) {
if( dupInfo[input[i]] == false ) {
dupInfo[input[i]] = true;
totalItems++;
}
}
int[] output = new int[totalItems];
int j = 0;
for( int i = 0; i < dupInfo.length; ++i ) {
if( dupInfo[i] == true ) {
output[j++] = i;
}
}
return output;
}
It's very simple and could be done for n different arrays the same way:
public static void compute(int[] a1, int[] a2, int[] a3) {
HashMap<Integer, Integer> map = new HashMap<>();
fillMap(map, a1);
fillMap(map, a2);
fillMap(map, a3);
for (Integer key : map.keySet()) {
System.out.print(map.get(key) > 1 ? key + ", " : "");
}
}
public static void fillMap(HashMap<Integer, Integer> map, int[] a) {
for (int i : a) {
if (map.get(i) == null) {
map.put(i, 1);
continue;
}
int count = map.get(i);
map.put(i, ++count);
}
}
fun atLeastTwo(a: ArrayList<Int>, b: ArrayList<Int>, c: ArrayList<Int>): List<Int>{
val map = a.associateWith { 1 }.toMutableMap()
b.toSet().forEach { map[it] = map.getOrDefault(it, 0) + 1 }
c.toSet().forEach{ map[it] = map.getOrDefault(it, 0) + 1 }
return map.filter { it.value == 2 }.map { it.key }
}
In Javascript you can do it like this:
let sa = new Set(),
sb = new Set(),
sc = new Set();
A.forEach(a => sa.add(a));
B.forEach(b => sb.add(b));
C.forEach(c => sc.add(c));
let res = new Set();
sa.forEach((a) => {
if (sb.has(a) || sc.has(a)) res.add(a);
})
sb.forEach((b) => {
if (sa.has(b) || sc.has(b)) res.add(b);
})
sc.forEach((c) => {
if (sa.has(c) || sb.has(c)) res.add(c);
})
let arr = Array.from(res.values());
arr.sort((i, j) => i - j)
return arr

How to find the biggest three numbers in an array java?

I have an array of numbers and I need the biggest of three number with respective index value. I have an array like this:
int [] value = new int[5];
value[0] = 8;
value[1] = 3;
value[2] = 5;
value[3] = 2;
value[4] = 7;
How to find the largest numbers and their index values?
I suspsect this is homework, so I'm going to give some help, but not a full solution.
You need the biggest three numbers, as well as their index values?
Well, walk over the array, keeping track of the highest three numbers you have found so far. Also keep track of their index numbers.
You could start by doing this for only the biggest number and its index. That should be easy.
It takes two variables, e.g. BiggestNumber and indexOfBiggestNumber. Start with finding the biggest number (trivial), then add some code to remember it's index.
Once you have that, you can add some more code to keep track of the second biggest number and it's index as well.
After that, you do the same for the third biggest number.
I have done it for you, and this works.
here goes the complete code:
import java.util.Arrays;
class tester {
public static void main(String[] args) {
int[] value = new int[5];
value[0] = 8;
value[1] = 3;
value[2] = 5;
value[3] = 2;
value[4] = 7;
int size = value.length;
int[] temp = (int[]) value.clone();
Arrays.sort(temp);
for (int i = 0; i < 3; i++) {
System.out.println("value: " + temp[size - (i + 1)] +
" index " + getIndex(value, temp[size - (i + 1)]));
}
}
static int getIndex(int[] value, int v) {
int temp = 0;
for (int i = 0; i < value.length; i++) {
if (value[i] == v) {
temp = i;
break;
}
}
return temp;
}
}
No need to traverse through array and keep tracking of so many variables , you can take advantage of already implemented methods like below.
I would suggest to use a List of Map.Entry<key,value > (where key=index and value=number) and then implement Comparator interface with overridden compare method (to sort on values). Once you have implemented it just sort the list .
public static void main(String[] args) {
int[] value = {5, 3, 12, 12, 7};
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int k = 0; k < value.length; k++)
map.put(k, value[k]);
List<Map.Entry<Integer, Integer>> list =
new LinkedList<Map.Entry<Integer, Integer>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
#Override
public int compare(
Entry<Integer, Integer> e1,
Entry<Integer, Integer> e2) {
return e2.getValue().compareTo(e1.getValue());
}
});
for (Entry<Integer, Integer> lValue : list)
System.out.println("value = " + lValue.getValue()
+ " , Index = " + lValue.getKey());
}
Results:
value = 12 , Index = 2
value = 12 , Index = 3
value = 7 , Index = 4
value = 5 , Index = 0
value = 3 , Index = 1
By this approach you can get top N largest numbers with their index.
To get the three biggest, basically, you sort, and pick the last three entries.
Getting their indexes takes a little more work, but is definitely doable. Simply bundle the number and its index together in a Comparable whose compareTo function only cares about the number. Sort, get the last three items, and now you have each number and its index.
class IntWithIndex implements Comparable<IntWithIndex> {
public int number, index;
public IntWithIndex(number, index) {
this.number = number;
this.index = index;
}
public int compareTo(IntWithIndex other) {
return number - other.number;
}
}
...
IntWithIndex iwi[] = new IntWithIndex[yourNumbers.length];
for (int i = 0; i < yourNumbers.length; ++i) {
iwi[i] = new IntWithIndex(yourNumbers[i], i);
}
Arrays.sort(iwi);
int largest = iwi[iwi.length - 1].number;
int largestIndex = iwi[iwi.length - 1].index;
// and so on
Sort the array in descending order and show the first 3 element.

Categories

Resources