Related
I have managed to create both arrays, however I can't figure out how to combine the two arrays. Every tutorial I see merges them as such:
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
// Output: 3, 4, 5, 6, 8, 9
What I need is something that would output: 3, 3, 3, 4, 5, 5, 6, 6, 8, 9
Here is the code I have written so far:
import java.util.Scanner;
public class Merger {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] arr1 = new int[10000];
int[] arr2 = new int[10000];
int[] merged = new int[20000];
int a1 = 0;
int a2 = 0;
int size = -1;
int size2 = -1;
int sizecheck = 0;
int size2check = 0;
System.out
.println("Enter the values for the first array, up to 10,000 values, enter a negative number to quit");
for (int i = 0; i < arr1.length; i++) {
arr1[i] = scan.nextInt();
merged[i] = arr1[i];
if (arr1[i] <= 0) {
break;
}
if (size <= arr1[i]) {
size = arr1[i];
sizecheck++;
}
a1++;
}
System.out
.println("Enter the values for the second array, up to 10,000 values, enter a negative number to quit");
for (int i = 0; i < arr2.length; i++) {
arr2[i] = scan.nextInt();
merged[i + a1] = arr2[i];
if (arr2[i] <= 0) {
break;
}
if (size2 <= arr2[i]) {
size2 = arr2[i];
size2check++;
}
a2++;
}
System.out.println("First Array: ");
for (int i = 0; i < a1; i++) {
System.out.print(" " + arr1[i]);
}
System.out.println("\nSecond Array: ");
for (int i = 0; i < a2; i++) {
System.out.print(" " + arr2[i]);
}
}
}
This prints both arrays out, however does not combine and sort the two.
Here's the code ! There may be a faster/easier way to do it but this one works as long as the 2 arrays are sorted
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 5};
int[] a2 = {1, 3, 4, 4, 4, 5};
int[] a3 = merge(a1, a2);
for (int i : a3) {
System.out.print(i);
}
}
public static int[] merge(int[] a1, int[] a2) {
int[] a3 = new int[a1.length + a2.length];
int indexA1 = 0;
int indexA2 = 0;
for (int i = 0; i < a3.length; i++) {
int n;
if (indexA1 == a1.length && indexA2 < a2.length) {
n = a2[indexA2];
indexA2++;
} else if (indexA1 < a1.length && indexA2 == a2.length) {
n = a1[indexA1];
indexA1++;
} else {
if (a1[indexA1] < a2[indexA2]) {
n = a1[indexA1];
indexA1++;
} else {
n = a2[indexA2];
indexA2++;
}
}
a3[i] = n;
}
return a3;
}
I assume that you are not yet familiar with Streams, but I would like to give you an example of what you can do with them.
Add import
import java.util.stream.IntStream;
Add this at the end of your main method
System.out.println("");
IntStream arr1Stream = IntStream.of(arr1).limit(a1); //creates an InStream with the first a1 values of arr1
IntStream arr2Stream = IntStream.of(arr2).limit(a2);
int[] both = IntStream.concat(arr1Stream, arr2Stream).sorted().toArray(); //combines the two streams, sorts them an converts them to an Array
System.out.println(Arrays.toString(both)); //easy way to print an array
The easiest way is to use a Stream.
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
Stream both arrays.
flatMap them to a single IntStream
sort them
convert to an array
int [] combined = Stream.of(arr1,arr2)
.flatMapToInt(Arrays::stream)
.sorted()
.toArray();
System.out.println(Arrays.toString(combined));
Prints
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
A non-stream approach can be done as follows:
// increase arr1 to make room for arr2
int oldLen = arr1.length;
arr1 = Arrays.copyOf(arr1, arr1.length+arr2.length);
// copy arr2 starting at 0, to arr1 starting at the old length
// positon of arr1 for a length of arr2
System.arraycopy(arr2, 0, arr1, oldLen, arr2.length);
// sort and print
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1));
Prints
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
Although your question, as asked, said nothing about merging sorted arrays, here is how you would do it.
The algorithm is simple. Just iterate thru each array and compare current values.
if arr1[i] <= arr2[k], copy arr1[i] to result, advance i by 1
else copy arr2[k] to result, advance k by 1.
in all cases the index to result, r, is advanced by 1
public int[] merge(int[] arr1, int[] arr2) {
// result array
int[] result = new int[arr1.length + arr2.length];
int r = 0;
int k = 0;
int i = 0;
// Iterate thru the arrays, copying the lowest or equal value
// to the target array. This process will cease when one of the arrays
// has been fully processed.
for (; i < arr1.length && k < arr2.length; ) {
for (; k < arr2.length && i < arr1.length;) {
if (arr1[i] <= arr2[k]) {
result[r++] = arr1[i++];
}else {
result[r++] = arr2[k++];
}
}
}
Having reached this far in the algorithm, one of the arrays must have been completely processed. So try and copy both. For the empty array, the while loop basically acts like an if statement.
while (i < arr1.length) {
result[r++] = arr1[i++];
}
while (k < arr2.length) {
result[r++] = arr2[k++];
}
// return the result
return result;
}
public class Merger {
public static void main(String[] args) {
int[] arr1 = { 3, 3, 5, 6, 8, 9 };
int[] arr2 = { 3, 4, 5, 6 };
int[] res = merge(arr1, arr2);
System.out.println(Arrays.toString(res));
}
public static int[] merge(int[] arr1, int[] arr2) {
int[] res = new int[arr1.length + arr2.length];
for (int i = 0, a1 = 0, a2 = 0; i < res.length; i++) {
if (a1 == arr1.length)
res[i] = arr2[a2++];
else if (a2 == arr2.length)
res[i] = arr1[a1++];
else
res[i] = arr1[a1] <= arr2[a2] ? arr1[a1++] : arr2[a2++];
}
return res;
}
}
A simple solution can be written using the classes, Arrays and System.
Steps:
Copy elements of arr1[] into a new array (say, output[]) whose size is the sum of the sizes of the given arrays.
Copy the elements of arr2[], after the element of arr1[], into output[]
Sort output[]
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr1 = { 3, 3, 5, 6, 8, 9 };
int[] arr2 = { 3, 4, 5, 6 };
// Copy elements of arr1[] into a new array whose size is the sum of the sizes
// of the given arrays
int[] output = Arrays.copyOf(arr1, arr1.length + arr2.length);
// Copy the elements of arr2[], after the element of arr1[], into output[]
System.arraycopy(arr2.clone(), 0, output, arr1.length, arr2.length);
// Sort output[]
Arrays.sort(output);
// Display output[]
System.out.println(Arrays.toString(output));
}
}
Output:
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
You can use System.arraycopy method for this purpose:
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
// create a new array of total length
int[] arr3 = new int[arr1.length + arr2.length];
// copy first array to the beginning of the total array
System.arraycopy(arr1, 0, arr3, 0, arr1.length);
// copy second array to the end of the total array
System.arraycopy(arr2, 0, arr3, arr1.length, arr2.length);
// sort the total array
Arrays.sort(arr3);
System.out.println(Arrays.toString(arr3));
// [3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
My code is here:
import java.util.Arrays;
public class Q1102 {
public static void main(String[] args) {
String temp = "1 3 5 7 6";
int[] array1 = new int[temp.length()];
for (int i = 0; i < temp.length(); i += 2) {
int mounth = Integer.parseInt(String.valueOf(temp.charAt(i)));
array1[i] = mounth;
}
System.out.println(Arrays.toString(array1));
}
}
For some strange reason, the program outputs this:
[1, 0, 3, 0, 5, 0, 7, 0, 6]
Can someone please tell me why this occurs, and how to remove the extra zeros?
I've printed out the values that entered the array as they are entered, and there aren't any extra zeros.
You are using character conversion in a way that only works with single digit numbers, it's fragile in a number of ways. Instead, split the String on whitespace and then parse those tokens. Like,
String temp = "1 3 5 7 6";
String[] tokens = temp.split("\\s+");
int[] array1 = new int[tokens.length];
for (int i = 0; i < tokens.length; i++) {
array1[i] = Integer.parseInt(tokens[i]);
}
System.out.println(Arrays.toString(array1));
Outputs (as I think you expected)
[1, 3, 5, 7, 6]
Here issue in this line temp.length(). It will return 9 as a string length. As you know java takes default value 0. That's why you are getting extra zeros.
import java.util.Arrays;
public class Q1102 {
public static void main(String[] args) {
String temp = "1 3 5 7 6";
int length = (temp.length() + 1)/2;
int[] array1 = new int[length];
for (int i = 0, k = 0; i < temp.length(); i +=2, k++) {
int mounth = Integer.parseInt(String.valueOf(temp.charAt(i)));
array1[k] = mounth;
}
System.out.println(Arrays.toString(array1));
}
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);
}
}
I have 2D integer array named arry like this:
[6, 2, 7]
[3, 6, 7]
[5, 6, 1]
[5, 3, 4]
[5, 3, 8]
I want to sort it in the way this would be the result (in order to do so I create new array of the same size, named table):
[3, 6, 7]
[5, 6, 1]
[5, 3, 4]
[5, 3, 8]
[6, 2, 7]
And I have this code:
for (int k = 0; k < numOfArrays; k++) {
int smallest = 2147483647;
int indexSmallest = 0;
for (int h = 0; h < numOfArrays; h++) {
if (arry[h][0] < smallest) {
smallest = arry[h][0];
indexSmallest = h;
}
}
tabel[k] = arry[indexSmallest];
arry[indexSmallest][0] = 2147483647;
}
for (int k = 0; k < numOfArrays; k++) {
System.out.println(Arrays.toString(tabel[k]));
}
The result is:
[2147483647, 6, 7]
[2147483647, 6, 1]
[2147483647, 3, 4]
[2147483647, 3, 8]
[2147483647, 2, 7]
I don't understand how can table contain 2147483647, if I've never set any value of table to 2147483647?
The real problem is this line:
tabel[k] = arry[indexSmallest];
Remember, arrays are objects. This line doesn't copy the inner array, it sets a reference to it.
So at this point both tabel[k] and arry[indexSmallest] point to the same array object. So when you do this:
arry[indexSmallest][0] = 2147483647;
You change it for both arry[indexSmallest] and tabel[k] (since they point to the same object)
To fix the problem, assing to tabel[k] a copy of the array:
tabel[k] = Arrays.copyOf(arry[indexSmallest], 3);
arry[indexSmallest][0] = 2147483647;
This line of code is setting the first element in each row to 2147483647 at the end of your outermost for loop. This is why it appears in each row. I'm not sure what you intended to do here, but this is why you are getting that value.
Remember, Java arrays are objects, which means they are passed by reference. So you're not actually making a copy of the inner arrays; use Arrays.copyOf() for that.
If you're allowed to use Arrays.sort() with a Comparator, you could do it like this.
java.util.Arrays.sort(arry, new java.util.Comparator<int[]>() {
public int compare(int[] a1, int[] a2) {
for (int k = 0; k < a1.length; k++) {
if (a1[k] != a2[k]) {
return a1[k] - a2[k];
}
}
return 0;
}
});
for (int k = 0; k < numOfArrays; k++) {
System.out.println(java.util.Arrays.toString(arry[k]));
}
If that's not allowed, then you can still use the comparison logic inside the above Comparator.compare() method. That's your basic sorting logic regardless of the implementation details.
You have make this info inside of an Object and implement Comparable/Comparator:
public YourObject implements Comparable {
private long a;
private long b;
private long c;
public YourObject (long a, long b, long c){
this.a = a;
this.b = b;
this.c = c;
}
public int compareTo(Object arg0) {
//make your comparison here...
}
}
In main function:
YourObject[] arr = new YourObject[3];
arr[0] = new YourObject (.., .., ..,);
arr[1] = new YourObject (.., .., ..,);
arr[2] = new YourObject (.., .., ..,);
Arrays.sort(arr); //sorting your data
You can greatly simplify your code by using Arrays.sort method, or otherwise you can implement something like this.
Selection sort of a 2d array by column
public static void selectionSort2D(int[][] arr, int column) {
// iterate over all subsets of the rows of the array
// (0-last, 1-last, 2-last, 3-last, ...)
for (int i = 0; i < arr.length; i++) {
// assume the min is the first row element
int min = arr[i][column];
// row index of the min element
int min_i = i;
// check the rows after i to find the smallest
for (int j = i + 1; j < arr.length; j++) {
// if this row element is less,
// then it is the new min
if (arr[j][column] < min) {
min = arr[j][column];
min_i = j;
}
}
// if the min element row is not equal to
// the current one, then swap these rows
if (i != min_i) {
int[] temp = arr[i];
arr[i] = arr[min_i];
arr[min_i] = temp;
}
}
}
// test
public static void main(String[] args) {
int[][] arr = {
{6, 2, 7},
{3, 6, 7},
{5, 6, 1},
{5, 3, 4},
{5, 3, 8}};
// sort by first column
selectionSort2D(arr, 0);
// output
for (int[] row : arr)
System.out.println(Arrays.toString(row));
//[3, 6, 7]
//[5, 6, 1]
//[5, 3, 4]
//[5, 3, 8]
//[6, 2, 7]
}
I have input stream of numbers coming like
1 3 5 6 5 6 7 43 54 3 2 ....
At any point of given time how to find the last five number ?
Or you could use a circular buffer:
private class CircularBuffer {
private int[] items;
private int index = 0;
private int size = 0;
public CircularBuffer(int size) {
items = new int[size];
}
public void add(int item) {
items[index] = item;
index = (index + 1) % items.length;
size = Math.min(size + 1, items.length);
}
public int get(int i) {
if (i < 0 || i >= size)
throw new IndexOutOfBoundsException();
return items[(index - size + i + items.length) % items.length];
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < size; ++i) {
builder.append(get(i));
builder.append(i < size - 1 ? ", " : "]");
}
return builder.toString();
}
}
Test code:
CircularBuffer b = new CircularBuffer(5);
for (int i = 1; i < 10; ++i) {
b.add(i);
System.out.println(b);
}
Output:
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
You could save them in a Stack which would be the easiest and 'best' way to do it inmho.
If you (for whatever reason) can't or don't want to use an Stack I would suggest you to implement the "push" method for Arrays:
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int[] numbers = new int[5];
while(true){ // as long as you expect numbers from your stream
push(numbers, sc.nextInt());
}
}
public static void push(int[] arr, int value){
for(int i = 1; i < arr.length; i++){
arr[i - 1] = arr[i];
}
arr[arr.length - 1] = value;
}
Assuming your Stream provides with you with Integers only, via STDIN, one per line - the numbers array now holds the last 5 inputs for you (or 0 as a default value in case less than 5 values arrived so far).
Greetings Tim