Sort Array with two loops Implementation - java

I am new with Java.
I try to do one of my assignment, but i can not figure out why my result still can not sort.
I have a prompt value(argument) 20 10 30 60 55, and i want to sort it.
I wrote two loops, and converted prompt value (which is string) to Integer.
Result: ( It is not sorted)
20
10
30
60
55
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at question2.SortedArray.main(SortedArray.java:29)
This is the code i wrote:
int temp = 0;
int array[] = null;
int array2[];
for(int i=0; i<args.length; i++){
int a = Integer.parseInt(args[i]);
array = new int[a];
for(int j=0; j<args.length; j++){
int b = Integer.parseInt(args[i]);
array2 = new int[b];
if(array[i]>array2[j])
temp = array2[j];
array2[j] = array[i];
array[i] = temp;
}
}
for (int i = 0; i < array.length; i++)
{
System.out.println(args[i].toString());
}
I could understand this code i fould online below
int tempVar;
for (int i = 0; i < numbers.length; i++)
{
for(int j = 0; j < numbers.length; j++)
{
if(numbers[i] > numbers[j])
{
tempVar = numbers [j ];
numbers [j]= numbers [i];
numbers [i] = tempVar;
}
}
}
for (int i = 0; i < numbers.length; i++)
{
System.out.print(numbers[i]+" ");
}
}

First, convert the String array of args into an int array of values. Then sort and display values. You've been sorting arrays (sized by your array int value), then printing the arguments (which you didn't sort). So, something like
int[] values = new int[args.length];
for (int i = 0; i < args.length; i++) {
values[i] = Integer.parseInt(args[i]);
}
int temp = 0;
for (int i = 0; i < values.length - 1; i++) {
for (int j = i + 1; j < values.length; j++) {
if (values[i] > values[j]) {
temp = values[j];
values[j] = values[i];
values[i] = temp;
}
}
}
System.out.println(Arrays.toString(values));

You need to initialize your array to hold your prompt values
int [] yourArray = {2,3,4 5,};
You don't need a second array to sort the values just a temporary int to hold the value that is being moved.
The statements below if needs to be enclose with { } otherwise all it will do is run to the first semicolon and then get out of the if.
Basically what the code you pasted in the second part is checking if element at the value i is greater than the value at element j. If the value is greater it swaps j with i.
for (int i = 0; i < numbers.length; i++)
{
for(int j = 0; j < numbers.length; j++)
{
if(numbers[i] > numbers[j]) //if element at i is greater than element a j
{
tempVar = numbers [j ]; //store the number at element j in temp
numbers [j]= numbers [i];// set the number at element i to element j
numbers [i] = tempVar;// set the number at temp to element
}
} // does this for each element until no element i greater than j
}

Get the integers to an array at first.
int[] yourArray = { 20, 10, 30, 60, 55 };
for (int i = 0; i < yourArray.length; i++) {
for (int j = 0; j < yourArray.length - 1; j++) {
// swap
if (yourArray[i] < yourArray[j]) {
int temp = yourArray[i];
yourArray[i] = yourArray[j];
yourArray[j] = temp;
}
}
}
for (int i : yourArray)
System.out.println(i);
Output
10
20
30
55
60

Related

Sort array in descending order and collect the changes of main array in new array

