I currently have a text file in the format
matrix
row
a
b
c
row
d
e
f
row
g
h
i
row
j
k
l
matrix
row
m
n
o
p
q
row
r
s
t
u
v
I would like to convert this into two integer matrices (stored as 2 2D arrays), in the format
a b c
d e f
g h i
j k l
and
m n o p q
r s t u v
So far, I have created a Scanner object of the file and put each line in a text array:
Scanner sf = new Scanner(new File("C:\\textfiles\\matrices.txt"));
int maxIndex = -1;
String text[] = new String[10000]; // I added more than necessary for safety
while (sf.hasNext()){
maxIndex++;
text[maxIndex] = sf.nextLine();
}
sf.close();
This way, the text file is now contained in a string array, where each line is a new element of the array. Right now, I would like to partition the array into two arrays with each array being the matrices. How should I continue? (note: I am a total beginner and desire answers that are simple (no arraylist, hashmap, etc., and that's why this question is not a duplicate of How to read two matrices from a txt file in java because it uses BufferedReader, and there are other potential duplicate questions, so I would like to clear this up)
What I currently have after the top:
int counter = 0;
int iCounter = 0; // row
int jCounter = 0; // column
int matrix1[][];
int matrix2[][];
while (counter < maxIndex){
if (counter = 0)
{
\\not yet written...
}
\\not yet written...
}
As #Rob said, it's really cumbersome to do this without dynamic data structures such as ArrayList's. But nevertheless, here's a code that does your job (considering you have only two matrices), without using any List's:
int counter = 0;
int iCounter = 0; // row
int jCounter = 0; // column
int matrix1[][];
int matrix2[][];
int rowSize = 0, numberOfRows = 0;
counter = 2;
while (!text[counter].equals("row") && !text[counter].equals("matrix")) {
counter++;
rowSize++;
}
//now we have the row size
numberOfRows = 1;
while (!text[counter].equals("matrix")) {
if (text[counter].equals("row"))
numberOfRows++;
counter++;
}
//now we have the total number of rows
matrix1 = new int[numberOfRows][rowSize];
counter = 2; //to start from the first matrix
//now counter should point to the first row of the first matrix
while (!text[counter].equals("matrix")) {
jCounter = 0;
while (!text[counter].equals("row")
&& !text[counter].equals("matrix")) {
matrix1[iCounter][jCounter++] = Integer.parseInt(text[counter]);
//supposing your input is Integers, otherwise, you can change
//it to the corresponding type (i.e. Long, Double, etc)
counter++;
}
iCounter++;
if (!text[counter].equals("matrix"))
counter++;
}
//now we finished with the first matrix, and the counter points to
//the first "row" of the second matrix, so we do the same thing again
rowSize = 0;
numberOfRows = 0;
int startOfSecondMatrix = counter + 2; //save this for later
counter += 2; // so that counter points to the first number
while (counter < text.length && !text[counter].equals("row")) {
counter++;
rowSize++;
}
numberOfRows = 1;
while (counter < text.length) {
if (text[counter].equals("row"))
numberOfRows++;
counter++;
}
matrix2 = new int[numberOfRows][rowSize];
counter = startOfSecondMatrix;
iCounter = 0;
while (counter < text.length) {
jCounter = 0;
while (counter < text.length && !text[counter].equals("row")) {
matrix2[iCounter][jCounter++] = Integer.parseInt(text[counter]);
counter++;
}
iCounter++;
counter++;
}
For each matrix we perform the same operations:
-We first go through the matrix to count its size to be able to initialize it, after that, we go row by row, and parse each number.
You might as well put all the work for one matrix into a function (and take care of the bounds) and call it as long you still have more matrices.
This does what you want. Unfortunately doing this with 2D arrays is considerably harder since once you set the size of an array its difficult to manage changing it. Therefore using ArrayList is much easier.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Main {
public static final String MATRIX = "matrix";
public static final String ROW = "row";
public static void main(String[] args) throws FileNotFoundException {
// Use correct file name here
Scanner sf = new Scanner(new File("matrices.txt"));
// This is a List of 2D Lists
List<List<List<String>>> matrices = new ArrayList<>();
// easier to process lines as we're reading them in so we
// only iterate over the file once
while (sf.hasNext()) {
boolean hasBeenProcessed = false;
String inputValue = sf.nextLine();
switch (inputValue) {
case MATRIX:
ArrayList<List<String>> matrix = new ArrayList<>();
matrices.add(matrix);
hasBeenProcessed = true;
break;
case ROW:
List<List<String>> currentMatrix = getMatrixBeingProcessed(matrices);
currentMatrix.add(new ArrayList<String>());
hasBeenProcessed = true;
break;
}
if (!hasBeenProcessed) {
List<List<String>> currentMatrix = getMatrixBeingProcessed(matrices);
List<String> currentRow = getCurrentRow(currentMatrix);
currentRow.add(inputValue);
}
}
// Print out the results:
int i = 1;
for (List<List<String>> matrix : matrices) {
System.out.println("Matrix " + i);
for (List<String> row : matrix) {
for (String element : row) {
System.out.print(element + " "); // no newline until end of the row
}
System.out.println(); // new line
}
i++;
System.out.println(); // new line
}
}
private static List<String> getCurrentRow(List<List<String>> currentMatrix) {
int lastRow = currentMatrix.size() - 1;
return currentMatrix.get(lastRow);
}
private static List<List<String>> getMatrixBeingProcessed(List<List<List<String>>> matrices) {
int lastMatrix = matrices.size() - 1;
List<List<String>> currentMatrix = matrices.get(lastMatrix);
return currentMatrix;
}
}
Output:
Matrix 1
a b c
d e f
g h i
j k l
Matrix 2
m n o p q
r s t u v
Process finished with exit code 0
Since you don't want to use List and arrays can't be resized once initialized, this is not easy.
There are two ways: Read the file and initialize arrays knowing the size (as #Maaddy posted) or 'resizing' arrays. That's not possible but it is if you use Arrays.copyOf() so you can create a new array.
The idea is create a 'tridimensional' array where you can store: matrix, row and column; and then start to read the file.
Every time you find a word the entire array will be updated creating a new array with one length more.
If the word is 'matrix' the extra length will be added to the first position (the position who 'store' the matrix)
If the word is 'row' then the space will be added for the current matrix. So in this way, the current matrix will have one more array where store the column values.
If the word is other then is a value for the column. The column is resized and added to the correct position.
Note that if a word 'matrix' or 'row' is found, the new array is initialized with no length. This is because will be resized later, when is necessary.
The code is as follows:
//Initialize array with no positions
String[][][] arrays = new String[0][0][0];
Scanner sf = new Scanner(new File("path/matrices.txt"));
int matrix = -1;
int row = -1;
int column = -1;
while (sf.hasNext()){
String line = sf.nextLine();
if(line.equals("matrix")) {
//'Resize' array: Create new array with 1 more length and old data
arrays = Arrays.copyOf(arrays, arrays.length + 1);
//Start new matrix
arrays[++matrix] = new String[0][0];
row = -1;
column = -1;
}else if(line.equals("row")) {
//'Resize' matrix: Create a new array with 1 more length and old data
arrays[matrix] = Arrays.copyOf(arrays[matrix], arrays[matrix].length+1);
row++;
arrays[matrix][row] = new String[0];
column = -1;
}else{
//'Resize' matrix
column++;
arrays[matrix][row] = Arrays.copyOf(arrays[matrix][row], arrays[matrix][row].length+1);
arrays[matrix][row][column] = line;
}
}
sf.close();
//Print result
for(int i = 0 ; i < arrays.length; i++) {
System.out.println("Matrix "+i);
for(int j = 0; j < arrays[i].length; j++ ) {
for(int k = 0; k < arrays[i][j].length; k++) {
System.out.print(arrays[i][j][k]+ " ");
}
System.out.println();
}
System.out.println();
}
And the result is:
Matrix 0
a b c
d e f
g h i
j k l
Matrix 1
m n o p q
r s t u v
Related
My goal for this program is to create a 2D-array ratings whose size is specified by the first two arguments from the command line. args[0] would represent the number of rows r and arg[1] would represent the number of columns c. The next arguments that follow would all be used to fill in the array. So if the command-line argument was 3 2 5 2 3 3 4 1. I would hope that the array would be 3 rows by 2 columns. The value 5 would be in ratings[0][0], the value 2 would be in ratings[0][1], the value 3 would be in ratings[1][0], etc. After that, I want to compute the sum of each column. So column 0 would be 12 and column 1 would be 6 in this scenario.
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int c = Integer.parseInt(args[1]);
int[][] ratings = new int[r][c];
int z = 2;
int y = 3;
int x = 0;
int counting = 0;
int sum = 0;
for (int rows = 0; rows < ratings.length; rows++ ) {
for (int column = 0; column < ratings[c].length; column++){
ratings[rows][column] = Integer.parseInt(args[z]);
sum += ratings[rows][column];
z++;
}
System.out.println(sum);
sum = 0;
}
//System.out.println(movieRating);
}
This is my attempt at summing the columns but this right now just sums 5 and 2, 3 and 3, 4 and 1. I want the columns not the rows to be summed but do not know how to fix it. Thank you
You seem to be adding the values to the 2D array correctly. What you're missing is an additional nested loop to print out the column totals:
for (int i = 0; i < ratings[c].length; i++) {
int colSum = 0;
for (int j = 0; j < ratings.length; j++) {
colSum += ratings[j][i];
}
System.out.println(colSum);
}
Add that where you currently have that //System.out.println(movieRating); line. Since you were adding the numbers to the array row-wise, you need to flip the for loops to be able to sum the columns.
Things you did right
You correctly initialized the ratings 2D-array with the values given on the command line. Let me re-write this below without your attempt at computing the columns' sum. Note that I renamed the variables so that the indices used in the for loop are single letter variable.
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
argIndex++;
}
}
}
Thing you didn't get right
The ratings array is filled row by row. In the code you posted, you compute in variable sum the sum of the elements inserted in the same row. This is the reason why it doesn't print the results you expected.
To compute the sum of each columns, I would recommend you create a new array in which to store this result. Integrating it with the code above:
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int[] columnSums = new int[columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
columnSums[c] += ratings[r][c];
argIndex++;
}
}
// array columnSums contains your results
}
I have changed your original code with a simpler version.
Let me know if you have problems understanding the solution.
public static void main(String[] args)
{
int row = Integer.parseInt(args[0]);
int col = Integer.parseInt(args[1]);
int arrayLength = row * col; // use a single dimension array, for simplicity
int[] ratings = new int[arrayLength]; // the array size is based on the rows and columns
// add data to the 'ratings' array
// This is not actually needed because the conversion can be done directly when the columns are summed up
for(int i = 0; i < arrayLength; i++)
{
ratings[i] = Integer.parseInt(args[i + 2]);
}
// sum up the columns using the % operator
int[] result = new int[col];
for(int i = 0; i < arrayLength; i++)
{
result[i % col] += ratings[i];
}
// print result
for(int i = 0; i < result.length; i++)
{
System.out.println(String.format("Movie %d rating is %d", i, result[i]));
}
}
PS: you are missing the validation around the String to int conversion and checks around the correctness of the user input
The goal of this is to print out the size of the blob when given a set of coordinates within a 10 x 10 matrix. It's written in java and the point of the exercise was to use recursion to find each of the 1's in the blob. (Any 1's that are connected to the original coordinate by going up, down, left, or right.
Example:
The Blob
0010010010
0100100101
1001001010
0011110101
0111101010
1001010100
0010101101
0101010010
1010100100
0101001000
The Coordinates
1 1
2 3
5 7
The Output
1
10
3
import java.util.*;
public class BlobsRunner
{
public static void main(String[] args)
{
//test the Blob class to make sure
//it works as intended
Blobs bloop = new Blobs(10, 10);
//call both constructors
Scanner reader = new Scanner(System.in);
System.out.println("Row: ");
int r = reader.nextInt();
System.out.println("Colum: ");
int c = reader.nextInt();
bloop.recur(r, c);
bloop.getBlobCount();
//print the newly instantiated Blob
bloop.toString();
//call methods - print out the size of the blob
//bloop.getBlobCount();
}
}
//next file
import java.util.*;
public class Blobs
{
private int[][] mat; //grid of 1s and 0s
private int count;
private int[][] visited;
public Blobs( int rows, int cols )
{
//set count to 0
count = 0;
//point mat at new mat size rows X cols
mat = new int[rows][cols];
//loop through mat
for(int a = 0; a < rows; a ++)
{
for(int b = 0; b< cols; b++)
{
mat[a][b] = (int)Math.random();
}
}
//fill in mat with 1s and 0s
//use Math.random()
visited = new int[rows][cols];
}
public Blobs( int rows, int cols, String s )//what does s mean?
{
//set count to 0
count = 0;
//point mat at new mat size rows X cols
mat = new int[rows][cols];
for(int a = 0; a < rows; a ++)
{
for(int b = 0; b< cols; b++)
{
mat[a][b] = (int)Math.random();
}
}
visited = new int[rows][cols];
//loop through mat
//load in the 1s and 0s from s
}
public void recur(int r, int c)
{
//add a base case
if(mat[r][c]==0)
{
//return;
}
if(visited[r][c] == 5)//figure out, make sure it doesn't count if it does
{
//return;
}
visited[r][c] = 5;
//mark current pos as visited
count++;
//increase count by 1
//add in 4 recursive calls
//UP
if(mat[r+1][c] == 1 && visited[r+1][c] != 5)
{
recur(r+1, c);
}
//DOWN
if(mat[r-1][c] == 1 && visited[r-1][c] != 5)
{
recur(r-1,c);
}
//LEFT
if(mat[r][c-1] == 1 && visited[r][c-1] != 5)
{
recur(r,c-1);
}
//RIGHT
if(mat[r][c+1] == 1 && visited[r][c+1] != 5)
{
recur(r,c+1);
}
}
public int getBlobCount()
{
//return count
return 0;
}
public String toString()
{
//you will need nested loops
//you will need a local string variable
for(int a = 0; a < mat.length; a++)
{
for(int b = 0; b < mat[a].length; b++)
{
System.out.print(mat[a][b]);
}
System.out.println();
}
return "";
}
}
Math.random() function returns double values between 0 to 1 so when you try to convert it to (int) it becomes 0. So all of your matrix is 0. And since you are doing nothing at recur() function its print 10x10 0 matrix.
Try adding import java.util.Random; then Random r = new Random(); and when you assign random numbers mat[a][b] = r.nextInt(2);
As #Fatih Aslan noted, Math.random() produces a double between 0.0 and 1.0, not including 1.0. When parsed to an int, Java will always produce the value 0.
If you do not want to use the java.util.Random library you can multiply the value you are obtaining from Math.random() by the difference between the highest and lowest random numbers you would like to generate, plus 1. If you want your lowest possible random number to be greater than 0, add that number to the output of Math.random().
For example, (int)(2 + (Math.random() * 9)) will produce random integers from 2 to 10 including 2 and 10.
My issue is the following:
I have a 2D array of size n x m, entered on a single line. On the next n lines there are m number of elements, that fill the array. So far so good.
There is a pawn on the field that always starts at the only 0 on the field (assuming there is always one 0).
It can move up and down, right and left. It always moves to the neighbouring cell with most coins and at each move collects 1 coin (=> empties the visited cell by 1). The pawn does this until there are only 0s around it and it can collect nothing anymore. I need to find the sum of all coins collected.
Here is a representation of first steps in Paint:
Coin Collection first steps:
Sample input:
4 3, 3 2 4, 2 0 3, 1 1 5, 2 2 5 -> output: 22
Here is my code so far:
I have some unfinished work with the targetCell (I still wonder how to get its coordinates dynamically in a loop, so that each cell with a larger value than the previous turns to a targetCell.) Also I'm stuck with using the directions I just created. Any hints would be useful for me to further develop the task.
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] my_array = input.split(" ");
int[] array = Arrays.stream(my_array).mapToInt(Integer::parseInt).toArray();
int n = array[0]; // rows of matrix
int m = array[1]; // cols of matrix
int[][] matrix = new int[n][m];
for (int i = 0; i < n; i++) {
String line = scanner.nextLine();
String[] numbers = line.split(" ");
matrix[i] = new int[m];
for (int j = 0; j < m; j++) {
matrix[i][j] = Integer.parseInt(numbers[j]);
}
}
int startPoint = 0;
int currentRow = 0;
int currentCol = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0) {
startPoint = matrix[i][j];
currentRow = i;
currentCol = j;
}
}
}
int target1 = 0;
int target2 = 0;
int targetCell = 0;
target1 = Math.max(matrix[currentRow - 1][currentCol], matrix[currentRow + 1][currentCol]);
target2 = Math.max(matrix[currentRow][currentCol - 1], matrix[currentRow][currentCol + 1]);
targetCell = Math.max(target1, target2);
System.out.println(targetCell);
int hDirection = 1;
if (targetCol < currentCol) {
hDirection = -1;
}
int vDirection = 1;
if (targetRow < currentRow) {
vDirection = -1;
}
}
}
}
(Can't comment so will use an answer for now. Sorry)
My first thought would be to keep a global variable for the run so that when a coin is collected, it is added to its current value; similar to how you would keep score in games like Tetris. That's assuming I've read it right.
So something like:
private static int current_score = 0; //Assuming no use of objects so using static
Couldn't understand the sample input in this example. If you could give a three turn scenario of what the final score would be, I could give you better insight.
I have a text file
0.4658 0 3
0.4095 0 3
0.4594 0 3
0.4297 0 3
0.3963 0 3
0.4232 0 3
0.4633 0 3
0.5384 0 3
0.5042 0 3
0.4328 0 3
that I want to read into a 2D double array that looks like this.
{{0.4658, 0, 3},
{0.4095, 0, 3},
... (and so on)
{0.4328, 0, 3}}
I have the following code:
public static void main(String[] args) throws Exception{
double[][] ref = null;
ref = matrix("data80.in",10,3);
}
public static double[][] matrix(String filename, int size1, int size2) throws Exception {
double[][] matrix = null;
BufferedReader buffer = new BufferedReader(new FileReader(filename));
String line;
int row = 0;
while ((line = buffer.readLine()) != null) {
String[] vals = line.trim().split("\\s+");
if (matrix == null) {
matrix = new double[size1][size2];
}
for (int col = 0; col < size1; col++) {
matrix[row][col] = Double.parseDouble(vals[col]);
}
row++;
}
buffer.close();
return matrix;
}
But it keeps giving me an outOfBounds exception, and I don't know where I am going wrong. Please help. If anyone has more efficient solutions as well to my problem it would be helpful
It's because of the following for loop:
for (int col = 0; col < size1; col++) {
matrix[row][col] = Double.parseDouble(vals[col]);
}
We are using size1 whereas we should be using size2, following would work:
for (int col = 0; col < size2; col++) {
matrix[row][col] = Double.parseDouble(vals[col]);
}
Also, there is no need for null check inside the for loop, you can remove it and initialise the array in the beginning, e.g.:
public static double[][] matrix(String filename, int size1, int size2) throws Exception {
double[][] matrix = new double[size1][size2];;
BufferedReader buffer = new BufferedReader(new FileReader(filename));
String line;
int row = 0;
while ((line = buffer.readLine()) != null) {
String[] vals = line.trim().split("\\s+");
for (int col = 0; col < size2; col++) {
matrix[row][col] = Double.parseDouble(vals[col]);
}
row++;
}
buffer.close();
return matrix;
}
You have defined you 2d matrix as
matrix = new double[size1][size2];
meaning there are size1 rows and size2 columns but in following line:
for (int col = 0; col < size1; col++) {
you have used size1. So correction is:
for (int col = 0; col < size2; col++) {
Here is yet another concept as to how you can place the delimited numerical data contained within a text file of any number of rows and any number of columns into a Double data type Two Dimensional Array. All you need to do is pass the path and file name to the method. You can also optionally supply the delimiter used within the file, the method default is a comma (,) delimiter since it is one of the most commonly used. Here is the method:
public static double[][] matrix(String filename, String... delimiterInFile) {
String delimiter = ","; // Default data delimiter in file.
// See if a optional data delimiter is supplied...
if (delimiterInFile.length > 0) { delimiter = delimiterInFile[0]; }
// Catch IO Exceptions
try {
//Place the contents of file into a ArrayList
List<String> list = Files.lines(Paths.get(filename)).collect(Collectors.toList());
// Get the greatest number of delimited columns contiained
// within the ArrayList the whole while ignoring blank lines
// (there could be blank lines in file). Our columns for our
// double 2D Array will be determined from this value. We also
// determine the true number of rows required (remember, no
// blank elements allowed so ArrayList.size() wont be good enough).
int r = 0, c = 0;
for (int i = 0; i < list.size(); i++) {
if (!list.get(i).equals("")) {
int l = list.get(i).split(delimiter).length;
if (l > c) { c = l; }
r++;
}
}
// If we have nothing then the get outta here
// by returning null.
if (r == 0 || c == 0) { return null; }
// Declare and initialize a double data type 2D Array
double[][] array = new double[r][c];
// Fill the double type array...
for (int i = 0; i < list.size(); i++) {
if (!list.get(i).equals("")) {
String[] data = list.get(i).split(delimiter);
for (int j = 0; j < data.length; j++) {
array[i][j] = Double.parseDouble(data[j]);
}
}
}
return array;
} catch (IOException ex) {
// Do what you want with the Exception...
ex.printStackTrace();
return null;
}
}
This method will automatically determine the required number of Rows and Columns for the returned Double data type 2D Array. The method ignores blank file lines so the required Rows needed for the returned Double 2D Array is determined with this in mind. The number of Columns value is determined by iterating through the data lines and detecting which data line contains the most delimited data. That column count is used for the entire 2D Array. This means then that file data lines which contain less columns will have their remaining Array Elements filled with a 0.0 double type value.
The optional delimiter that can be passed to this method can be any string or a RegEx (Regular Expression) string, for example: " " or "\\s+" or "," or ", " or "\t", etc.
This method will also throw an IO Exception should there be a problem accessing the supplied data file.
With the data file schema you provided:
0.4658 0 3
0.4095 0 3
0.4594 0 3
0.4297 0 3
0.3963 0 3
0.4232 0 3
0.4633 0 3
0.5384 0 3
0.5042 0 3
0.4328 0 3
and let's assume this file is named data.txt which is in your classpath, you might use this method like this:
double[][] myData = matrix("data.txt", "\\s+");
for (int i = 0; i < myData.length; i++) {
String strg = "";
for (int j = 0; j < myData[0].length; j++) {
strg+= myData[i][j] + " ";
}
System.out.println(strg);
}
Keep in mind, this is not a method I would recommend for really large data files (Hundreds of thousands of lines).
Please dont let the length of this post scare you! Okay so here is the prompt I am currently working on:
"Write a class named BucketSort containing a method called sort that:
a) Place each value of the one-dimensional array into a row of the bucket array, based on the value’s “ones” (rightmost) digit. For example, 97 is placed in row 7, 3 is placed in row 3 an 100 is placed in row 0. This procedure is called a distribution pass.
b) Loop through the bucket array row by row, and copy the values back to the original array. This procedure is called a gathering pass. The new order of the preceding values in the one-dimensional array is 100, 3 and 97.
c) Repeat this process for each subsequent digit position (tens, hundreds, thousands, etc.) On the second (tens digit) pass, 100 is placed in row 0, 3 is placed in row 0 (because 3 has no tens digit) and 97 is placed in row 9. After the gathering pass, the order of the values in the one-dimensional array is 100, 3 and 97. On the third (hundreds digit) pass, 100 is placed in row 1, 3 is placed in row 0 and 97 is placed in row 0 (after the 3) After this last gathering pass, the original array is in sorted order. being sorted.
This sorting technique provides better performance than a bubble sort,but requires much more memory—the bubble sort requires space for only one additional element of data. This comparison is an example of the space/time trade-off: The bucket sort uses more memory than the bubble sort, but performs better. This version of the bucket sort requires copying all the data back to the original array on each pass. Another possibility is to create a second two-dimensional bucket array and repeatedly swap the data between the two bucket arrays. The two-dimensional array of buckets is 10 times the length of the integer array"
A bit of a mouth full I know. Below is my code thus far, but I can't figure out why it will not print in the correct order and I think it is time for fresh eyes. Any ideas are appreciated, thanks!
import java.util.Arrays;
public class BucketSort_main {
public static void main(String[] args)
{
int[] numbers = new int [5];
int[] tnumbers = new int [500];
int [][] bucket = new int [10][numbers.length];
int [] a = new int [10];
int count = 0;
int divisor = 1;
int cnt = 1;
boolean moreDigits = true;
for (int s = 0; s < 10; s++)
{
a[s] = 0;
}
for (int b = 0; b < numbers.length; b++)
{
numbers [b] = (int)(Math.random()*2000);
tnumbers [b] = numbers [b];
}
int[] tmpSort = new int[10];
while (moreDigits)
{
moreDigits = false;
for (int i = 0; i < tmpSort.length; i++)
{
tmpSort[i]= -1; // hint hint
}
for (int i = 0; i < numbers.length; i++)
{
int tmp = tnumbers[i] / divisor;
if (tmp/10 != 0)
{
moreDigits = true;
}
int digit = tmp % 10;
tmpSort[digit] = tnumbers[i]; // hint hint
System.out.println("Number["+i+"], Digit "+cnt+" is "+digit + ". Full number = " + tnumbers[i]);
bucket [digit][a[digit]] = tnumbers[i];
System.out.println ("Digit " + digit + " going to slot " + a[digit] + ". " + bucket[digit][a[digit]]);
System.out.println (" ");
a[digit]++;
}
cnt++;
divisor *= 10;
for (int x = 0; x < 10; x++)
{
a [x] = 0;
for (int y = 0; y < numbers.length; y++)
{
if (bucket[x][y] != 0)
{
tnumbers [y] = 0;
tnumbers [y] = bucket[x][y];
bucket[x][y] = 0;
}
}
}
}
for (int o = 0; o < numbers.length; o++)
{
System.out.println (tnumbers[o]);
}
}
}
The Problem is here:
for (int x = 0; x < 10; x++)
{
a [x] = 0;
for (int y = 0; y < numbers.length; y++)
{
if (bucket[x][y] != 0)
{
tnumbers [y] = 0;
tnumbers [y] = bucket[x][y];
bucket[x][y] = 0;
}
}
}
You are using the same y to get values from the bucket and assign values to tnumbers. So, when you loop through y the second time you are starting over again at tnumbers[0], tnumbers[1], etc...
Fix this issue and your code works fine.