How to count 1st duplicates value in array in Java - java

I have taken array int[] a = {33,33,5,5,9,8,9,9}; In this array so many values are duplicates means 33 comes twice & 5 also comes twice & 9 comes three times.
But I want to count the first value which is duplicate means 33 is first value which comes twice so answer would be 2.
I try:
public class FindFirstDuplicate
{
public static void main(String[] args) {
int c=0;
int[] a = {33,33,5,5,9,8,9,9};
outerloop:
for(int i = 0; i < a.length; i++)
{
for(int j = i+1; j< a.length; j++)
{
if(a[i] == a[j])
{
System.out.println(a[i]); //Duplicate value
c++;
break outerloop;
}
}
}
System.out.print("Count: "+c);
}
}
Output:
33
1

public class HelloWorld{
public static void main(String[] args) {
int[] a = {33,33,5,5,9,8,9,9};
for(int i = 0; i < a.length; i++)
{
int c=1; // we already found one.
// and we initialize this counter inside the loop,
// so that it is reset for each new starting number.
for(int j = i+1; j< a.length; j++) // we're starting from next number (reason we start with c=1)
{
if(a[i] == a[j])
c++;
}
if(c > 0) {
System.out.println("First uplicate value: "+ a[i] + " Count: " + c);
break; // we have to break out of the outer loop,
// so the inner loop can finish counting duplicates
}
}
}
}

Try something like:
int[] numbers = {33, 33, 5, 5, 9, 8, 9, 9};
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i< numbers.length; i++) {
if (!set.add(number[i])) {
System.out.println("first duplicate is " + number[i] + " and index is " + i);
break;
}
}

If the values in the array are non-negative and reasonably small, you can use a BitSet to store whether or not you have seen a value previously:
BitSet bits = new BitSet();
for (int i = 0; i < numbers.length; ++i) {
if (bits.get(numbers[i])) {
System.out.println("first duplicate at " + i + ": " + numbers[i]);
break;
}
bits.set(numbers[i]);
}

You could try this out:
int[] a = {33,33,5,5,9,8,9,9};
Integer[] uniques = new Integer[a.length];
Integer[] counts = new Integer[a.length];
int len = 0;
for(int num : a){
boolean matched = false;
for(int i = 0; i < len; i++){
if(num == uniques[i].intValue()){
matched = true;
counts[i] = new Integer(counts[i]+1);
break;
}
}
if(!matched){
uniques[len] = new Integer(num);
counts[i] = new Integer(1);
len++;
}
}
for(int i = 0; i < len; i++){
if(counts[i].intValue() > 1){
System.out.println("first duplicate is " + uniques[i] + " and number of times it appears " + counts[i]);
break;
}
}

In your code you exit both loops after the first duplicate is found, so any other occurences of the element would be ignored.
Also you start with c = 0. When you get to the second occurence, c will be incremented and be 1, not 2.
To count all elements simply change the loop condition of the outer loop and remove the break:
int c = 1;
int i;
for(i = 0; (c == 1) && (i < a.length); i++)
{
for(int j = i+1; j < a.length; j++)
{
if(a[i] == a[j])
{
c++;
}
}
}
System.out.println(a[i]); //Duplicate value
System.out.print("Count: "+c); // maybe do something else, if c == 1 (no duplicates)???
However SMA's answer describes a more performant way (for arbitrary input arrays) of finding the first duplicate. Once you found the second occurence of the first duplicate, you'd only need to count the number of occurences in the rest of the array to get the final count.

Related

Why doesn't this program output one integer at the end of the loop?

