I have a m*n matrix where every element is unique. From a given starting point I have to move to the smallest point(up, down, left, right)and then have to do the same process again. When all other surrounding point is greater than the existing one I have to stop and print the position from start. suppose I have a matrix(5*5)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
and starting point is (2,2) then the output will be 13,8,3,2,1.
I have solved this problem my way, But the problem is its complexity. I do not think my solution is efficient. Can anyone suggest me any better solution?
N.B: Except scanner pkg, I am not allowed to import any other pkg. Here is my code:
import java.util.Scanner;
public class DirectionArray {
public static void main(String [] args) {
Scanner in = new Scanner(System.in);
int row = in.nextInt();
int col = in.nextInt();
int[][] ara = new int[row][col];
int[] ara2 = new int[4];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
ara[i][j] = in.nextInt();
}
}
System.out.println("Give starting point(x) ");
int x= in.nextInt();
System.out.println("Give starting point(y) ");
int y= in.nextInt();
int sx=x;
int sy =y;
int [] fx={+1,-1,0,0};
int [] fy={0,0,+1,-1};
int p=0;
int l=0;
int v=0;
int r=0;
int [] result=new int[row*col] ;
int min=ara[x][y];
boolean swap=true;
for(int i=0;i<(row*col)-1;i++) {
for (int k = 0; k < 4; k++) {
int nx = x + fx[k];
int ny = y + fy[k];
if (nx >= 0 && nx < row && ny >= 0 && ny < col) {
if (min > ara[nx][ny]) {
ara2[p] = ara[nx][ny];
p++;
}
}
}
p=0;
while(swap) {
swap=false;
r++;
for (int q = 0; q < ara2.length-r; q++) {
if(ara2[q]>ara2[q+1]){
int temp = ara2[q];
ara2[q]=ara2[q+1];
ara2[q+1]=temp;
swap=true;
}
}
}
for(int j=0;j<ara2.length;j++) {
if(ara2[j]!=0)
{
v=ara2[j];
result[l]=v;
l++;
break;
}
}
min=v;
for(int o=0;o<ara2.length;o++) {
ara2[o]=0;
}
for(int m=0;m<row;m++){
for(int n=0;n<col;n++){
if(ara[m][n]==v) {
x = m;
y = n;
}
}
}
I think you need to split up your code in more methods. It would make it easier to read.
For example this is how I would reorganize it:
private static final int[][] COORDINATES_TO_TRY = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int row = in.nextInt();
int col = in.nextInt();
int[][] array = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
array[i][j] = in.nextInt();
}
}
System.out.println("Give starting point(x) ");
int x = in.nextInt();
System.out.println("Give starting point(y) ");
int y = in.nextInt();
findMinimum(array, x, y);
return;
}
private static int[] findMinimum(int[][] array, int x, int y) {
for (int i = 0; true; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(array[x][y]);
int[] coordinates = findLocalMinimum(array, x, y);
if (x == coordinates[0] && y == coordinates[1]) {
return coordinates;
}
x = coordinates[0];
y = coordinates[1];
}
}
private static int[] findLocalMinimum(int[][] array, int x, int y) {
int min = array[x][y];
int minX = x;
int minY = y;
for (int[] coordinates : COORDINATES_TO_TRY) {
int i = x + coordinates[0];
int j = y + coordinates[1];
if (i >= 0 && i < array.length && j >= 0 && j < array[i].length) {
if (array[i][j] < min) {
minX = i;
minY = j;
min = array[i][j];
}
}
}
return new int[]{minX, minY};
}
Related
This is the code I have written, My objective is to segregate the 0s and non 0s without changing the order of the non 0s
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int[] arx;
arx = new int[x];
int[] ary;
ary = new int[x];
for (int i = 0; i < x; i++) {
int q = sc.nextInt();
if (q != 0) {
arx[i] = q;
} else if (q == 0) {
ary[i] = q;
}
}
for (int j = 0; j < arx.length; j++) {
System.out.print(arx[j] + " ");
}
for (int j = 0; j < ary.length; j++) {
System.out.print(ary[j] + " ");
}
}
}
Sample i/p:
5
0 1 0 3 12
Sample o/p:
1 3 12 0 0
What I am getting:
o/p:
0 1 0 3 12 0 0 0 0 0
You should maintain separate index counters for the two arrays:
int x = sc.nextInt();
int ix = 0;
int iy = 0;
int[] arx;
arx = new int[x];
int[] ary;
ary = new int[x];
for (int i=0; i < x; i++) {
int q = sc.nextInt();
if (q != 0) {
arx[ix++] = q;
}
else if (q == 0) {
ary[iy++] = q;
}
}
for (int i=0; i < ix; i++) {
System.out.print(arx[i] + " ");
}
for (int i=0; i < iy; i++) {
System.out.print(ary[i] + " ");
}
For your inputs the above generated the following output:
1 3 12 0 0
Since array with arx is filled with zeroes , you can only use one array to add non zero values.
{
Scanner sc = new Scanner (System.in);
int x = sc.nextInt ();
int[] arx;
arx = new int[x];
int ind = 0;
for (int i = 0; i < x; i++) {
int q = sc.nextInt ();
if (q != 0){
arx[ind++] = q;
}
}
for (int j = 0; j < arx.length; j++){
System.out.print (arx[j] + " ");
}
}
I have a piece of program that i have to fill. It is supposed to count adjacent numbers in a 5 by 5 binary matrix. For example a matrix like this:
0 1 1 1 0
1 0 0 0 1
1 0 0 0 0
1 0 0 1 0
0 1 0 1 0
Should return 8, you can only move horizontally or vertically.
Here is the code that generates these said matrices and it can't have any modifications after i'm done.
import java.util.Random;
public class Test {
public static void main(String[] args) {
final Random r = new Random();
for (int kerrat = 0; kerrat < 10; kerrat++) {
int[][] alkioTaulukko = new int[5][5];
System.out.println("Matriisin");
for (int i = 0; i < alkioTaulukko.length; i++) {
System.out.print("");
for (int j = 0; j < alkioTaulukko[i].length; j++) {
alkioTaulukko[i][j] = r.nextInt(2);
System.out.print("" + alkioTaulukko[i][j] + " ");
}
System.out.println("");
}
System.out.print("suurimman yhtenäisen alueen koko on ");
System.out.println(laskeSuurinAlue(alkioTaulukko));
System.out.println("");
}
}
}
And finally here is my solution to the problem.
static int laskeSuurinAlue(int[][] matriisi) {
int vierekkaiset = 0;
int rivi = matriisi.length;
int palkki = matriisi[0].length;
for (int r = 0; r < rivi; r++)
{
for (int p = 0; p < palkki; p++)
{
if ((p+1 < palkki) && (matriisi[r][p] == matriisi[r][p+1]))//loops through the rows
vierekkaiset++;
if ((r+1 < rivi) && (matriisi[r][p] == matriisi[r+1][p]))//loops through the columns
vierekkaiset++;
}
}
return vierekkaiset;
}
What happens is that my solution always brings up too big results and i'm failing to see any pattern between each run. However if i use a smaller matrix like this:
int[][] array = {{1, 0, 1}, {0, 1, 1}, {0, 1, 0}};
The result is correctly 4.
And if i use a bigger one like this:
int[][] arr = {{1,0,1,1,0},
{0,0,1,0,0},
{0,0,1,0,1},
{1,1,1,0,1},
{0,0,1,0,0}
};
The result is always 20.
Finally here is my code at its current state:
import java.util.Random;
import static java.util.Arrays.deepToString;
public class Test {
public static void main(String[] args) {
final Random r = new Random();
int[][] array = {{1, 0, 1}, {0, 1, 1}, {0, 1, 0}};
int[][] arr = {{1,0,1,1,0},
{0,0,1,0,0},
{0,0,1,0,1},
{1,1,1,0,1},
{0,0,1,0,0}
};
for (int kerrat = 0; kerrat < 10; kerrat++) {
int[][] alkioTaulukko = new int[5][5];
System.out.println("Matriisin");
for (int i = 0; i < alkioTaulukko.length; i++) {
System.out.print("");
for (int j = 0; j < alkioTaulukko[i].length; j++) {
alkioTaulukko[i][j] = r.nextInt(2);
System.out.print("" + alkioTaulukko[i][j] + " ");
}
System.out.println("");
}
System.out.print("suurimman yhtenäisen alueen koko on ");
System.out.println(laskeSuurinAlue(arr));//Change to arr,array or alkioTaulukko to run the code with different matrices
System.out.println(deepToString(arr));
System.out.println("");
}
}
static int laskeSuurinAlue(int[][] array) {
int counter = 0;
int rowLimit = array.length;
int colLimit = array[0].length;
for (int r = 0; r < rowLimit; r++)
{
for (int c = 0; c < colLimit; c++)
{
if ((c+1 < colLimit) && (array[r][c] == array[r][c+1]))
counter++;
if ((r+1 < rowLimit) && (array[r][c] == array[r+1][c]))
counter++;
}
}
return counter;
}
}
You're couting the same entry more than once.
Use this code
static int laskeSuurinAlue(int[][] array) {
int counter = 0;
int rowLimit = array.length;
int colLimit = array[0].length;
for (int r = 0; r < rowLimit; r++)
{
for (int c = 0; c < colLimit; c++)
{
if (array[r][c] == 0) {
continue;
}
int sum = array[r][c];
sum += (r + 1 < rowLimit) ? array[r+1][c] : 0;
sum += (c + 1 < colLimit) ? array[r][c+1] : 0;
sum += (r - 1 >= 0 ) ? array[r-1][c] : 0;
sum += (c - 1 >= 0) ? array[r][c-1] : 0;
if (sum > 1) {
counter++;
}
}
}
return counter;
}
I am working on a project that requires a pattern recognition program. I will receive a data file with 50000+ data points, and have to recognize if a certain pattern is present. If the sum of the square regression is above a certain value, I have the pattern, otherwise, I keep cycling to the end of the of the file. However, at around datapoint 1000 ~ 3500, the sum settles and does not change. I cannot figure out why it won't change.
public class Recognition {
private static final double[] pattern = {102.0909091,
...
-102};
private static double[] temp = new double[161];
private static int[] sums;
private static final int threshold = 2107270;
private static Scanner reader;
private static PrintWriter writer;
public static int[] rec(int[] array) {
sums = new int[array.length];
int[] solution = array;
int sum = 0;
for (int x = 0; x < 161; x++) {
temp[x] = Math.pow((array[x] - pattern[x]), 2);
solution[x] = 0;
sums[x] = sumArray();
}
loop:
for (int x = 161; x < array.length; x++) {
sum = sumArray();
if (sum > threshold) {
solution[x] = 1;
cycleArray();
sums[x] = sum;
continue loop;
}
sums[x] = sum;
solution[x] = 0;
cycleArray();
temp[0] = Math.pow((array[x] - pattern[0]), 2);
}
return solution;
}
private static int sumArray() {
int sum = 0;
for (int x = 0; x < temp.length; x++) {
sum += temp[x];
}
return sum;
}
private static void cycleArray() {
for (int x = (temp.length - 1); x > 0; x--) {
temp[x] = temp[x - 1];
}
}
public static void main(String[] args0) throws FileNotFoundException {
reader = new Scanner(new File("data1.txt");
writer = new PrintWriter(new File("pattern.txt"));
int[] data = new int[50000];
int x = 0;
while (reader.hasNext()) {
data[x] = reader.nextInt();
x++;
}
int[] solutions = rec(data);
for (int y = 0; y < solutions.length; y++) {
writer.printf("%d: %d, Running Sum: %d\n", y + 1, solutions[y], sums[y]);
System.out.println(solutions[y]);
}
}
}
For clarification, the pattern length is 161 integers. If the pattern is recognized, then a 1 is outputted, otherwise a 0 is outputted.
Any and all help is appreciated.
Here's my whole idea of it, and I dont get stuck except when i hit the max value
public class PatternRecognition {
private double[] pattern = new double[161];
private double[] temp = new double[161];
private int[] sums;
private static final int threshold = 2107270;
public int[] rec(int[] array) {
sums = new int[array.length];
int[] solution = array;
int sum = 0;
for (int x = 0; x < 161; x++) {
temp[x] = Math.pow((array[x] - pattern[x]), 2);
solution[x] = 0;
sums[x] = sumArray(temp);
}
for (int x = 0; x < array.length-temp.length; x++) {
for (int x2 =0; x2<temp.length ; x2++)
temp[x2] = Math.pow((array[x+x2] - pattern[x2]), 2);
sum = sumArray(temp);
if (sum > threshold)
solution[x] = 1;
else solution[x] = 0;
sums[x] = sum;
}
return solution;
}
private int sumArray(double[] temp) {
int sum = 0;
for (int x = 0; x < temp.length; x++) {
sum += temp[x];
}
return sum;
}
private void cycleArray() {
for (int x = (temp.length - 1); x > 0; x--) {
temp[x] = temp[x - 1];
}
}
public static void main(String[] args0) {
int[] data = new int[50000];
int x = 0;
while (x<data.length) {
data[x] = x/2;
x++;
}
PatternRecognition p=new PatternRecognition();
x=0;
while (x<p.pattern.length) {
p.pattern[x] = x+1;
x++;
}
int[] solutions = p.rec(data);
for (int y = 0; y < solutions.length; y++) {
System.out.printf("%d: %d, Running Sum: %d %d\n", y + 1, solutions[y], p.sums[y], Integer.MAX_VALUE);
System.out.println(solutions[y]);
}
}
}
My code needs to multiply each row of an array by each column of the next. The user inputs the height and width and the program will randomly generate the array values. It doesn't give any errors if the arrays are equal for example (3x3)(3x3) or even if you do (3x2)(2x3). if however you enter something like (3x3)(3x2) it gives an out of bounds exception.
public class Multiply {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int width = -1;
int height = 0;
int width2 = 0;
int height2 = 0;
while (width != height2) {
while (height <= 0) {
System.out.print("Enter a height for array1: ");
height = checkInt(scan);
}
while (width <= 0) {
System.out.print("Enter a width for array1: ");
width = checkInt(scan);
}
while (height2 <= 0) {
System.out.print("Enter a height for array2: ");
height2 = checkInt(scan);
}
while (width2 <= 0) {
System.out.print("Enter a width for array2: ");
width2 = checkInt(scan);
}
if (width != height2) {
System.out
.println("Error! Dimensions of matrices not compatible. Try again.");
width = -1;
height = 0;
width2 = 0;
height2 = 0;
}
}
int array1[][] = randomMatrix(height, width);
int array2[][] = randomMatrix(height2, width2);
int product[][] = matrixMultiply(array1, array2, height, width2);
printArray(product);
}// end of main method
public static int[][] randomMatrix(int height, int width) {
int array1[][] = new int[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
array1[i][j] = (int) (-10 + Math.random() * 20);
}
}
return array1;
}// end of randomMatrix method
public static int[][] matrixMultiply(int[][] array1, int[][] array2, int height, int width) {
int[][] product = new int[height][width];
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
int prod = 0;
for (int k = 0; k < array2.length; k++) {
prod = prod + array1[i][k] * array2[k][j];
}
product[i][j] = prod;
}
}
return product;
}// end of matrixMultiply method
public static void printArray(int[][] array) {
System.out.println(" ");
System.out.println("Row Major Representation:");
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
System.out.println(" ");
System.out.println("Column Major Representation:");
for (int i = 0; i < array[1].length; i++) {
for (int j = 0; j < array.length; j++) {
System.out.print(array[j][i] + " ");
}
System.out.println();
}
}
public static int checkInt(Scanner scan) {
int width = 0;
if (scan.hasNextInt()) {
width = scan.nextInt();
return width;
} else {
scan.next();
return 0;
}
}
}// end of public class Multiply
The value of the variable "j" (Line 82) in its final iteration is causing the Out of Bounds Exception. The error occurs for (3x3)(3x2) because in the final "j" iteration, j equals 2, making the value higher than 1 (the highest index value for j's location). Adding some logic to check for when j > the highest index will prevent the issue.
I need to have each cell in the firstArray become the sum of all adjacent cells then dump that answer into secondArray.
Example:
Initial array with random numbers:
3 5 11
5 9 14
1 2 8
Computed array:
19 42 41
20 49 48
33 62 44
3 spot([0][0]) is 5 + 9 + 5 = 19, and so on. Here's what I have:
public class ProcessArray {
private int rows;
private int columns;
private int [][] firstArray;
private int [][] secondArray;
public ProcessArray(int rows, int columns) {
this.rows=rows;
this.columns=columns;
firstArray = new int[rows][columns];
secondArray = new int[rows][columns];
initializeArray(firstArray, secondArray);
randomlyFillArray(firstArray);
System.out.println("Initial array with random numbers: ");
printArray(firstArray, secondArray, rows, columns);
getFirstArray(firstArray);
System.out.println("Computed array:");
computeArrayValues(firstArray);
}
private void initializeArray(int firstArray[][], int secondArray[][]){
for(int i = 0; i <firstArray.length; i++){
for (int j =0; j<firstArray[i].length; j++){
firstArray[i][j] = (0);
}
}
for(int i = 0; i <secondArray.length; i++){
for (int j =0; j<secondArray[i].length; j++){
secondArray[i][j] = (0);
}
}
}
public void randomlyFillArray(int firstArray[][]){
for(int i = 0; i <firstArray.length; i++){
for (int j =0; j<firstArray[i].length; j++){
firstArray[i][j] = (int)(Math.random()*15);
}
}
}
//here's where I try to have it add, I don't know what loop to have it run to go to each spot in the `firstArray`:
public void computeArrayValues(int firstArray[][]){
int x=1;
int y=1;
int sum;
int topLeft = firstArray[x-1][y-1];
int top = firstArray[x][y-1];
int topRight = firstArray[x+1][y-1];
int midLeft = firstArray[x-1][y];
int midRight = firstArray[x+1][y];
int botLeft = firstArray[x-1][y+1];
int bot = firstArray[x][y+1];
int botRight = firstArray[x+1][y+1];
secondArray[0][0]= (bot+botRight+midRight);
for (x=0; x<firstArray.length; x++){
for(y=0; y<firstArray.length; y++){
secondArray[x][y] = (topLeft+top+topRight+midLeft+midRight+botLeft+bot+botRight);
}
}
System.out.println(secondArray[x][y]);
}
public void printArray(int firstArray[][], int secondArray[][], int rows, int columns){
for (int i = 0; i < rows; i++){
for (int j = 0; j < columns; j++){
System.out.printf(String.format("%4s", firstArray[i][j]));
}
System.out.println();
}
}
public int[][] getFirstArray(int array[][]){
array = firstArray;
return array;
}
public int[][] getSecondArray(int array[][]){
array = secondArray;
return array;
}
}
Presuming you are looking for suggestions on alternative approaches, I would suggest encapsulating cell coordinates and using streams of cells instead of iteration. This assumes java 8 (naturally):
class Cell {
private final int row;
private final int col;
private Cell(int row, int col) {
this.row = row;
this.col = col;
}
public static Stream<Cell> streamCells(int rows, int cols) {
return IntStream.range(0, rows)
.flatMap(row -> IntStream.range(0, cols)
.flatMap(col -> new Cell(row, col)));
}
public Stream<Cell> streamAdjacentCells(int rows, int cols) {
return IntStream.range(row - 1, row + 1)
.flatMap(row -> IntStream.range(col - 1, col + 1)
.flatMap(col -> new Cell(row, col)))
.filter(cell -> cell.row >= 0 && cell.col >= 0)
.filter(cell -> cell.row < rows && cell.col < cols)
.filter(cell -> cell.row != this.row && cell.col != this.col);
}
public int getValue(int[][] array) {
return array[row][col];
}
public void setValue(int[][] array, int value) {
array[row][col] = value;
}
}
Then the code to set adjacent values quite simple:
int[][] destination = new int[rows][cols];
Cell.streamCells(rows, cols)
.forEach(cell -> setValue(
destination,
cell.streamAdjacentCells(rows, cols)
.mapToInt(adj -> getValue(source, adj))
.sum()));
This will fulfill the stated requirement, but running the program with the example data will output:
19 42 28
20 49 35
16 37 25
That would be the correct output for a sum of all adjacent cells (let me know if I misunderstood the question).
public class ArraySum {
static int[][] sum(int array[][]) {
// Asuming square arrays
int size = array.length;
int result[][] = new int[size][size];
// For every cell in the table
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
// Iterate the neighbors
for (int n = -1; n <= 1; n++) {
for (int m = -1; m <= 1; m++) {
// Discard the cell
if (n == 0 && m == 0) {
continue;
}
int ii = i - n;
int jj = j - m;
// Check if the neighbor coordinates are
// inside of the array bounds
if (ii >= 0 && ii < size && jj >= 0 && jj < size) {
result[i][j] += array[ii][jj];
}
}
}
}
}
return result;
}
public static void main(String... args) {
int a[][] = { {3, 5, 11},
{5, 9, 14},
{1, 2, 8} };
int r[][] = sum(a);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.printf("%d ", r[i][j]);
}
System.out.println();
}
}
}