How do I get a unique number in array [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
number = {5,3,5,5,5,6,6,9,3,3};
How do I get a unique number which is not duplicated in array?
What I want to get
9
My code is below
int[] list = {5,3,5,5,5,6,6,9,3,3};
Arrays.sort(list);
for(int i = 0; i < list.length; i++){
for(int j = i+1; j < list.length; j++){
if(list[i] == list[j]){
break;
}
}
}

This is a brute force approach but can solve you problem.
public static int GetUnique(int val){
int count = 0;
int[] list = {5,3,5,5,5,6,6,9,3,3};
for(int i = 0; i < list.length; i++){
for(int j = i+1; j < list.length; j++){
if(list[i] == list[j]){
count++;
}
}
if(count == 1)
return list[i];
count = 0;
}
return 0
}

Efficient way of finding non repeating elements from given array would be by using hash tables:
Construct a hash table consisting of element and it's occurrence count by traversing the given array
Map<Integer, Integer> hashTable = new HashMap<>();
for(int i = 0; i < list.length; i++) {
if(hashTable.containsKey(list[i])) {
hashTable.put(list[i], hashTable.get(list[i]) + 1);
} else {
hashTable.put(list[i], 1);
}
}
Once the hash table is ready, then any desired operations on it can be performed. For example: If first non repeating number is to be found, then a simple iteration on the given list would suffice:
for(int i = 0; i < list.length; i++) {
if(hashTable.get(list[i]) == 1) {
System.out.println(list[i]);
break;
}
}
Time complexity of this approach is O(n)

You can also use Java Stream API:
Integer[] list = {5,3,5,5,5,6,6,9,3,3,13};
Map<Integer, Long> counts = Arrays.stream(list)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
int[] uniqueValues = counts.entrySet().stream().filter(e -> e.getValue().equals(1L)).mapToInt(Map.Entry::getKey).toArray();
Output:
[9, 13]
This is what happened:
First, numbers have been grouped by occurrences in format: number: occurrences of number:
3: 3 occurrences
5: 4 occurrences
6: 2 occurrences
9: 1 occurrence
13: 1 occurrence
In next step we filter above groups by leaving only numbers with 1 occurrence and mapping result into final array

If list[i-1] != list[i] and list[i]!=list[i+1] Then, it's necessary to manage start and end of the array, otherwise arrayIndexOutOfBoundsException raise.
int[] list = {3,3,5,6,6,9,9,15};
Arrays.sort(list);
for(int i = 0; i <list.length; i++){
if( (i==0 && (list[i]!=list[i+1])) || ((i>0) && (list[i]!=list[i-1]) && (( i==list.length-1) || (list[i+1]!=list[i]))) ){
System.out.println(list[i]);
break;
}
}

Related

Find number of duplicate that occurs in array - Java

I can't wrap my head around this. Need to find duplicates and I did. All now that is left is to print how many times a duplicate appears in the array. I just started with Java,so this needs to be hard coded for me to understand. Spend last two days trying to figure it out but with no luck.. Any help will be great! Talk is cheap,here is the code..
import java.util.Arrays;
public class LoopTest {
public static void main(String[] args) {
int[] array = {12,23,-22,0,43,545,-4,-55,43,12,0,-999,-87};
int positive_counter = 0;
int negative_counter = 0;
for (int i = 0; i < array.length; i++) {
if(array[i] > 0) {
positive_counter++;
} else if(array[i] < 0) {
negative_counter++;
}
}
int[] positive_array = new int[positive_counter];
int[] negative_array = new int[negative_counter];
positive_counter = 0;
negative_counter = 0;
for (int i = 0; i < array.length; i++) {
if(array[i] > 0) {
positive_array[positive_counter++] = array[i];
} else if(array[i] < 0) {
negative_array[negative_counter++] = array[i];
}
}
System.out.println("Positive array: " + (Arrays.toString(positive_array)));
System.out.println("Negative array: " + (Arrays.toString(negative_array)));
Arrays.sort(array);
System.out.println("Array duplicates: ");
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if(array[i] == array[j]) {
System.out.println(array[j]);
}
}
}
}
}
Since you are already sorting the array you can find the duplicates with just one loop (they will be next to each other right?). So you can do something like:
Arrays.sort(array);
System.out.println("Array duplicates: ");
int lastValueCount=1; //How many times we met the current value (at least 1 - this time)
for (int i = 1; i < array.length; i++){
if(array[i] == array[i-1])
lastValueCount++; //If it is the same as the previous increase the count
else {
if(lastValueCount>1) //If it is duplicate print it
System.out.println(array[i-1]+" was found "+lastValueCount+" times");
lastValueCount=1; //reset the counter
}
}
Result for your array is:
Array duplicates:
0 was found 2 times
12 was found 2 times
43 was found 2 times
Also you can use some of the Java bells and whistles like inserting the values into Map or something like that but I guess you are looking from an algorithmic point of view so the above is the simple answer with just one loop
Just go through your solution, first you separate positive and negative numbers in two different arrays, then you never use them, so what's the purpose of this separation ?
I am giving you just an idea related to your problem, it's better to solve it by your self so that you can get hands on Java.
Solution: you can use Dictionary-key value pair. Go through your array, put element in dictionary as a key and value as zero, on every iteration check if that key already exist in Dictionary, just increment its value. In the end, all of the values are duplicates that occurs in your array.
Hope it helps you.
From the algorithmic point of view, Veselin Davidov's answer is good (the most efficient).
In a production code, you would rather write it like this :
Map<Integer, Long> result =
Arrays.stream(array)
.boxed() //converts IntStream to Stream<Int>
.collect(Collectors.groupingBy(i -> i, Collectors.counting()));
The result is this Map :
System.out.println(result);
{0=2, 545=1, -4=1, -22=1, -87=1, -999=1, -55=1, 23=1, 43=2, 12=2}
An easy way would be using Maps. Without changing code too much:
for (int i = 0; i < array.length; i++) {
int count = 0;
for (int j = i + 1; j < array.length; j++) {
if(array[i] == array[j]) {
System.out.println(array[j]);
count++;
}
}
map.put(array[i], count);
}
Docs:
https://docs.oracle.com/javase/7/docs/api/java/util/Map.html
Edit: As a recommendation, after you are done with the example, you should analize your code and find what isnĀ“t neccesary, what could be done better, etc.
Are all your auxiliary arrays neccesary? Are all loops necessary?
You can do it by creating an array list for duplicate values:-
Arrays.sort(array);
System.out.println("Array duplicates: ");
ArrayList<Integer> duplicates = new ArrayList<Integer>();
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if(j != i && array[i] == array[j] && !duplicates.contains(array[i])){
duplicates.add(array[i]);
System.Out.println(duplicates[duplicates.size()-1]);
}
}
}
public static void findDuplicate(String s){
char[] charArray=s.toCharArray();
ArrayList<Character> duplicateList = new ArrayList<>();
System.out.println(Arrays.toString(charArray));
for(int i=0 ; i<=charArray.length-1; i++){
if(duplicateList.contains(charArray[i]))
continue;
for(int j=0 ; j<=charArray.length-1; j++){
if(i==j)
continue;
if(charArray[i] == charArray[j]){
duplicateList.add(charArray[j]);
System.out.println("Dupliate at "+i+" and "+j);
}
}
}
}

