I am trying to loop through my array and find all the numbers that are repeating more than once:
E.G: if there is 1 1 2 3 4
It should print saying "1 repeats more than once"
Here is my code and so far what I have tried, however it prints all duplicates and keep going, if there is 4 4 4 4 3 6 5 6 9, it will print all the 4's but i dont want that:
class average {
public static void main(String[] args) throws IOException {
int numOfLines = 0;
int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
int[] buffer;
File myFile = new File("num.txt");
Scanner Scan = new Scanner(myFile);
while(Scan.hasNextLine()) {
Scan.nextLine();
numOfLines++;
}
Scan.close();
Scan = new Scanner(myFile);
System.out.println("Number Of Lines: " + numOfLines);
buffer = new int[numOfLines];
for(int i=0; i<numOfLines; i++) {
buffer[i] = Scan.nextInt();
}
Scan.close();
Scan = new Scanner(myFile);
for(int i=0; i<buffer.length; i++) {
sum = sum+i;
mean = sum/numOfLines;
}
System.out.println("Sum: " + sum);
System.out.println("Mean: " + mean);
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
System.out.println(buffer[k]);
}
}
}
Just add the number you will find duplicated to some structure like HashSet or HashMap so you can find it later when you will detect another duplication.
Set<Integer> printed = new HashSet<Integer>();
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
Integer intObj = new Integer(buffer[k]);
if (!printed.contains(intObj)) {
System.out.println(buffer[k]);
printed.add(intObj);
}
break;
}
}
}
Better O(n) alghorithm:
Set<Integer> printed = new HashSet<Integer>();
for(int i=0; i<buffer.length; i++) {
if (!printed.add(new Integer(buffer[i])) {
System.out.println(buffer[i]);
}
}
You perform the check for every single item of the array, including the first 4, the second 4 and so on. That's why it just doesn't stop and it prints the message multiple times per duplicated element.
You're saying you cannot use a Set and that you don't want to sort your data. My suggestion is that you loop over the array and add each duplicated item to a list. Make sure you check whether the item has already been added. (or use a Set :) )
Then loop over the list and print those items.
I would use a HashMap to store the value I encounter in the array, with the count as a value. So if you encounter a 4, you would look it up in the HashMap, if it doesn't exist, you would add it with a value of 1, otherwise increment the value returned.
You can the loop over the HashMap and get all the values and print the number of duplicates encountered in the array.
Integer[] ints = {1, 1, 2, 3, 4};
System.out.println(new HashSet<Integer>(Arrays.asList(ints)));
Output: [1, 2, 3, 4]
This problem is much simpler and likely faster to solve using a collection. However, as requested here's an answer that uses "just simple array[s]" and no sorting. I've tried not to change your code too much but I refuse to leak resources in the case of an exception.
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
class Average {
public static void main(String[] args) throws IOException {
int numOfLines = 0;
int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
int[] buffer;
int flag = -1;
File myFile = new File("num.txt");
try (Scanner Scan = new Scanner(myFile)) {
while(Scan.hasNextLine()) {
Scan.nextLine();
numOfLines++;
}
}
try (Scanner Scan = new Scanner(myFile)) {
System.out.println("Number Of Lines: " + numOfLines);
buffer = new int[numOfLines];
for(int i=0; i<numOfLines; i++) {
buffer[i] = Scan.nextInt();
}
}
for(int i=0; i<buffer.length; i++) {
sum = sum+i;
mean = sum/numOfLines;
}
System.out.println("Sum: " + sum);
System.out.println("Mean: " + mean);
//copy every duplicate
int[] dupesOnly = new int[numOfLines];
int dupesOnlyIndex = 0;
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
dupesOnly[dupesOnlyIndex++] = buffer[i];
//System.out.println(buffer[k]);
}
}
}
//mark all but first occurrence of dupe
boolean[] skip = new boolean[dupesOnlyIndex]; //Inits to false
for (int i = 0; i < dupesOnlyIndex; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(dupesOnly[k] == dupesOnly[i]) {
skip[k] = true;
}
}
}
//skip elements marked as extra dupes
int[] dupesUnique = new int[dupesOnlyIndex];
int dupesUniqueIndex = 0;
for (int i = 0; i < dupesOnlyIndex; i++) {
if (skip[i] == false) {
dupesUnique[dupesUniqueIndex++] = dupesOnly[i];
}
}
//trim to size
int[] dupesReport = new int[dupesUniqueIndex];
for (int i = 0; i < dupesReport.length; i++) {
dupesReport[i] = dupesUnique[i];
}
System.out.println("Dupes: " + Arrays.toString(dupesReport));
}
}
Input file "num.txt" (numbers separated by newlines not commas):
1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3
Output:
Number Of Lines: 14
Sum: 91
Mean: 6
Dupes: [1, 2, 3, 7]
Using the apache commons CollectionUtils.getCardinalityMap(collection):
final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
final List<Integer> list = Arrays.asList(buffer);
final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(list);
for (final Map.Entry<Integer, Integer> entry: cardinalityMap.entrySet()) {
if (entry.getValue() > 1) {
System.out.println(entry.getKey());
}
}
toString() of cardinalityMap looks like this after the init:
{1=4, 2=2, 3=2, 4=1, 5=1, 6=1, 7=2, 9=1}
Using standard java:
final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
final List<Integer> list = Arrays.asList(buffer);
final Set<Integer> set = new LinkedHashSet<Integer>(list);
for (final Integer element: set) {
if (Collections.frequency(list, element) > 1) {
System.out.println(element);
}
}
Related
I need to write a program, which deletes a number of elements from an int array that are equal to some int value. Eventually I should get an array that isn't bigger than the initial one.
I mustn't use lists or any methods that do the deletion directly.
I tried to do this this way and I can't trace the flaw. I suppose, it should be in the last "for" construction but I'm not sure.
import java.util.Arrays;
import java.util.Scanner;
public class App {
public static void main(String\[\] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Array size: ");
int sizeInput = scan.nextInt();
int[] original = new int[sizeInput];
System.out.print("Array itself: ");
for (int i = 0; i < sizeInput; i++) {
original[i] = scan.nextInt();
}
System.out.println("Number to be deleted: ");
int dNumber = scan.nextInt();
int[] newArr = new int[original.length];
for (int i = 0; i < original.length - 1; i++) {
int sum = 0;
if (original[i] == dNumber) {
newArr[i] = original[i + 1];
sum = sum + 1;
} else if (original[i] != dNumber) {
newArr[i] = original[i + sum];
}
}
System.out.println(Arrays.toString(newArr));
}
}
and here's what I got in my console eventually:
Array size: 5
Array itself: 1 2 3 4 5
Number to be deleted: 2
\[1, 3, 3, 4, 0\]
You see? In the output I get the second "3" for some reason and I also don't get why there's no last element of the initial array.
Please, explain what wrote wrong so that my code doesn't solve the problem. And please explain ho can I solve It. Thanks!
You need a position int for the new array, so you go further only when you set a new value
int[] original = {1, 2, 3, 4, 5};
int dNumber = 2;
int[] newArr = new int[original.length];
int j = 0;
for (int val : original) {
if (val != dNumber) {
newArr[j] = val;
j++;
}
}
newArr = Arrays.copyOf(newArr, j); // truncate
System.out.println(Arrays.toString(newArr));
// [1, 3, 4, 5]
I'm trying to figure out how to take in an integer and rearrange them so that every alternating character is saved (So the [1, 2, 3, 4, 5, 6] would return [1, 4, 2, 5, 3, 6]). I think a queue would be the best to use for this problem so here's what I have so far. It returns [3, 1, 4, 5, 2, 6], but I'm not sure how I can get it to return the alternating form above :
import java.util.*;
public class everyOtherInteger {
public static void main(String[] args) {
Queue <Integer> sort = new LinkedList<Integer>();
String s = "123456";
for (int i = 0; i < s.length(); i++) {
sort.add(Integer.parseInt(s.charAt(i) + ""));
if (i%2 == 0) {
int a = sort.remove();
sort.add(a);
}
else {
}
}
System.out.println(sort);
}
}
Just build the list differently. No queue required.
You can add half the numbers at the start, the add the rest in-between each.
List<Integer> nums = new ArrayList<>();
Scanner sc = new Scanner(System.in);
int limit = sc.nextInt(); // 6
int value = 1;
for (int i = 0; i < limit / 2; i++) {
nums.add(value++);
}
for (int i = 1; i < limit; i+=2) {
nums.add(i, value++);
}
System.out.println(nums); // [1, 4, 2, 5, 3, 6]
I would just add them one after the other in a single loop. The second element is simply the current one plus the offset where the offset is half the array length.
read in the number as a string.
and work with the character array of digits.
Scanner input = new Scanner(System.in);
String val = input.next();
List<Integer> result =new ArrayList<>();
char[] digits = val.toCharArray();
int half = digits.length/2;
for(int i = 0; i < half; i++) {
result.add(digits[i]-'0');
result.add(digits[i+half]-'0');
}
System.out.println(result);
For an input of 123456, prints
[1, 4, 2, 5, 3, 6]
Write a program to print all the LEADERS in the array. An element is leader if it is greater than all the elements to its right side. And the rightmost element is always a leader. For example int the array {16, 17, 4, 3, 5, 2}, leaders are 17, 5 and 2.
Let the input array be arr[] and size of the array be size.
o/p what i am getting is 2 5 17
Note: i want o/p in reverse order , also one below other(line break).
class LeadersInArray
{
/* Java Function to print leaders in an array */
void printLeaders(int arr[], int size)
{
int max_from_right = arr[size-1];
/* Rightmost element is always leader */
System.out.print(max_from_right + " ");
for (int i = size-2; i >= 0; i--)
{
if (max_from_right < arr[i])
{
max_from_right = arr[i];
System.out.print(max_from_right + " ");
}
}
}
public static void main(String[] args)
{
LeadersInArray lead = new LeadersInArray();
int arr[] = new int[]{16, 17, 4, 3, 5, 2};
int n = arr.length;
lead.printLeaders(arr, n);
}
}
Expected output:
17
5
2
Intead of printing those within the loop, add those to a list, and then print those separately.
Following are the changes in your code.
class LeadersInArray {
List<Integer> printLeaders(int[] arr, int size) {
List<Integer> list = new ArrayList<>();
int max_from_right = arr[size - 1];
list.add(max_from_right);
for (int i = size - 1; i >= 0; i--) {
if (max_from_right < arr[i]) {
max_from_right = arr[i];
list.add(max_from_right);
}
}
return list;
}
public static void main(String[] args) {
LeadersInArray lead = new LeadersInArray();
int arr[] = new int[]{16, 17, 4, 3, 5, 2};
List<Integer> integers = lead.printLeaders(arr, arr.length);
for(int i = integers.size()-1; i>=0 ;i--){
System.out.println(integers.get(i));
}
}
}
I am trying to print duplicate elements in one d array using for each loop. But my output was an unexpected one. Could anyone please assist?
package Login;
public class DupsArray {
static int[] a = {1,2,3,3};
public static void main(String[] args) {
int length = a.length;
for(int i=0;i<=length-1;i++) {
for(int j : a) {
for(j=1;j<=length-1;j++) {
if(a[i]==(a[j]) ) {
System.out.println("Found duplicate");
} else {
System.out.println("No duplicates found");
}
}
}
}
}
The results show as follows:
The expected results to be print duplicate found.
Try using the below logic which compares every element with all other element in the array, if any duplicate is found,it stops the execution to continue futher
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("Found duplicate");
return;
}
}
}
System.out.println("No duplicate Found");
We can do something like this
Integer[] arr = {1, 2, 3, 3, 5, 5, 7, 8, 7};
Set<Integer> set = new HashSet<Integer>();
for (Integer i : arr) {
if (set.add(i) == false)
{
System.out.println(i);
}
}
try this and update as per your requirement
public class Main{
public static void main(String[] args) {
int[] ar = new int[] {1, 1, 3, 3, 4, 5, 7, 8};
int size = ar.length;
int error = 0;
for(int i = 0; i < size; i++){
for(int j = i+1; j < size; j++){
if(ar[i] == ar[j]){
if(i != j){
error = error + 1;
System.out.println("dulicate element " + j);
}
}
}
}
System.out.println("total number of duplicate element " + error);
}
}
You can use Sets like that :
Integer[] a = {1, 2, 3, 3, 5, 5, 7, 8, 7};
Set<Integer> duplicatesSet = new HashSet<>();
Set<Integer> helperSet = new HashSet<>();
for (Integer element : a) {
if (!helperSet.add(element)) { // NOTE*
System.out.println("Duplicate found : " + element);
duplicatesSet.add(element);
}
}
Then you can do whatever you like with the duplicates set
for(Integer el : duplicatesSet){
System.out.println(el);
}
Note*
According to javadocs :
boolean add(E e);
Adds the specified element to this set if it is not already present
return true if this set did not already contain the specified element
This way we can know if the element is already in the set, if it is we can add it to our duplicates.
My program is supposed to take a provided array and create a new array where each element is the sum of the previous elements in original array. For example element one in new array is element one in original array. Element two in new array is sum of element one an element two in original array. Element three in new array is sum of elements one, two and three in original array. I wrote this but I know it is incomplete. Please guide.
public class PrefixSum
{
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int x = 0;
for(int i = 0; i < array.length; i++)
{
x = array[i];
x = x + i;
}
newArray[0] = 0;
System.out.println(" " + newArray[x]);
}
}
You can use a variable runningTotal to keep count of the running total like so:
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int[] originalArray = new int[]{0,5,1,-3,2,0,4};
int[] sumArray = new int[originalArray.length];
int runningTotal = 0;
for(int i = 0; i < originalArray.length; i++){
runningTotal += originalArray[i];
sumArray[i] = runningTotal;
}
System.out.println("The originalArray is: " + Arrays.toString(originalArray));
System.out.println("The sumArray is: " + Arrays.toString(sumArray));
}
}
Output:
The originalArray is: [0, 5, 1, -3, 2, 0, 4]
The sumArray is: [0, 5, 6, 3, 5, 5, 9]
Try it here!
You may Debug this code in order to understand the changes.
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int x = 0;
for(int i = 0; i < array.length; i++)
{
x += array[i];
newArray[i] = x;
}
}
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int sum = 0;
for(int i = 0; i < array.length; i++)
{
sum += array[i];
newArray[i]= sum;
System.out.println(" " +newArray[i]);
}
}
List<Integer> sums = new ArrayList<>();
Stream.of(0, 5, 1, -3, 2, 0, 4).reduce((left, right) -> {
sums.add(left + right);
return left + right;
});
Printing sums after running yields :
[0, 5, 6, 3, 5, 5, 9]
Try it here.