Need advice on parsing out duplicates in Java - java

I have an assignment that requires that I create two arrays (with user defined length) full of random numbers between 1-100, then merge the two arrays without duplicates in alternating order. I just need help merging the two without any repeating numbers. Can anyone help? Thanks!
import java.util.Scanner;
import java.lang.Math;
class Main {
public static void main(String[] args){
Scanner scan = new Scanner (System.in);
int f=0;
int j=0;
int k=0;
//getting first array length and making array1 and array2 that length
while (f==0){
System.out.println("Enter an array length (must be 10 or greater):");
int length = scan.nextInt();
if (length < 10){
f=0;
}
else{
f=1;
}
if (f==1){
int [] array1 = new int[length];
int [] array2 = new int[length];
int [] array3 = new int[length*2];
System.out.print("First Array: ");
//creating random integers between 1 and 100 inclusive to fill array1
for (int i=0; i<=length-1; i++){
int x = (int)(Math.random()*100)+1;
array1[i] = x;
System.out.print(x+" ");
}
//creating random integers between 1 and 100 inclusive to fill array2
System.out.print("\nSecond Array: ");
for (int i=0; i<=length-1; i++){
int y = (int)(Math.random()*100)+1;
System.out.print(y+" ");
array2[i] = y;
}
//combining both arrays
System.out.print("\nMerged Array: ");
for (int i=0; i<=length*2-1; i++){
if ((i==0) || (i%2==0)){
array3[i] = array1[j];
j++;
}
else{
array3[i] = array2[k];
k++;
}
System.out.print(array3[i]+" ");
}
}
}
}
}

First, let's extract your method to fill arrays.
static int[] fillRandomArray(int n) {
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = (int) (Math.random() * 100) + 1;
System.out.print(arr[i] + " ");
}
System.out.println();
return arr;
}
Now you can simplify your code to use that method, and your merge is very close; you don't need j or k in each case you are indexing by half of i (the cases being even or odd). Like,
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("Enter an array length (must be 10 or greater):");
int length = scan.nextInt();
if (length >= 10) {
System.out.print("First Array: ");
// creating random integers between 1 and 100 inclusive to fill array1
int[] array1 = fillRandomArray(length);
// creating random integers between 1 and 100 inclusive to fill array2
System.out.print("\nSecond Array: ");
int[] array2 = fillRandomArray(length);
// combining both arrays
System.out.print("\nMerged Array: ");
int[] array3 = new int[array1.length + array2.length];
for (int i = 0; i < array3.length; i++) {
if (i % 2 == 0) {
array3[i] = array1[i / 2];
} else {
array3[i] = array2[i / 2];
}
System.out.print(array3[i] + " ");
}
System.out.println();
}
}
If you actually need to eliminate duplicates between array1 and array2 while you merge, then you can't assume that the output array will be double the input length. I would use a Set. Like,
// combining both arrays
System.out.print("\nMerged Array: ");
Set<Integer> set = new LinkedHashSet<>();
for (int i = 0; i < array1.length + array2.length; i++) {
if (i % 2 == 0) {
if (set.add(array1[i / 2])) {
System.out.print(array1[i / 2] + " ");
}
} else {
if (set.add(array2[i / 2])) {
System.out.print(array2[i] + " ");
}
}
}
// If you actually need an int[]
int[] array3 = set.stream().mapToInt(Integer::intValue).toArray();

Related

What is the best way to read user inputs via scanner?