So a jist of what the program needs to do is to count how many integers are greater than the average of the sum of all elements in an array. It does this as the last number it counts is the total number of integers greater than average. However, it also shows the number of times it has looped. For example, if the number of integers is supposed to be 3, it will show, 1,2,3. That's fine but the 1,2, the part is not necessary, just the 3. This is the only way I have found possible but is there a better way?
import java.util.Scanner;
public class Sparky
{
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
int sum =0;
int n;
do
{
System.out.print("Enter integer n, greater than 0: ");
n = kbd.nextInt();
}while(n < 1);
System.out.println();
int[] arr = new int[n];
System.out.println("Array on one line: ");
for(int i = 0; i < arr.length; i++)
{
arr[i] = (int) (Math.random() * 500) + 1;
System.out.print(arr[i] + " ");
}
int max = arr[0];
for(int i = 1; i < arr.length; i++)
{
if(arr[i] > max)
{
max = arr[i];
}
}
System.out.println();
{
double x = 0;
double y;
for(int i = 0; i < arr.length; i ++){
x = arr[i] + x;
}
y = x / arr.length;
System.out.println("Average: " + y);
System.out.println("Number of integers greater than average: ");
int count = 1;
for(int i = 0; i < arr.length; i ++)
{
if(arr[i] > y)
{
System.out.print(count + ",");
count ++;
}
}
}
}
}
Change the last section of your code from this :
for(int i = 0; i < arr.length; i ++)
{
if(arr[i] > y)
{
System.out.print(count + ",");
count ++;
}
}
To this :
for(int i = 0; i < arr.length; i ++)
{
if(arr[i] > y)
{
count ++;
}
}
System.out.print(count);
It should print the number of integers greater than average.
Xerox's answer was good, but I noticed a bug in your code. If you start count at 1, your count will be off. Also, I thought I'd show you how to use a foreach loop. So I made some updates to your code, ran it, and added comments for you. Remember, short variable names were used in the 80s because they took up disk space and slowed down processing time when they were larger. That's no longer an issue, and if your variable names are cryptic, your code is difficult to read, even when it's simple. You'll notice that your code is much easier to read with descriptive variable names and a foreach loop. I left the rest of the file for you to do if you are interested.
import java.util.Scanner;
public class Sparky {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
int n;
do {
System.out.print("Enter integer n, greater than 0: ");
n = kbd.nextInt();
} while (n < 1);
System.out.println();
int[] arr = new int[n];
System.out.println("Array on one line: ");
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 500) + 1;
System.out.print(arr[i] + " ");
}
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
System.out.println();
{
double x = 0;
double average; //Better to have readable variables. "y" means nothing, "average" is clear, especially in the next section.
for (int i = 0; i < arr.length; i++) {
x = arr[i] + x;
}
average = x / arr.length;
System.out.println("Average: " + average);
int numberGreaterThanAverage = 0; //This needs to start at 0 or your count will be off. Also, name the variable what it does. Short variable names help no one.
for (int number: arr) { //This is called a foreach loop. It does the same thing as your loop, but is much each to read, also I renamed "i", short for "iterator" to "number" which is what it actually is, a number in the array.
if (number > average) {
numberGreaterThanAverage++;
}
}
System.out.println("Number of integers greater than average: " + numberGreaterThanAverage); //This needed to be moved out of the loop, and it also could be concatenated with the rest of the text to put it all on one line.
}
kbd.close(); //You need to close this or you can get a memory leak
}
}
Always consider printing statements after you are done with modifying the values, best is to print outside the loop.
In this case, Count is being printed before it is incremented, on the last iteration of the loop, it increments and quits the loop.
for(int i = 0; i < arr.length; i ++)
{
if(arr[i] > y)
{
// System.out.print(count + ","); count is being printed before it is incremented
count ++;
}
}
System.out.print(count + ","); //Should be printed **after** the loop ends.

DeleteZero's using Java