public static int[] sortByScores(double[] scores){
double temp;
int i,j;
int[] scoreIndex = new int[3];
for (i = 0; i <= scores.length; i++)
for (j = i+1; j < scores.length; j++) {
if (scores[i] < scores[j]) {
temp = scores[i];
scores[i] = scores[j];
scores[j] = temp;
scoreIndex[i] = j;
scoreIndex[j] = i;
}
}
return scoreIndex;
}
This method sort the "scores" array in descending order and store which index key is changed from the array in "scoreIndex" array.
This method doesn't work if I enter 1,3,2,4
Is they any better way to store the index key changes log?
Example if 1 enter:
1
2
4
3
Sorted will be:
4
3
2
1
And sortIndex should be:
Key Value
0 3
1 2
2 0
3 1
You can actually get the array containing the proper ordering of the elements at certain indices without sorting this array, for example, by doing this:
for(int i = 0; i < scores.length; i++) {
for(int j = i; j < scores.length; j++) {
if(scores[scoreIndex[j]] > scores[scoreIndex[i]]) {
int temp = scoreIndex[j];
scoreIndex[j] = scoreIndex[i];
scoreIndex[i] = temp;
}
}
}
In short, at the beginning of this method we are creating an array which contains the current order of indices in your scores[] array, this is 0, 1, ..., scores.length-1. Then, we perform an operation similar to standard sorting but not in terms of the scores[] array, but in terms of the scoreIndex[] array.
Once we have this array sorted, we can create another array and and place its elements at the appropriate position by:
double[] copy = new double[scores.length];
for(int k = 0; k < scores.length; k++) {
copy[k] = scores[k];
}
for(int n = 0; n < scores.length; n++) {
scores[n] = copy[scoreIndex[n]];
System.out.println(scores[n]);
}
So, to put it together:
public static int[] sort(double[] scores) {
int[] scoreIndex = new int[scores.length];
for(int i = 0; i < scores.length; i++) {
scoreIndex[i] = i;
}
for(int i = 0; i < scores.length; i++) {
for(int j = i; j < scores.length; j++) {
if(scores[scoreIndex[j]] > scores[scoreIndex[i]]) {
int temp = scoreIndex[j];
scoreIndex[j] = scoreIndex[i];
scoreIndex[i] = temp;
}
}
}
double[] copy = new double[scores.length];
for(int k = 0; k < scores.length; k++) {
copy[k] = scores[k];
}
for(int n = 0; n < scores.length; n++) {
scores[n] = copy[scoreIndex[n]];
System.out.println(scores[n]);
}
return scoreIndex;
}
First, you should declare scoreIndex as:
int[] scoreIndex = new int[scores.length];
And, in every outer loop, you find the max element, set it as scores[i], at the same time, set scoreIndex[indexOfMaxElement] = i. To achieve this, you also need a copy of the origial array.
Here is the complete code:
public class Main {
public static void main(String[] args) {
double[] array = new double[] {1, 2, 4, 3};
int[] result = sortByScores(array);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
public static int[] sortByScores(double[] scores){
int[] scoreIndex = new int[scores.length];
double[] copy = new double[scores.length];
boolean[] records = new boolean[scores.length];
// copy
for (int i = 0; i < scores.length; i++) {
copy[i] = scores[i];
}
for (int i = 0; i < scores.length; i++) {
// find the max element
for (int j = i + 1; j < scores.length; j++) {
if (scores[i] < scores[j]) {
double temp = scores[i];
scores[i] = scores[j];
scores[j] = temp;
}
}
// set the max element's index
for (int k = 0; k < copy.length; k++) {
if (copy[k] == scores[i] && !records[k]) {
scoreIndex[k] = i;
records[k] = true;
break;
}
}
}
return scoreIndex;
}
}
My one worked too but #user6690200 your one is way better.
public static int[] sortByScores(double[] scores){
double temp,temp2;
int i,j;
int[] scoreIndex = new int[3];
double[] scoreBackup = new double[scores.length];
double[] scoreBackup2 = new double[scores.length];
// Generating unique score, beacuse student can have same score
for(i=0;i<scores.length;i++)
scoreBackup[i] = scores[i]*(i+1);
for(i=0;i<scores.length;i++)
scoreBackup2[i] = scores[i]*(i+1);
for (i = 0; i < scores.length; i++) {
for (j = i+1; j < scores.length; j++) {
if (scores[i] < scores[j]) {
temp = scores[i];
temp2 = scoreBackup2[i];
scores[i] = scores[j];
scoreBackup2[i] = scoreBackup2[j];
scores[j] = temp;
scoreBackup2[j] = temp2;
}
}
}
for(i = 0; i<scores.length;i++)
for(j=0;j<scores.length;j++)
if(scoreBackup[i] == scoreBackup2[j])
scoreIndex[i] = j;
return scoreIndex;
}

How do I find the sum of values for a multidimensional array and replace values of unused indexes?

I have 4x4 2D array that already has values in each index. I want to have a function that calculates the sum of a row/column of the array and store it at the first/final column and have the other indexes revert to 0.
This is what I have to render my array:
public static void print2Darray(int[][] numbers) {
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers.length; j++) {
System.out.print(numbers[i][j]);
System.out.print("\t");
}
System.out.println();
}
}
Which displays something like this:
10 15 30 40
15 5 8 2
20 2 4 2
1 4 5 0
Currently this is the function that I have:
public static void sumLeft(int[][] numbers) {
for (int i = 0; i < numbers.length; i++) {
numbers[i][0] = (numbers[i][0] + numbers[i][1] + numbers[i][2] + numbers[i][3]);
if (i == 3) {
numbers[0][1] = 0;
numbers[0][2] = 0;
numbers[0][3] = 0;
numbers[1][1] = 0;
numbers[1][2] = 0;
numbers[1][3] = 0;
numbers[2][1] = 0;
numbers[2][2] = 0;
numbers[2][3] = 0;
numbers[3][1] = 0;
numbers[3][2] = 0;
numbers[3][3] = 0;
}
}
}
Which does this:
95 0 0 0
30 0 0 0
28 0 0 0
10 0 0 0
I just want to find an algorithm that would do this without "cheating" or just hacking my way through it.
All you need to do is loop over the elements of the "row" array:
public static void sumLeft(int[][] numbers) {
for (int i = 0; i < numbers.length; i++) {
for (int j = 1; j < numbers[i].length; j++) {
numbers[i][0] += numbers[i][j];
numbers[i][j] = 0;
}
}
}
Why did not you do simple this:
for (int i = 0; i < numbers.length; i++) {
for (int j = 1; j < numbers[i].length; j++) {
numbers[i][0] += numbers[i][j];
numbers[i][j] = 0;
}
}
Use the inner loop in the reverse order as:
for (int i = 0; i < numbers.length; i++) { // for all rows
int sum = 0; // about to be sum, reset every row
for (int j = numbers[i].length -1 ; j >=0; j--) { // iterate reverse in columns
if (j == 0) {
numbers[i][j] += sum; // final sum
} else {
sum += numbers[i][j]; // keep evaluating
numbers[i][j] = 0; //reset
}
}
}