I use some approaches similar to the following one in Java:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] a= new int[3];
//assign inputs
for (int i=0;i<3;i++)
a[i] = scan.nextInt();
scan.close();
//print inputs
for(int j=0;j<3;j++)
System.out.println(a[j]);
}
However, generally the first input parameter is length and for this reason I use an extra counter (c) in order to distinguish the first element. When using this approach, the scanner does not read inputs one by one and checking the first and other elements in two blocks seems to be redundant.
// input format: size of 3 and these elements (4, 5, 6)
// 3
// 4 5 6
public static void getInput() {
int n = 0; //size
int c = 0; //counter for distinguish the first index
int sum = 0; //
int[] array = null;
Scanner scan = new Scanner(System.in);
System.out.println("Enter size:");
//block I: check the first element (size of array) and assign it
if (scan.nextInt() <= 0)
System.out.println("n value must be greater than 0");
else {
n = scan.nextInt();
array = new int[n];
}
System.out.println("Enter array elements:");
//block II: check the other elements adn assign them
while(scan.hasNextInt() && c<n) {
if (scan.nextInt() >= 100) {
System.out.println("Array elements must be lower than 100");
} else {
array[c] = scan.nextInt();
c++;
}
}
scan.close();
int sum = 0;
for (int j = 0; j < n; j++) {
sum += array[j];
}
System.out.println("Sum = " + sum);
}
My question is "how can I modify this approach with a single block (while and for loop inside while)? I tried 5-6 different variations but none of them works properly?"
Hope this helps,
public static void getInput() {
int n; //size
int c = 0; //counter for distinguish the first index
int sum = 0; //
int[] array;
Scanner scan = new Scanner(System.in);
System.out.println("Enter size:");
//check the first element (size of array) and assign it
n = scan.nextInt();
while(n <= 0)
{
System.out.println("n value must be greater than 0");
System.out.println("Enter size:");
n = scan.nextInt();
}
array = new int[n];
System.out.println("Enter array elements:");
// check the other elements and assign them
while(c<n) {
int num = scan.nextInt();
if (num >= 100) {
System.out.println("Array elements must be lower than 100");
} else {
array[c++] = num;
}
}
scan.close();
for (int j = 0; j < n; j++) {
sum += array[j];
}
System.out.println("Sum = " + sum);
}
Output:
Enter size:
-1
n value must be greater than 0
Enter size:
4
Enter array elements:
1
2
3
4
Sum = 10
I've optimized your code and fixed some bug.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter size:");
int n = scan.nextInt();
if (n <= 0) {
System.out.println("n value must be greater than 0");
return; // need to break from here
}
int c = 0;
int sum = 0; // no need for array
System.out.println("Enter array elements:");
// check the other elements and assign them
while (c++ < n) {
int next = scan.nextInt();
if (next >= 100) {
System.out.println("Array elements must be lower than 100");
c--; // ensure can reenter the number
} else {
sum += next;
}
}
scan.close();
System.out.println("Sum = " + sum);
}

How to output multiple values being stored into an array using a for loop on the same line?

I created my arrays and when I am entering the values for the arrays, they are being shown on separate lines for example...
Enter the values for the first array: 75
48
23
I would like the numbers to be shown on the same line and not sure how to do it. Thank you for your help.
public class CompareArrays
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int arraySize;
System.out.print("Enter the array size: ");
arraySize = input.nextInt();
int[] array1 = new int[arraySize];
int[] array2 = new int[arraySize];
System.out.print("Enter the values for the first array: ");
for(int i = 0; i < arraySize; i++) {
array1[i] = input.nextInt();
}
System.out.print("Enter the values for the second array: ");
for(int i = 0; i < arraySize; i++) {
array2[i] = input.nextInt();
}
if(Compare(array1, array2)) {
System.out.println("Judgement: \t The arrays are identical");
}else {
System.out.println("Judgement: \t The arrays are not identical");
}
input.close();
}
public static boolean Compare(int[] array1, int[] array2)
{
for (int i = 0; i < array1.length; i++) {
if(array1[i] != array2[i]) {
return false;
}
}
return true;
}
}
When in the console inputting those values you are hitting enter which is why it looks like it is on different lines. If you want to input the values on 1 line you could possibly input them as a string and split it.
If you're looking to just print the array on one line you can do that with a basic for loop and using System.out.print().
int[] a = {1, 2, 3, 4};
for(int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}

Bubblesort random Array Java

