Reputation: 2140
I have the following code:
import java.util.Scanner;
public class ArrayDuplicates {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("How many numbers are you going to enter? ");
int num = scan.nextInt();
int[] arr = new int[num]; // initialize array with user inputted length
for (int i = 0; i < arr.length; i++) { // enter numbers into array
arr[i] = scan.nextInt();
}
int[] unique = new int[arr.length]; //initialize new array that will hold unique values
for (int i = 0; i < arr.length; i++) {
boolean b = true; //boolean that checks if an element is a duplicate
for (int j = i+1; j < arr.length; j++) { //check all elements above int i
if (arr[i] == arr[j]) {
b = false; // set b to false if there is an existing duplicate
}
}
if (b) {
unique[i] = arr[i]; // if no duplicates exist, then it is unique.
}
}
for (int i = 0; i < unique.length; i++) {
System.out.println(unique[i]);
}
}
}
The problem with this code (aside from being horribly slow for large arrays, but that's not the point) is that since the undeclared elements for the unique
array will be set to 0
, the duplicate elements from the first array are being set to 0
in unique[]
(if that makes any sense). I understand why this happens, but cannot find an efficient way to fix this. I tried setting the duplicate elements to Integer.MIN_VALUE
in the unique array and then printing only the elements of unique[]
which are not equal to Integer.MIN_VALUE
, but that seems like a weak solution to the problem. How can I fix this problem?
EDIT: If I run the code:
How many numbers are you going to enter? 4
1
2
2
0
Output:
1
0
2
0
Since the second element of the array is a duplicate, I do not set unique[1]
to any value, making it default to 0. How do I avoid printing that 0, since it is not part of the original array?
EDIT 2: Yes, this is homework, but the reason I don't want to use sets, sorting, etc. is primarily that I am not familiar with them. Also, as I am not asking anyone to write the entire program for me, I think it's fine to ask for a little help.
Upvotes: 3
Views: 17006
Reputation: 21
I tried to improved this code, please comments/suggest if further improvement can be done.
public static int[] removeDuplicate(int[] arr) {
int[] noDuplicates = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
boolean b = true;
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]){
b = false;
}
}
if (b) {
noDuplicates[i] = arr[i];
System.out.print(noDuplicates[i] + " ");
}
}
return noDuplicates;
}
Upvotes: 0
Reputation: 41
public class RemoveDuplicateFromArray {
public static void main(String[] args) {
int[] myArray = {1, 2, 1, 4, 1, 5, 2, 5};
System.out.println("Before removing duplicate" + Arrays.toString(myArray));
RemoveDuplicateFromArray rd = new RemoveDuplicateFromArray();
int[] newArray = rd.findDuplicate(myArray);
System.out.println("Before removing duplicate" + Arrays.toString(newArray));
}
public int[] findDuplicate(int[] inputArray) {
Arrays.sort(inputArray);
int count = 0;
for (int i = 0; i < inputArray.length; i++) {
if (i + 1 < inputArray.length && inputArray[i] == inputArray[i + 1]) {
count++;
}
}
int[] result = new int[inputArray.length - count];
int c = 0;
for (int j = 0; j < inputArray.length; j++) {
if (j + 1 < inputArray.length && inputArray[j] == inputArray[j + 1]) {
} else {
result[c] = inputArray[j];
c++;
}
}
inputArray = result;
return inputArray;
}
}
Upvotes: 0
Reputation: 195
Example with String [].
public static List<String> arrListWithNoDups(String arr[]){
Map<String, Integer>map = new HashMap<String, Integer>();
List<String>list = new ArrayList<String>();
for(int i = 0; i<arr.length; i++){
if(map.get(arr[i]) == null){
map.put(arr[i], 0);
}
else{
map.put(arr[i], map.get(arr[i])+1);
}
}
for(int j = 0; j<arr.length; j++){
if(map.get(arr[j])==0){
list.add(arr[j]);
}
}
return list;
}
Upvotes: 0
Reputation: 1
Create a parallel character array with all the values as '.' Whenever you find a duplicate, set the value to a ',' in the character array. Then Print only the values of your array that have a corresponding '.' in the character array.
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
if(a[i]=='.')
System.out.println(arr[i]);
}
}
}
Upvotes: 0
Reputation: 15
void myFunction(int arr[])
{
int size=arr.length;
for(int i=0;i<size;i++)
{
for(int j=i+1;j<size;j++)
{
if(arr[i]==arr[j])
{
arr[j]=arr[size-1];
size--;
}
}
}
for(int a=0;a<size;a++)
{
System.out.print(arr[a]+" ");
}
}
Upvotes: -2
Reputation: 1323
This solution allows you to enter any integer value even negative. It's your same code with some modifications and has added a parallel array for comparisons. It has also removed some lines of code that are no longer needed.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("How many numbers are you going to enter? ");
int num = scan.nextInt();
int[] arr = new int[num]; // initialize array with user inputted length
int[] arrflag = new int[num];
for (int i = 0; i < arr.length; i++) { // enter numbers into array
System.out.print("Enter number: ");
arr[i] = scan.nextInt();
arrflag[i] = 0;
}
int[] unique = new int[arr.length]; //initialize new array that will hold unique values
int n=0;
for (int i = 0; i < arr.length; i++) {
if (arrflag[i] == 0) {
unique[n++] = arr[i];
for (int j = i+1; j < arr.length; j++) { //check all elements above int i
if (arr[i] == arr[j]) {
arrflag[j]=-1;
}
}
}
}
for (int i = 0; i < n; i++) {
System.out.println(unique[i]);
}
}
Upvotes: 1
Reputation: 718826
Any value that you choose (zero, min-int, max-int) to represent a removed duplicate is a problem. The user could always enter that number, and your program wouldn't behave correctly. (The only way you could legitimately use (say) min-int or max-int would be if the requirements clearly said that that number was invalid input.)
The correct way to deal with duplicates is to keep a counter of the number of non-duplicates, and make sure that the duplicates (or slots that would contain them) are at the high end of the array; i.e. indexes >= the counter. (That becomes an invariant that your algorithm needs to maintain ...)
The best solution is to eliminate the duplicates before you add them to the array. Keep a count of the number of non-duplicates and iterate until that reaches your num
... rather than the length of the array.
But if you do want to add all values to the array and then eliminate the duplicates, when you find a duplicate you need to swap elements so that you can maintain the invariant. The logic is a little bit fiddly ... but quite doable.
UPDATE
I just noticed that your original solution was using two arrays. I assumed that you were using one array, and doing an in-place update to eliminate the duplicates.
Upvotes: 4
Reputation: 188
You can store the maximum value entered by user (while the user is entering the values in the first loop) and then make the default value for unique equals to max + 1.
Or you can try another approach for solving the problem, something like this:
int num = scan.nextInt();
int[] arr = new int[num];
int[] uniq = new int[num+1000000];
int j = 0;
// enter numbers into array
for (int i = 0; i < arr.length; i++) {
int input = scan.nextInt();
if(uniq[input] != 1){
uniq[input] = 1;
arr[j] = input;
j++;
}
}
for (int i = 0; i < j; i++) {
System.out.println(arr[i]);
}
Note that this solution is under the assumption that the user will not enter a number greater than (num + 1,000,000)
.
Upvotes: 1
Reputation: 620
I am going to use the tools that you used to solve the problem, cuz something in me is telling me this is homework...
import java.util.Scanner;
public class ArrayDuplicates
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.print("How many numbers are you going to enter? ");
int num = scan.nextInt();
int[] arr = new int[num]; // initialize array with user inputted length
for (int i = 0; i < arr.length; i++)// enter numbers into array
{
arr[i] = scan.nextInt();
}
double[] unique = new double[arr.length]; //initialize new array that will hold unique values
///////My edit
for(int z = 0; z < unique.length; z++)
{
unique[z] = -0.5;
}
///////
for (int i = 0; i < arr.length; i++)
{
boolean b = true; //boolean that checks if an element is a duplicate
for (int j = i+1; j < arr.length; j++) //check all elements above int i
{
if (arr[i] == arr[j])
{
b = false; // set b to false if there is an existing duplicate
}
}
if (b)
{
unique[i] = arr[i]; // if no duplicates exist, then it is unique.
}
}
for (int i = 0; i < unique.length; i++)
{
if(!(unique[i] == -0.5))
{
System.out.println((int)(unique[i]));
}
}
}
}
So, you see where I commented out my edit? that's the new thing, a very easy way to check is to give the values a number that is not expected, in this case, a negative number. Now, that is an assumption on my part, change -1 to whatever value you know will not be entered into that Scanner
. Same for the if statement.
Upvotes: 3
Reputation: 7824
The best way to do this is to use a Map.
public interface Map<K,V>
An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
I don't know why you would not want to use a set unless you are doing homework...
If you really can't use a set. Go ahead and create an ArrayList
. Store the elements of the array
inside, but everytime you want to store you check if the element is already part of the ArrayList
.
int [] list = {5, 5, 3, 2, 5, 3, 5};
ArrayList<Integer> list2 = new ArrayList<Integer>();
for(int i = 0; i < list.length; i++)
if(!list2.contains(list[i]))
list2.add(list[i]);
You can, if you want, turn your ArrayList
back into an array.
Object[] list3 = list2.toArray();
Upvotes: 2