Finding the largest row and column, solution is inconsistent

Where is the logic error?.. Sometimes the solution is correct and sometimes it is not. The program is suppose to calculate the row with the greatest sum and column with the greatest sum. For example:
1 1 1 1
0 0 1 0
0 0 1 0
0 0 1 0
Then the output would be:
largest row = 0
largest column = 2 //since count starts at 0
This is what I have:
import java.util.Random;
public class LargestRowAndColumn {
public static void main(String[] args) {
Random f = new Random();
int[][] m = new int[4][4];
for (int i = 0; i < m.length; i++) {
for (int j = 0;j < m[0].length; j++) {
m[i][j] = f.nextInt(2);
}
}
for (int i = 0; i < m.length; i++) {
for (int j = 0;j < m[0].length; j++) {
System.out.print(m[i][j] + " ");
}
System.out.println();
}
System.out.println("The largest row is index: " + computeRow(m));
System.out.println("The largest column is index: " + computeColumn(m));
}
public static int computeRow(int[][] m) {
int[] count = new int[m.length];
int sum;
for (int i = 0; i < 4; i++) {
sum = 0;
for (int j = 0; j < 4; j++) {
sum = sum + m[i][j];
}
count[i] = sum;
}
int maxIndex = 0;
for (int i = 0; i < i + 1; i++) {
for (int j = count.length - 1; j >= i; j--) {
if (count[i] < count[j]) {
maxIndex = j;
break;
}
}
}
return maxIndex;
}
public static int computeColumn(int[][] m) {
int[] count = new int[m.length];
int sum = 0;
for (int i = 0; i < 4; i++) {
sum = 0;
for (int j = 0; j < 4; j++) {
sum = sum + m[j][i];
}
count[i] = sum;
}
int maxIndex = 0;
for (int i = 0; i < i + 1; i++) {
for (int j = count.length - 1; j >= i; j--) {
if (count[i] < count[j]) {
maxIndex = j;
break;
}
}
}
return maxIndex;
}
}
Your maxIndex nested loop is too complex. It should be a single loop, checking the current max value seen so far with the current item in the loop. Something like this:
int maxIndex = 0;
for (int i = 1; i < count.length; i++) {
if (count[i] > count[maxIndex]) {
maxIndex = i;
}
}
return maxIndex;
Your code is correct , but
for (int i = 0; i < m.length; i++) {
for (int j = 0;j < m[0].length; j++) {
m[i][j] = f.nextInt(2);
}
}
for (int i = 0; i < m.length; i++) {
for (int j = 0;j < m[0].length; j++) {
System.out.print(m[i][j] + " ");
}
Because of the two loops:
You are creating two random 2-dimensional array instead of one.
There is one which is being printed and the other one which is not being printed but being used for index values you require so do :
System.out.print("Index" + "\t0"+"\t1"+"\t2"+"\t3" +"\n");
System.out.print("--------------------------------------------\n");
for (int i = 0; i < m.length; i++) {
System.out.print(i+ "|\t");
for (int j = 0;j < m[0].length; j++) {
m[i][j] = f.nextInt(101);
System.out.print(m[i][j] + " \t");
}
System.out.println();
}
This will also print the index, which may assist you
Why you made your job difficult. Make 2 loops, 1 for calculating the row with biggest sum, 1 for calculating the line with the bigger sum.
You don't need an int array count[i]. In your example you calculate the row with the greatest sum, you don't need to know the sum of every row after the for loop finished, so you can use a simple int bigRow.
int bigRow = 1, sumRow = 0;
// We assume that 1st row is the biggest
// Calculate the sumRow
for (int j=0;j<n;j++)
sumRow = sumRow + m[i][j] ;
// At this moment our maximum is row 1 with its sum.
// Now we compare it with the rest of the rows
// If another row is bigger, we set him as the biggest row
for ( int i=1;i<n;i++) // We start with row 2 as we calculated the 1st row
{ int auxRow = 0;
for (int j=0;j<m;j++)
{ auxRow = auxRow + m[i][j] ; }
if (auxRow > sumRow ) { auxRow=sumRow ; bigRow = i;}
}
Do the same with lines.
int bigLine = 1, sumLine = 0 ;
Let me know if you have another problem.

Java Array of unique randomly generated integers

public static int[] uniqueRandomElements (int size) {
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[j] = (int)(Math.random()*10);
}
}
}
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
return a;
}
I have a method above which should generate an array of random elements that the user specifies. The randomly generated integers should be between 0 and 10 inclusive. I am able to generate random integers but the problem I have is checking for uniqueness. My attempt to check for uniqueness is in my code above but the array still contains duplicates of integers. What am I doing wrong and could someone give me a hint?
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[j] = (int)(Math.random()*10); //What's this! Another random number!
}
}
}
You do find the duplicate values. However, you replace it with another random number that may be a duplicate. Instead, try this:
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);//note, this generates numbers from [0,9]
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--; //if a[i] is a duplicate of a[j], then run the outer loop on i again
break;
}
}
}
However, this method is inefficient. I recommend making a list of numbers, then randomizing it:
ArrayList<Integer> a = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){ //to generate from 0-10 inclusive.
//For 0-9 inclusive, remove the = on the <=
a.add(i);
}
Collections.shuffle(a);
a = a.sublist(0,4);
//turn into array
Or you could do this:
ArrayList<Integer> list = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){
list.add(i);
}
int[] a = new int[size];
for (int count = 0; count < size; count++){
a[count] = list.remove((int)(Math.random() * list.size()));
}
It might work out faster to start with a sequential array and shuffle it. Then they will all be unique by definition.
Take a look at Random shuffling of an array, and at the Collections.shuffle function.
int [] arr = [1,2,3,.....(size)]; //this is pseudo code
Collections.shuffle(arr);// you probably need to convert it to list first
If you have a duplicate you only regenerate the corresponding number once. But it might create another duplicate. You duplicate checking code should be enclosed in a loop:
while (true) {
boolean need_to_break = true;
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
need_to_break = false; // we might get another conflict
a[j] = (int)(Math.random()*10);
}
}
if (need_to_break) break;
}
But make sure that size is less than 10, otherwise you will get an infinite loop.
Edit: while the above method solves the problem, it is not efficient and should not be used for large sized arrays. Also, this doesn't have a guaranteed upper bound on the number of iterations needed to finish.
A better solution (which unfortunately only solves second point) might be to generate a sequence of the distinct numbers you want to generate (the 10 numbers), randomly permute this sequence and then select only the first size elements of that sequence and copy them to your array. You'll trade some space for a guarantee on the time bounds.
int max_number = 10;
int[] all_numbers = new int[max_number];
for (int i = 0; i < max_number; i++)
all_numbers[i] = i;
/* randomly permute the sequence */
for (int i = max_number - 1; i >= 0; i--) {
int j = (int)(Math.random() * i); /* pick a random number up to i */
/* interchange the last element with the picked-up index */
int tmp = all_numbers[j];
all_numbers[j] = a[i];
all_numbers[i] = tmp;
}
/* get the a array */
for (int i = 0; i < size; i++)
a[i] = all_numbers[i];
Or, you can create an ArrayList with the same numbers and instead of the middle loop you can call Collections.shuffle() on it. Then you'd still need the third loop to get elements into a.
If you just don't want to pay for the added overhead to ArrayList, you can just use an array and use Knuth shuffle:
public Integer[] generateUnsortedIntegerArray(int numElements){
// Generate an array of integers
Integer[] randomInts = new Integer[numElements];
for(int i = 0; i < numElements; ++i){
randomInts[i] = i;
}
// Do the Knuth shuffle
for(int i = 0; i < numElements; ++i){
int randomIndex = (int)Math.floor(Math.random() * (i + 1));
Integer temp = randomInts[i];
randomInts[i] = randomInts[randomIndex];
randomInts[randomIndex] = temp;
}
return randomInts;
}
The above code produces numElements consecutive integers, without duplication in a uniformly random shuffled order.
import java.util.Scanner;
class Unique
{
public static void main(String[]args)
{
int i,j;
Scanner in=new Scanner(System.in);
int[] a=new int[10];
System.out.println("Here's a unique no.!!!!!!");
for(i=0;i<10;i++)
{
a[i]=(int)(Math.random()*10);
for(j=0;j<i;j++)
{
if(a[i]==a[j])
{
i--;
}
}
}
for(i=0;i<10;i++)
{
System.out.print(a[i]);
}
}
}
Input your size and get list of random unique numbers using Collections.
public static ArrayList<Integer> noRepeatShuffleList(int size) {
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0; i < size; i++) {
arr.add(i);
}
Collections.shuffle(arr);
return arr;
}
Elaborating Karthik's answer.
int[] a = new int[20];
for (int i = 0; i < size; i++) {
a[i] = (int) (Math.random() * 20);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[i] = (int) (Math.random() * 20); //What's this! Another random number!
i--;
break;
}
}
}
int[] a = new int [size];
for (int i = 0; i < size; i++)
{
a[i] = (int)(Math.random()*16); //numbers from 0-15
for (int j = 0; j < i; j++)
{
//Instead of the if, while verifies that all the elements are different with the help of j=0
while (a[i] == a[j])
{
a[i] = (int)(Math.random()*16); //numbers from 0-15
j=0;
}
}
}
for (int i = 0; i < a.length; i++)
{
System.out.println(i + ". " + a[i]);
}
//Initialize array with 9 elements
int [] myArr = new int [9];
//Creating new ArrayList of size 9
//and fill it with number from 1 to 9
ArrayList<Integer> myArrayList = new ArrayList<>(9);
for (int i = 0; i < 9; i++) {
myArrayList.add(i + 1);
}
//Using Collections, I shuffle my arrayList
Collections.shuffle(myArrayList);
//With for loop and method get() of ArrayList
//I fill my array
for(int i = 0; i < myArrayList.size(); i++){
myArr[i] = myArrayList.get(i);
}
//printing out my array
for(int i = 0; i < myArr.length; i++){
System.out.print(myArr[i] + " ");
}
You can try this solution:
public static int[] uniqueRandomElements(int size) {
List<Integer> numbers = IntStream.rangeClosed(0, size).boxed().collect(Collectors.toList());
return Collections.shuffle(numbers);
}