I'm very new to java and have been playing around with sorting algorithms. I have the following code working for a set array. I was just wondering what I'd need to change to get it to sort arrays of randoms lengths and integers. I guess the answer is pretty obvious any help is appreciated!
public static void main(String[] args) {
int number[]={8,5,3,2,9};
int temp;
boolean fixed=false;
while(fixed==false){
fixed=true;
for(int i=0; i<number.length-1 ; i++){
if(number[i] > number[i+1]){
temp = number[i+1];
number[i+1]=number[i];
number[i]=temp;
fixed=false;
}
}
}
for(int i=0; i<number.length; i++)
System.out.println(number[i]);
}
}
I mean, your algorithm would work regardless of the array's length. About how to generate such arrays, you could do this:
int n = Math.random()*10000 + 1; //so its never 0.
int number[] = new int[n];
for(int i=0;i<n;i++) number[i]=Math.random()*10000;
Everything else stays the same :).
EDIT: You commented on the question that you'd rather generate the array by taking an input from the keyboard. You can do that by using a scanner.
Scanner scanIn = new Scanner(System.in);
do{
int n = scanIn.nextInt();
} while (n<1);
int number[] = new int[n];
for(int i=0;i<n;i++) number[i] = scanIn.nextInt();
scanIn.close();
What you are looking for is probably a method to extract your bubblesort to. Please note that this method changes the input array and does not return a new array.
private static void bubblesort(int[] array) {
int temp;
boolean fixed = false;
while (!fixed) {
fixed = true;
for (int i = 0; i < array.length - 1; i++) {
if (array[i] > array[i + 1]) {
temp = array[i + 1];
array[i + 1] = array[i];
array[i] = temp;
fixed = false;
}
}
}
}
You can then call it using different approaches.
Fixed size array:
// fixed size array
int number[] = {8, 5, 3, 2, 9};
bubblesort(number);
System.out.println(Arrays.toString(number));
Read numbers from System.in.
// read from sys.in like "2 6 4"
Scanner s = new Scanner(System.in);
String line = s.nextLine();
int[] parsedInts = Arrays.stream(line.split("\\s+")).mapToInt(Integer::parseInt).toArray();
bubblesort(parsedInts);
System.out.println(Arrays.toString(parsedInts));
You can the use Scanner Class in java and need to import java.util.Scanner class
Scanner sc = new Scanner(System.in);
System.out.println("Enter the array length :");
int n = sc.nextInt();
int number[] = new int[n];
System.out.println("Enter the numbers :");
for(int i = 0; i < number.length; i++) {
number[i] = sc.nextInt();
}

Write a method that rotates a one-dimensional array with one position to the right in such a way that the last element becomes the first element.