Java - Result not outputting correctly [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to finish a program that displays the average, hottest, & coldest temperatures of the week, and also displays which days are the hottest and coldest. The user enters in 7 temperatures from Sun - Sat. It is almost working but it seems as though there is a bug in the method near the bottom called searchTemp, this method sees how many times the highest/lowest temperature occurred in the array of temperatures, and then creates an array of size needed, and then it iterates over all the values, storing the indexes at which the high/low temperatures occurred in the original array, it then returns the new array with the values of the index locations. Ideally I would map these values to an array containing the strings Sunday through Saturday and print out all the days that the temperature was the highest or lowest. The issue is that right now if the user enters say 18 for the highest and then they enter 18 again, instead of the program outputting something like "Monday Wednesday" it outputs Wednesday Wednesday"
Can anyone help me?
public static int[] searchTemp(int[] array, int key) {
int count = 0;
for(int i = 0; i < array.length; i++) {
if(array[i] == key)
count++;
}
int[] indices = new int[count];
for(int j = 0; j < indices.length; j++) {
for(int i = 0; i < array.length; i++) {
if(array[i] == key)
indices[j] = i;
}
}
return indices;
}
}
The searchTemp should be changed as following:
public static int[] searchTemp(int[] array, int key) {
int count = 0;
for(int i = 0; i < array.length; i++) {
if(array[i] == key)
count++;
}
int[] indices = new int[count];
for(int j = 0; j < indices.length; j++) {
for(int i = 0; i < array.length; i++) {
if(array[i] == key) {
if(j > 0 && indices[j - 1] == i){
continue;
}
else {
indices[j] = i;
break;
}
}
}
}
return indices;
}
This will return the correct hottest/coldest.
Hope this help!
I believe it is here
int[] indices = new int[count];
for(int j = 0; j < indices.length; j++) {
for(int i = 0; i < array.length; i++) {
if(array[i] == key)
indices[i] = i; <---------
}
}
should be
indices[j] not i as you are using the inner array's length on this.