I need to finish this code which involves deleting all the zero's stored in the array. I thought it was complete but it won't compile, it's my last line that is dubios and I'm not getting right. Thank you.
public class DeleteZero {
public static int[] array(int[] a) {
int k = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] !=0)
k++;
}
int[] b = new int[k];
int t = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
b[t] = a[i];
t++;
}
}
return b;
}
public static void main (String args[]) {
int[] rand = new int[20];
for (int i = 0; i < 20; i++) {
rand[i] = (int)(Math.random());
}
System.out.println(array(a));
}
}
Few errors.
This would always insert 0 at rand[i] because you are casting Math.random() to int which will always become zero.
rand[i] = (int)(Math.random());
Change it to sth like this. I have written 10 but you can write any number to define the range.
rand[i] = (int)(Math.random()*10);
This line is also wrong:
System.out.println(array(a));
You need to print the array by looping over it, but more importantly your function array() returns a new array, which should be stored somewhere before printing it.
Here is a possible workaround
rand = array(rand);
for (int i=0; i<rand.length; i++){
System.out.println(rand[i]);
}
The compile time error is due to the fact that, in the main method you have created the array named rand and passing the array named a. from the main method call System.out.print(array(rand))
You can try Java 8's Stream, which turns the whole logic to one line return Arrays.stream(a).filter(n -> n!= 0).toArray();
Little fixed your code:
import java.util.Random; // Import Random
public class DeleteZero {
public static int[] array(int[] a) {
int k = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] !=0)
k++;
}
int[] b = new int[k];
int t = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
b[t] = a[i];
t++;
} else {
System.out.println("Skip at position: [" + i + "] because a[i] == "+a[i]+";"); // Display what removed.
}
}
return b;
}
public static void main (String args[]) {
int[] rand = new int[20];
Random rnd = new Random();
for (int i = 0; i < 20; i++) {
rand[i] = rnd.nextInt(11) + 0; // 11-1 = max, 0 = min
}
int[] a = array(rand);
System.out.println(a); // since it prints something like this: [I#106d69c, we should print all elements manually through a loop.
System.out.println("a.length = " + a.length + ", rand length: " + rand.length);
System.out.print("[");
for (int i = 0; i != a.length; i++) {
String space = ", ";
if (i == a.length-1) //if last not print space
space = "";
System.out.print(a[i]+space); // Print all elements
}
System.out.print("]\n");
}
}
Example of output:
Skip at position: [2] because a[i] == 0;
Skip at position: [8] because a[i] == 0;
Skip at position: [10] because a[i] == 0;
Skip at position: [12] because a[i] == 0;
Skip at position: [16] because a[i] == 0;
[I#106d69c
a.length = 15, rand length: 20
[6, 8, 1, 8, 7, 1, 3, 5, 3, 8, 5, 2, 7, 2, 8]

Removing duplicate characters in a String array

I have a sample input like [q w e r r t] and I want to remove duplicates and print [q w e r t] with arrays. I don't see why the output is different for the below code snippet.
for(int j=0; j< array.length; j++) {
for(int k=j+1; k< array.length; k++) {
if(array[j] == array[k]) {
continue;
}
System.out.print(array[j] + " ");
j = k;
}
}
Update: I wanted to use this logic for a sorted array. I used Arrays.sort(). I changed == to .equals() for Strings.
public static void main(String args[]) throws IOException {
// Enter size of array and assert the type of input
System.out.println("Enter size of array in integers");
Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt()) {
System.out.println("Please enter integers");
sc.next();
}
;
// Accepting the values into the array and sorting them
int demoInt = sc.nextInt();
String[] array = new String[demoInt];
String[] outputMarkers = new String[demoInt];
System.out.println("Enter the values");
for (int i = 0; i < array.length; i++) {
Scanner scNum = new Scanner(System.in);
array[i] = scNum.next();
if (i == array.length - 1) System.out.println("Array is full");
}
Arrays.sort(array);
System.out.printf("Sorted array is : %s", Arrays.toString(array));
//Checking for duplicates //Sample: a a a s d f
for (int j = 0; j < array.length; j++) {
for (int k = j + 1; k < array.length; k++) {
if (array[j].equals(array[k])) {
continue; //returns to for loop with increment
}
System.out.print(array[j] + ". ");
j = k;
}
}
}
Input: a a a d f
Output: a d f
Your problem is that you are checking each character against all the characters after it. Imagine an array with no duplicates; once you get to the last character, you have printed out all the characters before it. But when j = array.length - 1, then k = array.length, and the second for loop does not run at all, and your last character will never be printed.
Your code would always fail to print the last element correctly. The only case in which it would be correct is if your last element is a duplicate of a previous element, but not of the second-to-last element.
Try this code instead:
outerloop:
for (int j = 0; j < array.length; j++) {
for(int k = 0; k < j; k++) {
if(array[j] == array[k]) {
continue outerloop;
}
}
System.out.print(array[j] + " ");
}
The premise of the code is that it loops through each of the characters. If it matches any of the previous characters, the code skips that element and continues to the next one.
EDIT: Looks like you edited the question for a sorted array instead. That means if the last element is a duplicate, it will be a duplicate of the element before it so we don't have to worry about the corner case in my previous block of code.
for(int j=0; j< array.length; j++) {
for(int k=j+1; k< array.length; k++) {
if(array[j] == array[k]) {
continue;
}
System.out.print(array[j] + " ");
j = k;
}
}
System.out.print(array[array.length-1] + " ");
If you are looking to remove the values rather than just skip over them when printing, you will want to start from the end of your array and work towards 0, calling array.remove(i) when you find an object that matches a previously checked object.
Though that is just to do it as a loop exercise. It would be easier to push your array into a Set.
You can use a Boolean array of size 122, make all the values in the array as false, iterate the give character array, if the ASCII value of character is false, thena make it true and print it.
Below is the example code, here I have taken a string and removing all the duplicates and printing the resulting string:
static String removeDuplicate(String s) {
boolean[] flagArr = new boolean[122];
int sLength = s.length();
StringBuilder resultStr = new StringBuilder();
for (int i = 0; i < sLength; i++) {
char tempChar = s.charAt(i);
int tempVal = (int) tempChar;
if (!flagArr[tempVal]) {
flagArr[tempVal] = true;
resultStr.append(tempChar);
}
}
return resultStr.toString();
}
The complete code is at
Removing Duplicate Characters From String Without Using Set | jain Tarun Blog
Why not use only one loop ?
//assuming array has length >= 2
System.out.print(array[0] + " ");
for(int j=1; j< array.length; j++) {
if(array[j] == array[j - 1]) {
continue;
}
System.out.print(array[j] + " ");
}

Basic array - Java

