I am trying to learn Java on my own for only 3 weeks (from YouTube videos and blogs) and this is my first language. I want to write a program to find missing number (s) in an ascending integer array. I found a way, but it only works if the last number in the incrementing array is less than 10. Like 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
I also found other programs on the internet, but they all have the same problem.
I tried to write on my own with my limited 3 week knowledge and succeeded. But I think I took the long way. The code is almost 27 lines long.
Let me show you the code
I have an integer array with 9 elements:
[12, 13, 17, 18, 20, 21, 24, 25, 26]
and 14, 15, 16, 19, 22, 23 are missing
public class Exercises {
public static void main(String[] args) {
int[] arr = {12, 13, 17, 18, 20, 21, 24, 25, 26};
int len = arr.length;
System.out.println("\nArray source: \n" + Arrays.toString(arr));
//for avoiding ArrayIndexOutOfBoundsException
//error I am creating temp. array with 10 elemets
//and adding main array elements to temp. array
int[] tempArr = new int[len + 1];
for (int i = 0; i < len; i++) {
tempArr[i] = arr[i];
}
//adding last element to temp. array
int max = 0;
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] > max) {
max = tempArr[i];
}
}
tempArr[tempArr.length - 1] = max + 1;
System.out.println("\nMissing number(S): ");
for (int i = 0; i < len - 1; i++) {
// If it comes to the last loppf main array
// this will be use temp. arrays' last element to
// compare main array
if (i == (len - 1) && (tempArr[i + 1] - arr[i]) > 1) {
System.out.println(tempArr[i]);
} else if ((arr[i + 1] - arr[i]) > 1) {
for (int a = 1; a <= (arr[i + 1] - arr[i]) - 1; a++) {
System.out.println(arr[i] + a);
}
}
}
}
}
Output:
Array source:
[12, 13, 17, 18, 20, 21, 24, 25, 26]
Missing number(S):
14
15
16
19
22
23
I got what I wanted, but is there a more optimal way to do that?
Btw if I want to make code more esthetic it becomes huge :D
public class Exercises {
public static void main(String[] args) {
int[] arr = {12, 13, 17, 18, 20, 21, 24, 25, 26};
int len = arr.length;
int[] tempArr = new int[len + 1];
int[] correctArr = new int[MathUtils.max(arr) - MathUtils.min(arr) + 1];
int countArr = (MathUtils.max(arr) - (MathUtils.max(arr) - MathUtils.min(arr)) - 1);
for (int i = 0; i < correctArr.length; i++) {
countArr++;
correctArr[i] = countArr;
}
System.out.println("\nArray source: \n" + Arrays.toString(arr));
System.out.println("Source should be: \n" + Arrays.toString(correctArr));
for (int i = 0; i < len; i++) {
tempArr[i] = arr[i];
}
int max = 0;
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] > max) {
max = tempArr[i];
}
}
tempArr[tempArr.length - 1] = max + 1;
int count = 0;
for (int i = 0; i < len - 1; i++) {
if (i == (len - 1) && (tempArr[i + 1] - arr[i]) > 1) {
count++;
} else if ((arr[i + 1] - arr[i]) > 1) {
for (int a = 1; a <= (arr[i + 1] - arr[i]) - 1; a++) {
count++;
}
}
}
if (count == 1) {
System.out.println("\nThere is only one missing number:");
} else if (count > 1) {
System.out.println("\nThere are " + count + " missing numbers:");
}
for (int i = 0; i < len - 1; i++) {
if (i == (len - 1) && (tempArr[i + 1] - arr[i]) > 1) {
System.out.println(tempArr[i]);
} else if ((arr[i + 1] - arr[i]) > 1) {
for (int a = 1; a <= (arr[i + 1] - arr[i]) - 1; a++) {
System.out.println(arr[i] + a);
}
}
}
}
}
Output:
Array source:
[12, 13, 17, 18, 20, 21, 24, 25, 26]
Source should be:
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
There are 6 missing numbers:
14
15
16
19
22
23
You look to be over complicating things since a simple nested for loop is probably all that you need. The outer loop loops through the array, up to but not including the last number, and the inner loop loops between one item in the array going to the next item, from arr[i] + up to arr[i + 1]. Note that the inner loop won't "loop" if the two array items are contiguous, and so no if blocks are needed:
public class MissingNumber {
public static void main(String[] args) {
int[] arr = {12, 13, 17, 18, 20, 21, 24, 25, 26};
System.out.println("missing numbers");
for (int i = 0; i < arr.length - 1; i++) {
for (int j = arr[i] + 1; j < arr[i + 1]; j++) {
System.out.println("" + j);
}
}
}
}
Output:
missing numbers
14
15
16
19
22
23
That's it
You can use List<Integer> to avoid repeating the same calculation.
static List<Integer> missingNumbers(int[] a) {
List<Integer> missingNumbers = new ArrayList<>();
for (int i = 1, length = a.length; i < length; ++i)
if (a[i - 1] + 1 < a[i])
for (int j = a[i - 1] + 1; j < a[i]; ++j)
missingNumbers.add(j);
return missingNumbers;
}
public static void main(String[] args) {
int[] a = {12, 13, 17, 18, 20, 21, 24, 25, 26};
List<Integer> missingNumbers = missingNumbers(a);
if (missingNumbers.size() == 1)
System.out.println("There is only one missing number:");
else
System.out.println("There are " + missingNumbers.size() + " missing numbers:");
for (int n : missingNumbers)
System.out.println(n);
}
output:
There are 6 missing numbers:
14
15
16
19
22
23
int[] arr = { 12, 13, 17, 18, 20, 21, 24, 25, 26 };
System.out.println("Array Source:");
System.out.println(Arrays.toString(arr) + "\n");
System.out.println("Missing number(s):");
int nextNumber = arr[0] + 1;
for (int i = 1; i < arr.length; i++) {
while (arr[i] > nextNumber) {
System.out.println(nextNumber);
nextNumber++;
}
nextNumber++;
}
To fill the array with all numbers from min to max you can write
int[] shouldBe = IntStream.range(min, max + 1).toArray();
and in this special case
int[] shouldBe = IntStream.range(arr[0], arr[arr.length - 1] + 1).toArray();
public class missingnumber{
public static void main(String args[]){
int arr[]={1,2,3,4,6,7,8,9};
for(int i=arr.length-1;i>0;i--){
if(arr[i]-1!=arr[i-1]){
System.out.println(arr[i]-1);
}
}
}
}
Related
I'm trying to swap the maximum and minimum values in an array in my program.
Here is the code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int myArray[] = new int[25];
for (int i = 0; i < myArray.length; i++) {
System.out.println("Enter a number: ");
myArray[i] = in.nextInt();
}
int maximum = maxNumber(myArray);
int minimum = minNumber(myArray);
System.out.println(Arrays.toString(myArray));
}
public static int maxNumber(int[] arr) {
int maximumValue = arr[0];
//finds the maximum value in an array
for (int a = 1; a < arr.length; a++) {
if (arr[a] > maximumValue) {
maximumValue = arr[a];
}
}
return maximumValue;
}
public static int minNumber(int[] arr) {
int minimumValue = arr[0];
//finds the minimum value in an array
for (int a = 1; a < arr.length; a++) {
if (arr[a] < minimumValue) {
minimumValue = arr[a];
}
}
return minimumValue;
}
I have two separate functions to find the Maximum and Minimum values, but I'm stuck on the actual swapping of the values. The two functions work as I've used them for another program, but I'm not sure if they would work for this program.
At first I was thinking of finding them by setting them equal to each other in some way, but that led to nothing.
Any help would be appreciated.
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
int[] arr = new int[25];
System.out.format("Enter array int numbers (%d in total): ", arr.length);
for (int i = 0; i < arr.length; i++)
arr[i] = scan.nextInt();
System.out.println(Arrays.toString(arr));
swamMinMax(arr);
System.out.println(Arrays.toString(arr));
}
private static void swamMinMax(int[] arr) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
min = Math.min(min, arr[i]);
max = Math.max(max, arr[i]);
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == min)
arr[i] = max;
else if (arr[i] == max)
arr[i] = min;
}
}
Output:
Enter array int numbers (25 in total): 1 2 3 4 5 6 7 8 9 10 -1 -1 -1 14 15 16 17 18 19 20 21 22 23 66 66
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, 66, 66]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 66, 66, 66, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, -1, -1]
You were real close. I copied some of the code and commented where the changes need to be made. You can still use your existing code to populate the array from the console.
Also, kudos for assigning the first element in the array to min or max and starting your loop at 1. A lot of folks don't think about doing that.
int myArray[] = {1,10,-5,99,48,-22,43, 44,100,2};
System.out.println(Arrays.toString(myArray)); // print original array
int maxIdx = maxNumber(myArray); // get index of max
int minIdx = minNumber(myArray); // get index of min
// now swap max and min using the returned indices.
int save = myArray[maxIdx];
myArray[maxIdx] = myArray[minIdx];
myArray[minIdx] = save;
System.out.println(Arrays.toString(myArray)); // print the altered array
public static int maxNumber(int[] arr) {
int maximumValue = arr[0];
// finds the maximum value in an array
int idx = 0; //idx = 0 to start
for (int a = 1; a < arr.length; a++) {
if (arr[a] > maximumValue) {
idx = a; //save index of current max
maximumValue = arr[a];
}
}
return idx; // return index of max
}
public static int minNumber(int[] arr) {
int minimumValue = arr[0];
// finds the minimum value in an array
int idx = 0; // idx = 0 to start
for (int a = 1; a < arr.length; a++) {
if (arr[a] < minimumValue) {
idx = a; // save index of current min
minimumValue = arr[a];
}
}
return idx; // return index of min
}
This would print
[1, 10, -5, 99, 48, -22, 43, 44, 100, 2]
[1, 10, -5, 99, 48, 100, 43, 44, -22, 2]
You can use IntStream to find indexes of the maximum and minimum elements and then swap their values:
int[] arr = {1, 3, 5, 6, 4, 2, 8, 7, 9, -1, -3};
// indexes of the maximum and minimum elements
int max = IntStream.range(0, arr.length)
.boxed().max(Comparator.comparing(i -> arr[i])).orElse(-1);
int min = IntStream.range(0, arr.length)
.boxed().min(Comparator.comparing(i -> arr[i])).orElse(-1);
// swap the values
int temp = arr[max];
arr[max] = arr[min];
arr[min] = temp;
System.out.println(Arrays.toString(arr));
// [1, 3, 5, 6, 4, 2, 8, 7, -3, -1, 9]
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
Getting java.lang.ArrayIndexOutOfBoundsException while trying to find duplicate number in an array in Java.
Here is the code:
public class FindDuplicateNumberInArray {
public static void main(String[] args) {
int arr[] = { 11, 24, 65, 1, 111, 25, 58, 95, 24, 37 };
Arrays.sort(arr);
String sortedArray = Arrays.toString(arr);
System.out.println(sortedArray);
for (int i = 1; i < arr.length; i++) {
if (arr[i] == arr[i + 1]) {
System.out.println("Duplicate element from teh given array is = " + arr[i]);
}
}
}
}
public class FindDuplicateNumberInArray {
public static void main(String[] args) {
int arr[] = { 11, 24, 65, 1, 111, 25, 58, 95, 24, 37 };
Arrays.sort(arr);
String sortedArray = Arrays.toString(arr);
System.out.println(sortedArray);
// for (int i = 1; i < arr.length; i++) {
// if (arr[i] == arr[i - 1]) {
for (int i = 0; i < arr.length-1; i++) {
if (arr[i] == arr[i + 1]) {
System.out.println("Duplicate element from the given array is = " + arr[i]);
}
}
}
}
To check for a duplicate number, you are running the for loop to last element(say nth position), but your if condition checks the last element with (n+1)th element, which doesn't exist. And also, you need to check the 1st element too, so say i=0.
Or you can just change the if (arr[i] == arr[i + 1]) condition to if (arr[i] == arr[i - 1])
You have a very basic IndexOutOfBounds-Exception there. When accessing arrays, you have to provide an index. If that index is greater than array.length - 1, which is the last accessible index, you get an out of bounds exception. The same is true for lists.
Because you compare the current (i) value to the next one (i + 1), you run out of bounds, because you count to i < arr.length. This means when i == arr.length - 1 you still add 1 to i, which is equal to arr.length, which is more than arr.length - 1.
given an Array List with the values [10, 13, 2, 8, 7, 90, -1, 2]. I have to create a method that will reverse each successive sequence of 3 values within said list. For example (10, 13, 2) will become (2,13 10) and the (8, 7, 90) will become (90,7,8) However, it will not print out numbers that aren't part of a sequence of 3. So far this is what I have:
public static ArrayList<Integer> reverse3(ArrayList<Integer> list) {
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int i = 0; i <list.size()-1; i++){
for(int j = list.size()-1; j >= 0 ; j--){
newList.add(list.get(j));
}
}
return newList;
I'm having issues getting this to work properly. The output reverses the sequences of three but -1 and 2 are printed as well.
It sounds like all you really need to do is to swap 1 and 3, 2 and 4 etc. So:
for (int i = 0; i < list.size(); i += 3) {
Collections.swap(list, i, i + 2);
for (int j = i; j < i + 3; j++)
System.out.println(list.get(j) + " ");
}
Or you could just print them out without even swapping the items:
for (int i = 0; i < list.size(); i += 3) {
for (int j = i + 2; j >= i; j--)
System.out.println(list.get(j) + " ");
}
And here's a solution using sublist and Java 8 streams:
IntStream.range(0, list.size() / 3)
.mapToObj(n -> list.sublist(n, n + 3))
.map(Collections::reverse)
.flatMap(List::stream)
.forEach(System.out::println);
Since it looks like it's "do my homework for free" day today,
for extra credit, write it in scala:
list
.grouped(3)
.map(_.reverse)
.flatten
.toList
Something like that should do it:
for( int i = 1; i < list.size()-1; i+=3 ) {
int tmp = list.get(i+1);
list.set(i+1, list.get(i-1));
list.set(i-1, tmp);
}
This is the code you need:
public static ArrayList<Integer> reverse3(List<Integer> list) {
ArrayList<Integer> newList = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i+=3) {
for (int j = i+2; j >= i && j < list.size(); j--) {
newList.add(list.get(j));
}
}
return newList;
}
This is a demo:
public static void main(String[] args) {
List<Integer> list = Arrays.asList(10, 13, 2, 8, 7, 90, -1, 2);
System.out.println(list);
System.out.println(reverse3(list));
}
Input: [10, 13, 2, 8, 7, 90, -1, 2]
Results: [2, 13, 10, 90, 7, 8]
Could someone please advise why this code is not working correctly when threshold is set to <=3? last few digits of array does not get sorted. For example:
input: {20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; output: {3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 1 }
public class mergesorttest{
public static void main(String[]args){
int d[]= {20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
mergeSort(d,0,d.length);
for(int x:d) System.out.print(x+" ");
System.out.println();
}
static final int THRESHOLD = 3;
static void mergeSort(int f[],int lb, int ub){
if (ub - lb <= THRESHOLD)
insertion_srt(f, lb, ub);
else
{
int mid = (lb+ub)/2;
mergeSort(f,lb,mid);
mergeSort(f,mid,ub);
merge(f,lb,mid,ub);
}
}
static void merge (int f[],int p, int q, int r){
//p<=q<=r
int i =p; int j = q;
//use temp array to store merged sub-sequence
int temp[] = new int[r-p]; int t = 0;
while(i<q && j<r){
if(f[i]<=f[j]){
temp[t] =f[i];
i++;t++;
}
else{
temp[t] = f[j];
j++;
t++;
}
//tag on remaining sequence
while(i<q){
temp[t] = f[i];
i++;
t++;
}
while(j<r){
temp[t]=f[j];
j++;
t++;
}
//copy temp back to f
i=p;t=0;
while(t<temp.length){
f[i]=temp[t];
i++;
t++;
}
}
}
public static void insertion_srt(int array[], int n, int b){
for (int i = 1; i < n; i++){
int j = i;
int B = array[i];
while ((j > 0) && (array[j-1] > B)){
array[j] = array[j-1];
j--;
}
array[j] = B;
}
}
}
P.S. code was borrowed from other post
Combining MergeSort with Insertion sort to make it more efficient
In insertion_srt() shouldn't the for loop be
for (int i = n+1; i < b; i++){
and the while loop:
while ((j > n) && (array[j-1] > B)){
merge() also needs a fix, the trailing brace for the first while loop needs to be moved up before the code to tag on remaining sequences:
while(i<q && j<r){
if(f[i]<=f[j]){
temp[t] =f[i];
i++;
t++;
}else{
temp[t] = f[j];
j++;
t++;
}
}
while(i<q){
temp[t] = f[i];
i++;
t++;
}
while(j<r){
temp[t]=f[j];
j++;
t++;
}
My following code does the randomization of an array, however, I am wondering if I want to group first two or three elements together always, how should I proceed?
ArrayList<Integer> numbers = new ArrayList<Integer>();
for(int i=1;i<=11;i++)
{
numbers.add(i);
}
Collections.shuffle(numbers);
for (Integer nums : numbers)
System.out.println(nums);
Example Output: 5, 7, 4, 11, 2, 3, 1, 9, 6, 8, 10
(Note that the sequence '1,2,3' is randomized within the main array.)
Something like this maybe:
final int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
final int iterations = 10;
final int groupOf = 3;
for (int i = 0; i < array.length; i += groupOf) {
int groupOfRemainder = array.length - i < groupOf ? array.length - i : groupOf;
for (int j = 0; j < iterations; j++) {
int rnd1 = Math.random() * groupOfRemainder;
int rnd2 = Math.random() * groupOfRemainder;
Object temp = array[i + rnd1];
array[i + rnd1] = array[i + rnd2];
array[i + rnd2] = temp;
}
}
public static void shuffleKeepingFirstRTogether(List<Integer> list, int r) {
int size = list.size();
Collections.shuffle(list.subList(0, r));
Collections.shuffle(list.subList(r, size));
Collections.rotate(list, new Random().nextInt(size - r));
}