No duplicates in an array [duplicate]

This question already has answers here:
How to get unique values from array
(13 answers)
Closed 8 years ago.
void RemoveDups(){
int f=0;
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
{
arr[k]=arr[k+1];
}
nelems--;
}
if(i==(nelems+1)){
f++;
i=f+1; //increment again
}
}
}
This is the logic i have written to remove duplicate elements from an array ,but this is not working at all ?what changes i should make to make it work? or you people have better logic for doing the same considering time complexity.and i don't want to use built-in methods to achieve this.
int end = input.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (input[i] == input[j]) {
int shiftLeft = j;
for (int k = j + 1; k < end; k++, shiftLeft++) {
input[shiftLeft] = input[k];
}
end--;
j--;
}
}
}
I think you can use Set Collection
copy all the values to an HashSet and then using Iterator access the Values
Set<Integer> hashset= new HashSet<Integer>();
You have two options, C# has the Distinct() Linq expression that will do this for you (Missed the Java tag), however if you need to remove items, have you thought about sorting the list first, then comparing the current item to the previous item and if they're the same, remove them. It would mean your diplicate detection is only ever running through the array once.
If you're worried about sort you could easily implement an efficient bubble sort or somthing to that effect
You never decrease i after You compared for examlpe arr[0] to arr[5], You never will test arr[1] == arr[2]
You need to start a new loop (i) after You've incremented f.
try
for(int f=0;f<nelems-1;f++)
{
for(int i=f+1;i<nelems;i++)
{
...
}
}
with this nested for loop you can compare every two element of the array.
a good start is to eliminate duplicate elements without shrinking the array which is done lastly:
public class run2 extends Thread {
public static void main(String[] args) {
int arr[] = { 1, 2, 2, 3, 5, 6, 5, 5, 6, 7 };
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] == -1)
j++;
if (arr[i] == arr[j])
arr[j] = -1;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == -1) {
for (int j = i; j < arr.length; j++) {
if (arr[j] != -1) {
arr[i] = arr[j];
arr[j] = -1;
break;
}
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
Adapt this code :
public static int[] removeDuplicates(int[] numbersWithDuplicates) {
// Sorting array to bring duplicates together
Arrays.sort(numbersWithDuplicates);
int[] result = new int[numbersWithDuplicates.length];
int previous = numbersWithDuplicates[0];
result[0] = previous;
for (int i = 1; i < numbersWithDuplicates.length; i++) {
int ch = numbersWithDuplicates[i];
if (previous != ch) {
result[i] = ch;
}
previous = ch;
}
return result;
}
As far as I understood from your code,you are comparing each value starting from index 0 to the rest of the element and when you see the element which is located at index f your are trying to shift the entire array and decrementing the size of array(nelems).Look at line no. 11
if(i==(nelems+1)){
f++;
i=f+1;
The problem is when i is set to f+1,i will again be incremented in the for loop for the next iteration.So basically i starts comparing from f+2.And also you are comparing i with (nelems+1) considering the case when nelems decremented but you are not considering the case when i reaches the end without decreasing nelems in that case i will never be equale to (nelems+1).Now considering your logic you could do 2 things.
1.Here is your working code.
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i+1;k<nelems;k++)
{
arr[k-1]=arr[k];
}
if(i==(nelems-1)){
f++;
i=f;
}
nelems--;
}
if(i==(nelems-1)){//end of the loop
f++;
i=f; //increment again
}
}
2.You could use an outer for loop alternatively that will increment the f value once the inner for is completed.
void RemoveDups(){
for(int f=0;f<nelems;++f){
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
arr[k]=arr[k+1];
nelems--;
}
}
}
}
Now your problem is solved but the time complexity of your code will be(O(N^3)).
Now instead of shifting the entire array at line 4,you could just swap the arr[f] with last element.
if(arr[f]==arr[i]){
swap(arr[f],arr[nelems-1]);
nelems--;
}
it will reduce the time complexity from O(N^3) to O(N^2).
Now I'll suggest you my method
1.just sort the array.It will be done in O(NlogN).
2.now using one for loop you can get what do you wanted.
void RemoveDups(){
int k=0,i;
for(i=1;i<nelems;++i){
while(arr[i]==arr[i-1])
++i;
arr[k++]=arr[i-1];
}
arr[k++]=arr[i-1];
}
Now basically you got an array of size k,which contains non repeated element in sorted order and the time complexity of my solution is O(NlogN).