2-dimensional array in Java

Assume you are given an int variable named nPositive and a 2-dimensional array of ints that has been created and assigned to a2d. Write some statements that compute the number of all the elements in the entire 2-dimensional array that are greater than zero and assign the value to nPositive.
Code:
for(int i=0; i<a2d.length; i++){
int nPositive;
for(int j=0; j<a2d[a2d.length-1].length; j++) {
if(a2d[i][j] > 0) {
nPositive = a2d[i][j];
}
}
}
It has a compilation error. Why?
The iiner cycle is incorrect:
for(int j=0; j<a2d[i].length; j++){
You didn't initialize nPositive.
// make nPositive a global variable
int nPositive = 0;
for(int i=0; i<a2d.length; i++){
for(int j=0; j<a2d[a2d.length-1].length; j++) {
if(a2d[i][j] > 0) {
nPositive += a2d[i][j]; // add the value into nPositive as you go through the array
}
}
}
I tested it and find that,There is no any compilation error in your code...
for(int j=0; j<a2d[a2d.length-1].length; j++){//
let the length is a2d[10][10]
on statement a2d[a2d.length-1].length ,is equal a2d[10-1].length ,is equal a2d[9].length=>10
your algo is working fine for me ,i found no any error
here's my test code
public class A2dTest {
public static void main(String[] arr) {
int[][] a2d = new int[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = (int) (Math.random() * 100) + 1000000;// all positives
}
}
for (int i = 0; i < a2d.length; i++) {
int nPositive = 0;
for (int j = 0; j < a2d[a2d.length - 1].length; j++) {
if (a2d[i][j] > 0) {
nPositive = a2d[i][j];
System.out.println("nPositive=" + nPositive);
}}
}
}
}
I believe this is one of the questions on codeLab. You just need to properly initialize nPositive at 0 and increment it for every positive integer. That's all they're looking for involving the output. So your code needs to be:
nPositive = 0;
for (int i = 0; i < a2d.length; i++)
{
for (int j = 0; j < a2d[i].length; j++)
{
if (a2d[i][j] > 0)
{
nPositive++;
}
}
}

Categories

Resources