Unable to get a sorted array in ascending manner - java

I created a Java program that takes the user's choice and creates an int array of that size. Then the array is sorted and displayed and a number is asked to search in the array. I'm trying to use the bubble sort technique, however, the result always turns out to be a descending array rather than an ascending one.
import java.util.*;
class mt {
int i,M=0;
public void main() {
Scanner sc=new Scanner(System.in);
System.out.println("enter the size of array");
int sizeOfArray=sc.nextInt();
int arr[]= new int [sizeOfArray];
int temp;
System.out.println("enter the numbers");
for (i=0; i<sizeOfArray; i++) {
arr[i]=sc.nextInt();
}
System.out.println("the sorted array is below :");
for ( i=0; i<sizeOfArray-1; i++){
for (int j=0; j<sizeOfArray-2; j++) {
if (arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for (i=0; i<sizeOfArray; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
System.out.println("enter number to search");
int srch=sc.nextInt();
for (i=0; i<sizeOfArray; i++) {
if (arr[i]==srch)
{
System.out.println("found at "+i);
M++;
break;
}
else if (M==0&&i==sizeOfArray-1)
{
System.out.println("number not found");
}
}
}
}

Change your loops and condition as below
for ( i=0; i<arr.length - 1; i++){
for (int j=i+1; j<arr.length; j++) {
if (arr[i]>arr[j]) {
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
So you get resulting array in ascending order. In your case, you are missing elements as you are iterating over from 0 - array.length - 2.

Firstly the code mentioned above had lot of silly mistakes which need to be corrected:
1. "String args[]" need to be added in the main() method.
2. For all the for loops where "i" is the variable, it need to be defined as an "int".
3. the variable "M" need to be defined too.
Now when I did a dry run of this code, the result produced was also not proper.
Input given was as follows:
enter the size of array
5
enter the numbers
12
10
34
2
6
Output received was as below:
the sorted array is below :
2 10 12 34 6
enter number to search
Now the output was incorrect.
Although it was in ascending order... still the last element would get missed. The twin for loops that are used need to be used in a different way. Please find the code that should be present in that section:
for (int i=0; i<=sizeArr; i++){
for (int j=0; j<sizeArr-1; j++) {
if (arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
I hope that this works for you now.

Related

multidimensional array with no repeated numbers of the same row

int matrice2 [][] = new int [5][5];
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
matrice2[i][j] = (int)(Math.random()*10);
System.out.print(" "+matrice2[i][j]+" ");
}
}
System.out.println(" ");
System.out.println(" ");
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
for (int k=0;k<5;k++) {
if(j!=k) {
if (matrice2[i][j]==matrice2[i][k]) {
matrice2[i][k]=(int)(Math.random()*10);
}
}
}
System.out.print(" "+matrice2[i][j]+" ");
}
}
I wanted to make a multidimensional array without having any repeated numbers in the same row so the column doesn't matter if it has repeating numbers.
What I did here is generate 5x5 arrays formed in square.
Having index "j" as the one that gets compared with numbers in index "k" that checks the whole row if there are numbers that is equal to the number it contains in index "j".
So my only problem is that after detecting the number in "k" that is equal to the number in "j", the number in index "k" will generate a new number replacing the current number in "k" but the result in console shows that the original 5x5 array which is the first formed of the array before it gets changed has been changed but the numbers that have been replaced generated a numbers that already exist even it should keep changing until "k" cannot detect any repeated numbers.
I can think of other ways of doing it but I really want to know why it doesn't work even though I really think that it shouldn't give any problems but I might have missed something.
here's the example of the results that shouldn't have occured.
from
9 1 3 8 4
5 3 2 4 8
9 8 5 6 5
6 3 0 8 7
2 8 6 3 9
to
9 1 3 8 4
5 3 2 4 8
9 8 5 6 9
6 3 0 8 7
2 8 6 3 9
it shouldn't happen because "k" should have seen it since he starts from index 0 to 4.
while "j" is in index 4 and "k" is in index 0 it should have detected it immediately and change the number in "k" to something else random.
EDIT: I see the different ways you guys are showing but what Im asking is to provide maybe a better solution without using any imports. our teacher gave us this assignment telling us without using any of those imports which makes it more complicated but it's what we are asked for.
I tried it with while but still no changes happening.
I editted your code in a different way. I wrote some comment to code understand clearly. Try it please.
public class UniqueMatrix {
public static void main(String[] args) {
int matrix[][] = new int[5][5];
boolean uniqeMatrixFound = false;
while (!uniqeMatrixFound) {
//fill matrix until uniqe matrix found value is true
fillMatrix(matrix);
for (int i = 0; i < matrix.length; i++) {
HashSet<Integer> columnNumber = new HashSet<>();
for (int j = 0; j < matrix.length; j++) {
columnNumber.add(matrix[j][i]);
}
//if set size not equal to matrix size , create an new uniqe matrix with breaking false value
if (columnNumber.size() != matrix.length) {
uniqeMatrixFound = false;
break;
}
uniqeMatrixFound = true;
}
}
//print an array
for (int i = 0; i < matrix.length; i++) {
System.out.println(" ");
for (int j = 0; j < matrix.length; j++) {
System.out.print(" " + matrix[i][j] + " ");
}
}
}
//create a matrix with unique value in all rows.
private static void fillMatrix(int[][] matrice2) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
for (int i = 0; i < matrice2.length; i++) {
Collections.shuffle(list);
for (int j = 0; j < matrice2.length; j++) {
matrice2[i][j] = list.get(j);
}
}
}
}
Here is your code edited. I also commented inline what were the changes and why. You could have done it more easy but I think it suites you more to edit your example so you can understand. Only issue is that you should have stored the value on matrice2[i][j] = newValue (to let k go to the end of the line and check with all other values that your random is not an existing number)
Hope it helps.
public class UniqueMatrix {
public static void main (String[] args) {
int matrice2 [][] = new int [5][5];
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
matrice2[i][j] = (int)(Math.random()*10);
System.out.print(" "+matrice2[i][j]+" ");
}
}
System.out.println(" ");
System.out.println(" ");
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
for (int k=0;k<5;k++) {
if(j!=k) {
if (matrice2[i][j]==matrice2[i][k]) {
int newValue = (int)(Math.random()*10);
//store the newly found value in j for you have time to check with others till the end
matrice2[i][j] = newValue;
}
}
}
System.out.print(" "+matrice2[i][j]+" ");
}
}
}
}
Here is a different approach to the problem that uses a shuffled ArrayList instead of checking whether a value exists in the current row or not.
int matrice2[][] = new int[5][5];
ArrayList<Integer> sourceMatrix = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
sourceMatrix.add(i);
//generate random matrix using shuffled arraylist
for (int i = 0; i < matrice2.length; i++) {
Collections.shuffle(sourceMatrix);
for (int j = 0; j < matrice2[i].length; j++) {
matrice2[i][j] = sourceMatrix.get(j);
}
}
//print generated matrix
for (int i = 0; i < matrice2.length; i++) {
for (int j = 0; j < matrice2[i].length; j++) {
System.out.print(matrice2[i][j]);
}
System.out.println();
}
The way I read your logic is that when you find a duplicate you generate a new number and that new number will validated in the next iteration of the outer (j) loop. The problem is when j==k because that number will not be validated, normally this isn't a problem since j will increase and then that number will be validated with the exception of when j==4 since that is the last iteration.
So modify the rightmost column and that value will not be checked because 'j==k' will never be false.
The problem in your code was that after you detected the duplicate value, you assigned the new generated random number without checking if it is also a duplicate number. what i did here is that i detect duplicate and before assigning/replacing the new generated random number i will check whether it is also duplicate or not, if it is duplicate i will generate another otherwise i will assign it and move on.
(int)(Math.random()*10); // this code does not guarantee that new unique number is generated every time you call it.
the problem is in the code below , you are updating matrice2[i][k] with new (int)(Math.random()*10) with out checking whether it is same or different number.
if (matrice2[i][j]==matrice2[i][k]) {
matrice2[i][k]=(int)(Math.random()*10);
}

Trying to count repeated items in an integer Array but getting weird results

public static void checkMultiple(int a[]){
//will use this count variable later
//int[] count = new int[10];
//first scan over the array
for (int i = 0; i < a.length; i++)
{
//seeded loop to check against 1st loop
for (int j = 0; j < i; j++)
{
if (a[i] == a[j])
{
System.out.print(a[i] + " ");
}
}
}
}
I'm having trouble counting repeated numbers in an integer array of 10 random numbers. I havent wrote the "count" function yet but the checkMultiple() will print out the numbers that are repeated. However, some of the time it prints correctly such as:
4 2 9 0 9 6 3 3 7 5
9 3
the first line being the whole array and the second the numbers that are repeated at least once in the array. But when there is more than two of a single integer, it counts every single one of that integer such as:
9 5 2 8 5 5 7 6 3 3
5 5 5 3
Any tips or advice would be much appreciated!
It looks like as you are looping through and then immediately outputting the results.
This prevents the program from comparing what's being currently parsed and what has already been been parsed and counted.
I would pass an empty array into the first FOR loop and instead of "System.out.print," store the number in the passed-in array. You can then compare the values that have already been parsed against the value currently being parsed to see if it has already been counted.
When the outside FOR loop exits, output the array that was originally passed in empty (and now has a record of every duplicate in the initial array)
You are counting the number of duplicate instances. Your second example has three pairs of duplicate 5's. That's why you see the 5 repeated three times. Only output unique duplicate results.
Just use a hash map, if the key does not exist add it to the map with the value 1, if it does increase the value, then print the hash map.
A single iteration of the array will solve the problem.
Map<Integer, Integer> counter = new HashMap<>();
for (int i = 0; i < a.length; i++) {
if (counter.containsKey(a[i])) {
counter.put(a[i], counter.get(a[i]) + 1);
} else {
counter.put(a[i], 1);
}
}
Iterator it = counter.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
for (int i = 0; i < pair.getValue(); ++i) {
System.out.print(pair.getKey() + " ");
}
// or you could just print the number and how many times it was found
System.out.println(pair.getKey() + " " + pair.getValue());
it.remove();
}
try this
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
public class BirthdayCake {
private static void printcake(int n,int[] arr){
//Map<Integer,Integer> ha = new HashMap<Integer,Integer>();
int temp = arr[0],max=0, count=0;
/*for(int i=1;i<n;i++){
max = arr[i];
if(max<=temp){
temp=max;
count++;
break;
}
else{
max = arr[i];
count++;
break;
}
}*/
Arrays.sort(arr);
for(int i:arr){
System.out.println(i);
}
System.out.println("max:" +max);
max = arr[arr.length-1];
for(int i=0;i<n;i++){
if(arr[i]==max){
count++;
}
}
System.out.println("count:" +count);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("Entere thye array size:");
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i] = sc.nextInt();
}
printcake(n,arr);
}
}