Java Union array of 2 int arrays using nested loops [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I want to create a union array for two integer arrays using nested loops.
This is my attempt so far:
import java.util.Scanner ;
public class array4 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter first array size:");
int size = input.nextInt();
int x[] = new int[size];
System.out.println("Enter first array elements:");
for (int i = 0; i < size; i++) {
x[i] = input.nextInt();
}
System.out.print("Enter second array size:");
int size2 = input.nextInt();
int y[] = new int[size2];
for (int i = 0; i < size2; i++) {
y[i] = input.nextInt();
}
System.out.println("Union");
for (int i = 0; i < size; i++) {
System.out.println(x[i]);
}
for (int i = 0; i < size2; i++) {
for (int z = 0; z < size; z++) {
if (y[i] != x[z]) {
System.out.println(y[i]);
}
}
}
}
}
Lets assume that we will print all numbers from second array, and only these numbers from first array which don't exist in second one. So
for each element in first array
test if it exist in second array (iterate over elements in second array and set some boolean flag like exists to true if x[i]==y[j])
if element doesn't exist in second array print it
iterate over elements from second array
and print them
Algorithm can look like
for (int i = 0; i <= x.length; i++) {// "<=" is not mistake,
// in last iteration we print all elements
// from second array
boolean exist = false;
for (int j = 0; j < y.length; j++) {
if (i < x.length) {
if (x[i] == y[j])
exist = true;
} else
System.out.println(y[j]);
}
if (!exist && i < x.length)
System.out.println(x[i]);
}
This algorithm can be probably rewritten to something simpler but I will leave it in this form for now.
For the lack of requirements, here is my answer for now... just basing on your current code.
for (int i = 0; i < size2; i++) {
for (int z = 0; z < size; z++) {
if (y[i] != x[z]) {
System.out.println(y[i]);
break; //added break
}
}
}
The problem was you're printing array elements without duplicate multiple times, to avoid that, you should add a break after you print the element with no duplicate.
By the way, your code is just printing the elements on both arrays, I thought you're suppose to combine them? Shouldn't you have a new array that contains both of the elements on the two arrays?
EDIT 2:
Add these lines of code after you get the two set of arrays without duplicate:
I also added comments to explain what's happening.
System.out.println("Union");
int[] unionArray = new int[size + size2]; //created a new array that will contain two arrays
for (int i = 0; i < size; i++) { //put the first set of int in the new array
unionArray[i] = x[i];
}
for (int i = size; i < unionArray.length; i++) { //put the second set
unionArray[i] = y[i-size]; //i = size : started with the last index of the first array
//y[i-size] : we are getting the elements on the second array
}
for (int i = 0; i < unionArray.length; i++) { //output
System.out.println(unionArray[i]);
}
Hope this helps. :)
If it's just to play with arrays and you don't need to use loops - try using a Java collection for that task, that's how most people would probably implement it:
init collection 1 from array 1
init collection 2 from array 2
add collection 2 to collection 1
convert collection 1 back to an array
That can be a (more or less) neat one-liner.