I think I confused the methods and can't get the actual methods correct. Please help, the array needs to rotate to the right where the first digit will become the last digit. I generate a random array based on size that the user input. Then I print that array, then do the rotation, then print the new array with the first digit last and the last digit first.
import java.util.Scanner;
import java.util.Random;
public class modOne {
public static final int MIN = 1;
public static final int MAX = 15;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int arraySize = 0;
System.out.println("How many arrays to rotate right?");
int howMany = input.nextInt();
while(howMany <= 0) {
System.out.println("ERROR! Should be positive. REENTER: ");
howMany = input.nextInt();
}
while(howMany > 0) {
System.out.println("Enter array size: ");
arraySize = input.nextInt();
}
int[] a = new int[arraySize];
int[] b = new int[arraySize];
getRand(a, MIN, MAX);
System.out.println("The array before rotation: ");
printArray(a);
System.out.println("THe array after rotation: ");
transArray(a);
printArray(b);
System.out.println("Enter array size: ");
arraySize = input.nextInt();
}
public static void getRand (int[] list, int size, int low, int up) {
Random rand = new Random();
for(int r = 0; r < size; r++) {
list[r] = rand.nextInt(up - low + 1) + low;
}
}
public static void printArray(int[] list, int size) {
for (int r = 0; r < size; r++) {
System.out.printf("%5d", list[r]);
if(r % 6 == 5)
System.out.println();
}
System.out.println();
}
public static void transArray(int[] list, int size) {
for(int r = 0; r < size - 1; r++) {
list[r] = list[r-1];
}
}
}
You can make use of System.arrayCopy to copy sourceArray from start index to destination array from start index. You can also specify how many elements should e copied as last argument to System.arrayCopy method. See below:
int[] arr = new int[]{8, 15, 2,10, 11,15,1,3};
System.out.println("array before rotation: " + Arrays.toString(arr));
int lastElement = arr[arr.length -1 ];
System.arraycopy(arr, 0, arr, 1, arr.length-1);
arr[0] = lastElement;
System.out.println("array after rotation: " + Arrays.toString(arr));
I backup the last element and then copy the array entirely in a new array skipping the first element of the array and then I assign the first element of the array with the value that I backup early.
The output you get is as follow:
array before rotation: [8, 15, 2, 10, 11, 15, 1, 3]
array after rotation: [3, 8, 15, 2, 10, 11, 15, 1]
For more details on how System.arrayCopy works, you can see the following tutorial or read my answer in this question.
You just have to invert the order and save the value you are going to overwrite to recover it later. I also took the liberty to make some other changes to your code. Now it should work as intended.
while (howMany <= 0) {
System.out.println("ERROR! Should be positive. REENTER: ");
howMany = input.nextInt();
}
System.out.println("Enter array size: ");
arraySize = input.nextInt();
int[] a = new int[arraySize];
int[] b = new int[arraySize];
getRand(a, MIN, MAX);
System.out.println("The array before rotation: ");
printArray(a);
System.out.println("THe array after rotation: ");
printArray(transArray(a));
}
public static void getRand(int[] list, int low, int up) {
Random rand = new Random();
for (int r = 0; r < list.length; r++) {
list[r] = rand.nextInt(up - low + 1) + low;
}
}
public static void printArray(int[] list) {
for (int r = 0; r < list.length; r++) {
System.out.printf("%5d", list[r]);
if (r % 6 == 5) {
System.out.println();
}
}
System.out.println();
}
public static int[] transArray(int[] list) {
int temp1 = list[list.length - 1];
for (int r = list.length - 1; r > 0; r--) {
list[r] = list[r-1];
}
list[0] = temp1;
return list;
}
What you can do is use Arrays.copyOfRange(T[] original, int from, int to) in order to shift most of the array. Some numbers are cut off, though, and need to be placed back in afterwards.
public static void main( String[] args ) {
int[] arr = { 1, 2, 3, 4, 5, 6 };
arr = rot(arr, -1);
System.out.println(Arrays.asList(arr));
}
public static int[] rot( int[] arr, int amt ) {
while ( amt < 0 )
amt += arr.length;
amt = amt % arr.length;
int[] k = Arrays.copyOfRange(arr, amt, arr.length + amt);
for ( int i = 0; i < amt; i++ )
k[k.length - amt + i] = arr[i];
return k;
}
rot() rotates left by amt, so using the parameter amt = -1 achieves what you set out to do.
The rot() method first forces 0 ≤ amt < arr.length. This is because once you rotate by the full length of the array, you're back where you started. Next it shifts the array by amt, adding the integer's default value (0) to the end as padding to preserve length. Finally, it adds the lost elements back into the array where the 0's were placed.
for(int i = 0; i < validData.length / 2; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
The logic behind this is that you are swapping the values until you get to the center:
I made this image for you to better understand
Here, there is no center, but if there was a 3.5, then it would ignore the three point five because validData[validData.length - i - 1] = temp;

Adding corresponding elements of two arrays into third array

I am trying to let the user input the number of elements arrA and arrB should have and also making the user choose the int number they want for each corresponding element in both, arrA and arrB. Then, creating the third arrC with the sum of the corresponding elements in arrA and arrB and then printing arrA, arrB and arrC.
The output should look like this:
Input the length: 5
Enter a value for first array, position 0: 1
Enter a value for first array, position 1: 6
Enter a value for first array, position 2: 13
Enter a value for first array, position 3: -3
Enter a value for first array, position 4: 8
Enter a value for second array, position 0: 9
Enter a value for second array, position 1: -4
Enter a value for second array, position 2: 1
Enter a value for second array, position 3: 65
Enter a value for second array, position 4: 18
first: 1 6 13 -3 8
second: 9 -4 1 65 18
result: 10 2 14 62 26
This is the code I have written so far and I need help as to how would i use scanner to let the user choose the input length of arrA and arrB and the elements in arrA and arrB. This is what the code looks like so far :-
class ArrayArithmetic
{
public static void main ( String[] args )
{
int[] arrA = { 11, -27, 89, 17};
int[] arrB = {-3, 24, -9, -16};
int[] sum = { 0, 0, 0, 0};
for(int i = 0; i < arrA.length - 1; i++)
{
for(int j = 0; i < arrB.length - 1; i++)
{
sum[i] = arrA[i] + arrB[i];
}
}
System.out.println("sum: " + sum[0]+"," + sum[1] + "," + sum[2] + "," + sum[3] );
}
}
Lets suppose you have only 2 arrays to make it easy and don't nest loops, when you understand this pieces of code you can wrap all the method with a new loop and create infinite arrays to sum to result if you want... but you have to understand the basics first:
Create a Scanner and ask user for the lenght of the arrays:
Scanner sc = new Scanner(System.in);
// ask user!
System.out.println("Input the length:");
int arrayLength = in.nextInt();
Create the arrays with given lenght
int[] fistArray = new int[arrayLength];
int[] secondArray = new int[arrayLength];
int[] totals = new int[arrayLength];
Fill fist array iterating positions from 0 to number entered by user:
for (int i = 0; i < arrayLength; i ++) {
System.out.println("Enter a value for first array, position "+ i);
try {
firstArray[i] = Integer.parseInt(sc.nextLine());
} catch (Exception e) {
System.out.println("Not a valid number!!!);
i --;
}
}
Fill second array iterating positions from 0 to number entered by user and get the sum of each pos:
for (int i = 0; i < in.nextInt(); i ++) {
System.out.println("Enter a value for second array, position "+ i);
try {
secondArray[i] = Integer.parseInt(sc.nextLine());
totals[i] = fistArray[i] + secondArray[i];
} catch (Exception e) {
System.out.println("Not a valid number!!!);
i --;
}
}
And print the results:
System.out.println(Arrays.toString(firstArray));
System.out.println(Arrays.toString(secondArray));
System.out.println(Arrays.toString(totalsArray));
Finally, don't forget to close your Scanner to avoid memory leaks as pointed drgPP so:
sc.close();
The following code should do as you wanted:
import java.util.*;
class ArrayArithmetic
{
public static void main ( String[] args )
{
Scanner in = new Scanner(System.in);
System.out.print("Input the length ");
int len = in.nextInt();
int[] arrA = new int[len];
int[] arrB = new int[len];
int[] sum = new int[len];
for (int i = 0; i < len; i++){
System.out.print("Enter a value for first array, position " + i + ": ");
arrA[i] = in.nextInt();
}
for (int i = 0; i < len; i++){
System.out.print("Enter a value for second array, position " + i + ": ");
arrB[i] = in.nextInt();
}
for(int i = 0; i < arrA.length; i++)
{
for(int j = 0; i < arrB.length; i++)
{
sum[i] = arrA[i] + arrB[i];
}
}
System.out.println("sum: " + sum[0]+"," + sum[1] + "," + sum[2] + "," + sum[3] );
} }
public static void main (String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("Length of arrays: ");
try {
//Initializing length of array
int length = sc.nextInt();
//Constructing our arrays based on length
int[] arrA = new int[length];
int[] arrB = new int[length];
int[] arrSum = new int[length];
//Populating our array A via a loop
for (int i=0; i<arrA.length; i++) {
System.out.println("Values for arrA at index: "+i);
int value = sc.nextInt();
arrA[i]=value;
}
//Populating our array B via a loop
for (int i=0; i<arrB.length; i++) {
System.out.println("Values for arrB at index: "+i);
int value = sc.nextInt();
arrB[i]=value;
}
//Call the method to calcualte our sum which will be in sum array
arrSum = makeSum(arrA, arrB, length);
System.out.println(Arrays.toString(arrSum));
} catch (Exception e) {
e.printStackTrace();
} finally {
sc.close();
}
}
// Method to calculate our Sum Array based on the length and the Array A and B
public static int[] makeSum (int[] arrA, int[] arrB, int length) {
int[] arrSum = new int[length];
for (int i=0; i<arrA.length; i++) {
for (int j=0; j<arrB.length; j++) {
arrSum[j]=arrA[i]+arrB[j];
}
}
return arrSum;
}
Perhaps this is your question:
Scanner scan = new Scanner(System.in);
System.out.println("Enter size: ");
int size =scan.nextInt();
Integer[] arrA = new Integer[size];
ArrayList<Integer> arrB = new ArrayList<Integer>(size);

Categories