Here is my code snippet
import java.util.*;
public class UniqueEl
{
public static void main(String []p)
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter Array size");
int size=sc.nextInt();
//boolean ischeck=true;
int flag=0,cnt=0;
int []num=new int[size];
System.out.println("Enter Array Elements");
for(int i=0;i<size;i++)
{
num[i]=sc.nextInt();
}
System.out.println("Display Array Elements");
for(int i=0;i<size;i++)
{
System.out.println("Array Elements are :-"+num[i]);
}
System.out.println("Unique elements from the array ");
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
if(i!=j)
{
if(num[i]=num[j])
{
flag=1;
}
else
{
flag=0;
break;
}
}
}
if(flag==1)
{
cnt++;
System.out.println(num[i]+" ");
}
}
}
}
Here In this array code I have to print non-repeated integer value
Say Array value is :-[1,1,2,3,1,2,4,5] answer should be :-[3,4,5] that is non repeated integer value I have to print .Can any one help me to solve this problem
6 Answers 6
An easier approach may be to use Java 8's stream capabilities to count the number of appearances each element has, and then filter our the non-unique ones:
List<Integer> uniqueElements =
Arrays.stream(num)
.boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.filter(e -> e.getValue() == 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
Comments
Using EXOR Operation. Only works when the repeat count is Even and has only 1 unique number.
public class MyClass {
public static void main (String[] args)
{
int arr[] = { 1, 2, 5, 4, 6, 8, 9, 2, 1, 4, 5, 8, 9 };
int n = arr.length;
int v = 0;
for(int i = 0 ; i< n ; i++ ){
v = v ^ arr[i]; //XOR Operation
}
System.out.print(v);
}
}
Comments
Maybe this can be helpful:
static int[] uniqueElementsFrom(int[] arr) {
final Map<Integer, Integer> numberOfOccurences = new HashMap<Integer, Integer>();
for (int i : arr) {
if (!numberOfOccurences.containsKey(i)) {
numberOfOccurences.put(i, 1);
} else {
numberOfOccurences.put(i, numberOfOccurences.get(i) + 1);
}
}
final Set<Integer> integers = numberOfOccurences.keySet();
List<Integer> uniques = new LinkedList<Integer>();
for (int i: integers) {
if (numberOfOccurences.get(i) == 1) {
uniques.add(i);
}
}
final int[] uniqueIntsArray = new int[uniques.size()];
for (int counter = 0; counter < uniques.size(); counter++) {
uniqueIntsArray[counter] = uniques.get(counter);
}
return uniqueIntsArray;
}
Comments
If you want to correct your current code, there are just 2 problems i can see : 1. if(num[i]==num[j]), you want to do equality check, use == because = is assignment operator, and you want to compare num[i] to num[j]. 2. break from inner loop when you found a repetition of any int, i.e. flag=1. When flag=0, it means there is no repetition of this number and you are good to go. See corrected code below :
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
if(i!=j)
{
if(num[i]==num[j])
{
flag=1; //it is repeated number
break; //break the loop as we already found a repetition of this number
}
}
}
if(flag==0)
{
cnt++;
System.out.println(num[i]+" "); //here is your non-repeated number
}
}
Comments
You can use two Maps to store the found/abandoned values and therefore iterate the array only once.
The approach:
- for each element in array
- is the element indexed (already found)?
- if no index it (to a HashMap)
- if yes, remove it from index and put on abandoned list
- the results are the keys of the index map.
The code:
Set getUniqueValues(int[] numbers) {
HashMap<Integer,Boolean> numIndex = new HashMap<Integer, Boolean>();
HashMap<Integer,Boolean> abandoned = new HashMap<Integer, Boolean>();
for (int i = 0; i < numbers.length; i++) {
int currentNumber = numbers[i];
try {
// check if already abandoned and skip this iteration
if ( abandoned.get(currentNumber) != null) continue;
} catch(Exception e) {
}
boolean isInIndex;
try {
// check if it is already indexed
isInIndex = numIndex.get(currentNumber);
} catch(Exception e) {
// if not, we found it the first time
isInIndex = false;
}
if (isInIndex == false){
//so we put it to the index
numIndex.put(currentNumber, true);
}else{
// if it appeared, we abandon it
numIndex.remove(currentNumber);
abandoned.put(currentNumber, true);
}
}
return numIndex.keySet();
}
Further readings:
The maps use wrapper classes (Integer, Boolean), which are auto converted by Java:
The function returns a set, which may be converted to an array:
Comments
You can use this readable solution:
// Create a HashMap to store the count of each element
Map<Integer, Integer> countMap = new HashMap<>();
Arrays.stream(array)
.forEach(num -> countMap.put(num, countMap.getOrDefault(num, 0) + 1));
countMap.entrySet().stream()
.filter(entry -> entry.getValue() == 1)
.map(Map.Entry::getKey)
.forEach(System.out::println);
Java 8 features:
- getOrDefault:
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#getOrDefault-java.lang.Object-V-
- stream
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html