Java Programming Challenge Code Not Working [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have been given a challenge to do witH Java and one of the questions I keep getting the wrong answer the question is:
What is the sum of all of the palindromic numbers that are the products of two 2-digit or 1-digit numbers?
Edit:
So I basically need code that will work out the sum of all palindromes who can be made from 2 numbers either 2-digit or 1-digit.
package projects;
import java.util.ArrayList;
public class Project3 {
public static void main(String[] args) {
new Project3();
}
public Project3(){
ArrayList<Integer> numbers = new ArrayList<Integer>();
//generate 1-9
for(int i = 1; i < 10; i++){
numbers.add(i);
}
//generate 11-99
for(int i = 10; i < 100; i+=10){
numbers.add(i + (i / 10));
}
//generate 100-999
for(int i = 100; i < 1000; i+=100){
for(int j = 1; j < 10; j++){
numbers.add(i + (j*10) + (i / 100));
}
}
//generate 1000 - 9999
for(int i = 1000; i < 10000; i+=1000){
for(int j = 1; j < 10; j++){
numbers.add(i + (j * 100) + (j * 10) + (i / 1000));
}
}
boolean product = false;
for(int i = 0; i < numbers.size(); i++){
product = false;
for(int j = 99; j >= 1; j--){
if(numbers.get(i).intValue() % j == 0){
product = true;
break;
}
}
if(product == false){
numbers.remove(i);
}
}
int total = 0;
for(int i = 0; i < numbers.size(); i++){
total += numbers.get(i);
System.out.println(numbers.get(i) + "\t\t" + total);
}
System.out.println(total);
}
public String reverse(String thing){
String reversed = "";
char[] array = thing.toCharArray();
for(int x = thing.length() - 1; x >= 0; x--){
reversed += array[x];
}
return reversed;
}
}
Edit:
I am trying to ask what/where my program is going wrong and what I could do to get a program that will give me th right answer.
Your logic goes wrong when you are checking for divisibility in the following loop:
for(int j = 99; j >= 1; j--){
if(numbers.get(i).intValue() % j == 0){
product = true;
break;
}
Here you are just checking if the palindrome is divisible by a number between 1-99 but you are not worried about the other factor of the palindrome.
Example:
Let the palindrome be 2222.
When checking for its divisibility (inside 'j' loop), it is divisible by 22 and hence you are including it in the list, where as the other factor is 101 which is not a 2-digit/1-digit number.
You have to eliminate all such cases.
So instead of following this algorithm, it is better if you follow the algorithm in a reverse way as mentioned by few users above.
You try to create all the palindromic numbers and then check whether they are a product of some numbers. Instead, try it the other way around. You already have a reverse function, so just do this:
int counter = 0;
for (int i = 0; i < 100; i++) {
for (int k = i; k < 100; k++) {
String s = String.valueOf(i * k);
if (s.equals(reverse(s))) counter++;
}
}
Just one potential problem:
for(int i = 0; i < numbers.size(); i++){
...
if(product == false){
numbers.remove(i);
}
}
This might skip numbers. Consider the list N,P,* (where N is a non-product palidrome, P is a product palindrome and * is any palindrome). i is 0 and since N is a non-product palidrome it will be removed and your list now is P,*. Now i will be increased to 1 and thus the i-th element is *. P will be skipped - ouch.
To fix that, you might collect the palindromes into another set/list/collection and leave numbers unchanged.
Alternatively iterate backwards, i.e. for( i = numbers.size(); i >= 0; i--).
A thirds option would be to use an iterator, e.g. for( Iterator<Integer> itr = numbers.iterator(); itr.hasNext(); ) { ... } and then itr.next() and itr.remove().
Btw, you might want to use for a foreach loop whenever the value of i is not relevant, e.g. for(Integer number : numbers )
Edit: changed the example from 10,11,12 to 65,66,67 to reduce confusion. Please note that it's still an example and not necessarily based on your actual data.
Edit 2: I changed the example to something more abstract to avoid (or generate? ;) ) further confusion. Since I can't currently think of a sequence of a non-product palindrome followed by a product palindrome (product here means matching the requirement of being a product of 2 one- or two-digit numbers), I changed it to N,P,*.
I'll restate the point of my potential bug answer: when you iterate forward using indices and remove elements at the current or a lower index, you would skip elements, so don't do that unless you want that exact behavior.

Categories

Resources