How can you show how positions have changed after selection sort?

I coded a selection sort program and I was wondering if I wanted to add-on to it by showing how the positions of the values have changed, if it would be possible?
this is my selection sort code
import java.util.Scanner;
public class SelectionSort {
public static void main(String args[]) {
// int[] arr = {5,4,3,2,1}; // This is my array
int min = 0;
Scanner sc = new Scanner(System.in);
System.out.println("No of elements : ");
int noOfElements = sc.nextInt();
int[] arr = new int[noOfElements];
System.out.println("Give elements : ");
for (int i = 0; i < noOfElements; i++) {
arr[i] = sc.nextInt();
}
for (int i = 0; i < arr.length; i++) {
// Assume first element is min
min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
System.out.println("Sorted Elemenst : " + arr[i]);
}
}
}
If you are trying to get array after each iteration, then you should print at the end of each iteration using Arrays#toString() to print complete array
for (int i = 0; i < arr.length; i++) {
...
.....
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
System.out.println("Sorted Elements : " + Arrays.toString(arr));
}
I don't know if your 'task' is to write your own sort method, but if you are looking for sorting an array you should use this:
public static void main(String[] args) {
int[] arr = {5,4,3,2,1};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
Never assume what a User might enter and therefore never assume that the first entry will be the minimum value.
This question has been showing up a lot in StackOverflow and therefore I can only assume this is homework. With this in mind I'm sure the assignment intent is to accept a specific number of random integer values from the User, place those values into a Integer Array, then sort that array in ascending order. While the sorting process is taking place show (display in console) what steps are taking place (which values are swapped within the array).
Here's a tip, research the Bubble Sort and the little bit of code it takes to accomplish the sorting task of Integer numbers within a Integer Array. In general a Bubble Sort utilizes two for loops to carry out a sort. It is within the second for loop where you can detail the process (steps) taken to carry out the sort as towards which Array element values are swapped with other element values as the sort is carried out. It would be within the if statement code block which checks whether or not the previous Array element is greater than the current Array Element.
Good luck.

How to traverse through a one dimensional array in java [duplicate]

This question already has answers here:
Finding the minimum value of int numbers in an array (Java)
(10 answers)
Closed 5 years ago.
This is my first question on this site.
Anyways i'm making a program that will prompt the user for how many grades to enter. Then prompt the user to enter grades between 0 and 100 and store them in a array. Finally traverse the array to find the highest grade entered and display it to the user.
The problem i'm encountering is i have no clue on how to traverse through an array to compare two indexs in a array.
import java.util.*;
public class HighestGrade {
public static void main(String[] args) {
//Declare and Initialize Arrays and Scanner
Scanner scan = new Scanner(System.in);
int num = 0;
int[] array1;
int highestgrade = 0;
//Prompt user on how many grades they want to enter
System.out.print("How many grades do you want to enter: ");
num = scan.nextInt();
array1 = new int[num];
for(int i = 0; i < array1.length; i++){
System.out.print("Enter grade out of 100: ");
array1[i] = scan.nextInt();
}
//Traverse the array to find the highest grade entered
for (int i = 0; array1[0] < array1[i]; i++){
System.out.print("Higher");
}
//Display the results to the user
System.out.print("The highest grade is " + highestgrade + ".");
//Close scanner
scan.close();
}
}
To traverse through an array you can use a loop. For loop or while loop or do while loop.
To traverse through an array and keep track of the highest value you can maintain a variable and update it after each iteration if a value larger than that is encountered.
Speaking in terms of code..
int max = arr[0];
for ( int i = 0; i < arr.length; i++) {
if (arr[i] > max)
max = arr[i];
}
System.out.println("Largest is : "+max);
Hope this helps..!!
Also you can use Recursion to traverse an array. But it is not recommended as it will lead to stack related issues..
Another approach to get the highest value without traversing can be seen like this..
Step 1 : Sort the array in ascending order
Step 2 : Highest value will be at the end of the array, Use it as highest value
In codes..
Arrays.sort(arr);
System.out.println("Highest Value is : "+arr[arr.length - 1]);
To traverse the array you need to change your for loop like this:
for (int i = 0; i < array1.length; i++){
// do something with array1[i]
}
Is actually what you already did to fill it. Just do the same to use its values. But there is an alternative to get the highest value, you can use Arrays.sort:
Arrays.sort(array1); // sort values in ascending order.
System.out.println(array1[array1.length-1]); // get the element in the last position (the greatest)

Negative Arrays and Error Messages

//MY TASK IS TWO MERGE TO ARRAYS INTO ASCENDING ORDER.Your program will accept each array as input from the keyboard. You do not know ahead of time how many values will be entered, but you can assume each array will have a maximum length of 10,000 elements. To stop entering values enter zero or a negative number. You should disregard any non-positive numbers input and not store these in the array.
The elements of the two input arrays should be in increasing order. In other words, each array element must have a value that is greater than or equal to the previous element value. An array may contain repeated elements.
import java.util.Scanner;
import java.lang.Math;
class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int one[]= new int[10000];
int two[]= new int[10000];
int lengthShort=0;
int lengthLong=0;
int a =0;
int b =0;
System.out.println("Enter the values for the first array, "
+ "up to 10000 values, enter a negative number to quit");
for(int i=0; i<one.length && scan.hasNext(); i++){
one[i] = scan.nextInt();
a++;
if(one[i]<0){
one[i]=0;
break;
}
}
int length1 = a-1;
System.out.println("Enter the values for the second array, "
+ "up to 10000 values, enter a negative number to quit");
for(int i=0; i<two.length && scan.hasNext(); i++){
two[i] = scan.nextInt();
b++;
if(two[i]<0){
two[i]=0;
break;
}
}
int lengthTwo = b-1;
int mergeOne[] = new int[length1];
for (int i = 0; i<mergeOne.length; i++){
mergeOne[i]=one[i];
}
int mergeTwo[] = new int[lengthTwo];
for (int i = 0; i<mergeTwo.length; i++){
mergeTwo[i]=two[i];
}
System.out.println("First Array:");
for(int i=0; i<mergeOne.length; i++){
System.out.print(mergeOne[i] + " ");
}
System.out.println("\nSecond Array:");
for(int i=0; i<mergeTwo.length; i++){
System.out.print(mergeTwo[i] + " ");
}
if(mergeOne.length<=mergeTwo.length){
lengthLong = mergeTwo.length;
lengthShort = mergeOne.length;
}
else if(mergeOne.length>=mergeTwo.length){
lengthShort = mergeTwo.length;
lengthLong = mergeOne.length;
}
int merged[] = new int[length1 + lengthTwo];
for(int i = 0; i<lengthShort; i++){
if(i==0){
if(mergeOne[i]<=mergeTwo[i]){
merged[i] = mergeOne[i];
merged[i+1] = mergeTwo[i];
}
else if(mergeTwo[i]<=mergeOne[i]){
merged[i] = mergeTwo[i];
merged[i+1]= mergeOne[i];
}
}
else if(i>0){
if(mergeOne[i]<=mergeTwo[i]){
merged[i+i] = mergeOne[i];
merged[i+i+1] = mergeTwo[i];
}
else if(mergeTwo[i]<=mergeOne[i]){
merged[i+i] = mergeTwo[i];
merged[i+i+1]= mergeOne[i];
}
}
}
if(mergeOne.length<mergeTwo.length){
for(int k=lengthShort; k<lengthLong; k++){
merged[k]=mergeTwo[k];
}
}
if(mergeOne.length>mergeTwo.length){
for(int k=lengthShort; k<lengthLong; k++){
merged[k]=mergeOne[k];
}
}
for(int i = 0; i<merged.length; i++){
if((i+1)==merged.length)
break;
if(merged[i]>merged[i+1]){
int temp = merged[i+1];
merged[i+1]=merged[i];
merged[i]= temp;
}
}
System.out.println("\nMerged array in order is: ");
for(int i = 0; i<merged.length; i++){
System.out.print(merged[i] + " ");
}
}
}
//My code compiles in drjava but I have two issues:
1) It doesn't order the numbers in ascending order
2) When I run it through the site I have to submit this on it gives me the message as follows:
Runtime Error
Exception in thread "main" java.lang.NegativeArraySizeException
at Main.main(Main.java:281)
at Ideone.assertRegex(Main.java:94)
at Ideone.test(Main.java:42)
at Ideone.main(Main.java:29)
You'll need to rethink your merge algorithm. Suppose you input arrays are
1 5 10 50 100 500
2 4 6 8 10 12 14 16
You'll need to repeatedly decide which element is smaller to put into the output. So after selecting N elements, your output will look like
1 2 4 5 6 8 10 10 12 14
And you will need to have indexes pointing at the place in the input arrays you'll need to look at next:
1 5 10 50 100 500
^^
2 4 6 8 10 12 14 16
^^
As you can see, the indexes could be at very different places in the input arrays. However, your code does a lot of this:
if(mergeOne[i]<=mergeTwo[i]){
which means it's only comparing elements from the input that are in the same location. This doesn't work, and trying to swap elements in the output after the fact isn't good enough to get the job done.
Basically, instead of having one index and comparing the elements of the two input arrays at the same index, you'll need two indexes. I'll let you take it from there, but I think you can figure it out.
(And I have no idea why you're getting NegativeArraySizeException.)

Categories

Resources