I need to make 2 arrays called A and B, both of type int with size 100. Each index should be a random number between 0 and 100 inclusive and then compare both arrays, and say how many times 2 of the same number appeared in both arrays.
This is what I have so far
int count = 0;
int [] A = new int [100];
int [] B = new int [100];
for(int i = 0; i < A.length; i++){
A [i] = (int)(Math.random()*101);
System.out.println("Array A: " + i);
}
for(int i = 0; i < B.length; i++){
B [i] = (int)(Math.random()*101);
System.out.println("Array B: " + i);
}
if(A [i] == B [i]){
count++;
}
I'm not sure how to show how many times 2 of the same number appeared in both arrays.
You need to loop through both of the arrays:
int count = 0;
int [] A = new int [100];
int [] B = new int [100];
for(int i = 0; i < A.length; i++){
A [i] = (int)(Math.random()*101);
System.out.println("Array A: " + i);
}
for(int i = 0; i < B.length; i++){
B [i] = (int)(Math.random()*101);
System.out.println("Array B: " + i);
}
// Loop through the first array
for(int i = 0; i < A.length; i++) {
// For each element in the first array, loop through the whole second one
for (int j = 0; j < B.length; j++) {
// If it's a match
if(A[i] == B[j])
count++;
}
}
System.out.println("Count: " + count);
Alternatively, if you don't need the 2 arrays, you can simply do:
int count = Random.ints(100, 0, 101).boxed().collect(toSet())
.retainAll(Random.ints(100, 0, 101).boxed().collect(toSet()))
.size();
You started off nicely, but you need a nested for-loop to check each of the indexes.
ALSO-- make sure that in your arrays you print out A[i] and B[i] otherwise you're just printing out the number of the index as opposed to the number inside the index.
int count = 0;
int[] A = new int[100];
int[] B = new int[100];
//Create the first array
for (int i = 0; i < A.length; i++) {
A[i] = (int)(Math.random() * 101);
System.out.println("Array A: " + A[i]);
}
//Create the second array
for (int i = 0; i < B.length; i++) {
B[i] = (int)(Math.random() * 101);
System.out.println("Array B: " + B[i]);
}
//Check the indexes and make sure they are all compared-- 10,000 comparisons are made
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
if(A[i] == B[j])
count++;
}
}
Hopefully that posted correctly... first time posting code on this website, but I hope that I was of help!
Keep in mind if the same number is being posted twice, you're going to get counts over 100.
Good luck!

If statements in 2D arrays

When I am trying to run this code it shows java.lang.ArrayIndexOutOfBoundsException Error. Please help me to fix this code.
import java.util.*;
class Example {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
Random r = new Random();
final int N, S;
System.out.print("Input No of Students : ");
N = input.nextInt();
System.out.print("No of Subject : ");
S = input.nextInt();
int[][] st = new int[N][S];
int[] stNo = new int[N];
int[] stMax = new int[N];
for (int i = 0; i < N; i++) {
stNo[i] = r.nextInt(10000);
for (int j = 0; j < S; j++) {
st[i][j] = r.nextInt(101);
}
}
// Find max Value of marks of a Student
for (int i = 0; i < N; i++) {
for (int j = 0; j < S; j++) {
if (st[i][j] > st[i][j + 1]) {
stMax[i] = st[i][j + 1];
}
}
}
// Display marks
// Dispaly Column names
System.out.print("stNo\t");
for (int i = 1; i < S + 1; i++) {
System.out.print("Sub " + i + "\t");
}
System.out.print("Max");
// Print Values
for (int i = 0; i < N; i++) {
System.out.print(stNo[i] + "\t");
for (int j = 0; j < S; j++) {
System.out.print(st[i][j] + "\t");
}
System.out.print(stMax[i]);
System.out.println();
}
}
}
The error is
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: (here shows the input for "S")
at pack1.Example.main(Example.java:31)
As I am a new to coding I can not fix this. Please help me to fix this.
Thanks
An ArrayIndexOutOfBoundsException error means you exceed the boundaries of the array. In your case, st has S colomns and you tried to reach the S+1-th element (index S).
st[i][j + 1] => when j == S-1 (the end of the loop), you do an out of bounds.
Now, as your comment say, you're looking for the max value. Then the code should be:
stMax[i] = 0;
for (int j = 0; j < S; j++) {
if (st[i][j] > stMax[i]) {
stMax[i] = st[i][j];
}
}
What your code is doing is comparing the current value to the next one. And every time the next value is greater than the current one, you update stMax[i]. This does not make sense.
This line is causing the exception:
stMax[i] = st[i][j + 1];
You are iterating j to the end of the array, and always looking for the next element. So when j reaches the end of the array it is still looking for one more index, hence the outOfBoundsException.

Categories