Java Arrays: Making numbers into separated, arranged digits, output issue - java

I am trying to create a code in which will take a number such as this:
"787191230"
And return this:
"0 1 1 2 3 7 7 8 9"
Right now, my error is that my code is somehow printing out the first one correctly, then starts adding LOTS of 0's, in a pattern, I think. The amount of 0's increased each time seems to keep going down, but it's annoying, nevertheless.
My main code (where everything is done):
import java.util.Arrays;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import static java.lang.System.*;
public class NumberSorter
{
static int count = 0;
private static int getNumDigits(int number)
{
while(number>0){
number=number/10;
count++;
}
return count;
}
public static int[] getSortedDigitArray(int number)
{
int[] sorted = new int[getNumDigits(number)];
for(int a = 0; a<sorted.length; a++)
{
sorted[a] = number%10;
number = number/10;
}
for(int a = 0; a<sorted.length; a++)
{
int y = a;
for(int b = a+1; b<sorted.length; b++)
{
if(sorted[b]<sorted[y])
{
y = b;
}
}
if(y != a)
{
int temp = sorted[y];
sorted[y]=sorted[a];
sorted[a]=temp;
}
}
return sorted;
}
}
The test case code (where all the numbers I try to decode are):
public class NumberSorterRunner
{
public static void main(String args[])
{
int[] cases = {567891, 901912468, 864213507, 898777, 234422, 29826};
for( int test : cases )
{
int[] one = NumberSorter.getSortedDigitArray( test );
for(int item : one)
{
System.out.print(item + " ");
}
System.out.println();
}
}
}
And last, but not least: The output:
1 5 6 7 8 9
0 0 0 0 0 0 0 1 1 2 4 6 8 9 9
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 8 8 9
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 3 4 4
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 6 8 9
Any help, hints mainly, would make me very grateful! I can't figure out what's wrong with this! Thanks in advance.

Yopu've declared count as a static, but you never reset it, so for each new test, count starts at the last value from the previous one.
It doesn't need to be static or widely accessible, so just move it inside the getNumDigits() function
Try this:
private static int getNumDigits(int number)
{
int count = 0;
while(number>0){
number=number/10;
count++;
}
return count;
}

You have count as a static member of NumberSorter, you should probably keep it as a method-scoped variable.

Your getNumDigits does not behave correctly.
static int count = 0;
private static int getNumDigits(int number)
{
while(number>0){
number=number/10;
count++;
}
return count;
}
Why do you keep count around? Just declare a local variable:
private static int getNumDigits(int number)
{
int count = 0;
while(number>0){
number=number/10;
count++;
}
return count;
}

Try following simple code:
public static void main(String args[])
{
int[] cases = {567891, 901912468, 864213507, 898777, 234422, 29826};
for( int test : cases )
{
String numStr=String.valueOf(test);
char[] digits=numStr.toCharArray();
Arrays.sort(digits);
String sorted=new String(digits);
for (int i = 0; i < sorted.length(); i++) {
System.out.print(" "+sorted.charAt(i));
}
System.out.println();
}
}
Output:
1 5 6 7 8 9
0 1 1 2 4 6 8 9 9
0 1 2 3 4 5 6 7 8
7 7 7 8 8 9
2 2 2 3 4 4
2 2 6 8 9

Related

Java - Adjacency Matrix and DFS

I've been working on a program to implement a DFS in Java (by taking an adjacency matrix as input from a file). Basically, assuming vertices are traveled in numerical order, I would like to print the order that vertices become dead ends, the number of connected components in the graph, the tree edges and the back edges. But I'm not completely there yet. When I run my program, I get the number "1" as output, and nothing more. I've tried debugging certain parts of the DFS class, but I still can't quite figure out where I'm going wrong. Here is my code:
A basic "Driver" class:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Driver {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("sample1.txt"));
scanner.useDelimiter("[\\s,]+");
int input = scanner.nextInt();
int[][] adjMatrix = new int[8][8];
for(int i=0; i < input; i++) {
for (int j=0; j < input; j++) {
adjMatrix[i][j] = scanner.nextInt();
}
}
scanner.close();
new DFS(adjMatrix);
}
}
DFS class:
import java.util.Stack;
public class DFS {
Stack<Integer> stack;
int first;
int[][] adjMatrix;
int[] visited = new int[7];
public DFS(int[][] Matrix) {
this.adjMatrix = Matrix;
stack = new Stack<Integer>();
int[] node = {0, 1, 2, 3, 4, 5, 6};
int firstNode = node[0];
depthFirstSearch(firstNode, 7);
}
public void depthFirstSearch(int first,int n){
int v,i;
stack.push(first);
while(!stack.isEmpty()){
v = stack.pop();
if(visited[v]==0) {
System.out.print("\n"+(v+1));
visited[v]=1;
}
for (i=0;i<n;i++){
if((adjMatrix[v][i] == 1) && (visited[i] == 0)){
stack.push(v);
visited[i]=1;
System.out.print(" " + (i+1));
v = i;
}
}
}
}
}
And the matrix from the input file looks like this:
0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0
Take a look at this part:
int input = scanner.nextInt();
int[][] adjMatrix = new int[8][8];
for(int i=0; i < input; i++) {
for (int j=0; j < input; j++) {
adjMatrix[i][j] = scanner.nextInt();
}
}
First you read a number, input.
Then you read input rows, in each row input columns.
This is your input data:
0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0
What is the first number, that will be read by scanner.nextInt().
It's 0. So the loop will do nothing.
Prepend the number 8 to your input, that is:
8
0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0
Btw, it's a good idea to verify that you have correctly read the matrix.
Here's an easy way to do that:
for (int[] row : adjMatrix) {
System.out.println(Arrays.toString(row));
}
There are several other issues in this implementation:
The number 7 appears in a couple of places. It's actually a crucial value in the depth-first-search algorithm, and it's actually incorrect. It should be 8. And it should not be hardcoded, it should be derived from the size of the matrix.
It's not a good practice to do computation in a constructor. The purpose of a constructor is to create an object. The depth-first-logic could be moved to a static utility method, there's nothing in the current code to warrant a dedicated class.
Fixing the above issues, and a few minor ones too, the implementation can be written a bit simpler and cleaner:
public static void dfs(int[][] matrix) {
boolean[] visited = new boolean[matrix.length];
Deque<Integer> stack = new ArrayDeque<>();
stack.push(0);
while (!stack.isEmpty()) {
int v = stack.pop();
if (!visited[v]) {
System.out.print("\n" + (v + 1));
visited[v] = true;
}
for (int i = 0; i < matrix.length; i++) {
if (matrix[v][i] == 1 && !visited[i]) {
visited[i] = true;
stack.push(v);
v = i;
System.out.print(" " + (i + 1));
}
}
}
}

How do I generate a Matrix style output

I'm trying to get an output of a random string consisted of 1's and 0's in a Matrix style. I know how to display a string consisted of 1's and 0's, but I can't keep on looping through it for some reason. What I'm trying to do, is that whenever the StringBuilder reaches the length of 20, I want to start the loop on a new line again and repeat this 100 times.
import java.util.List;
import java.util.Random;
public class main {
static Random rand = new Random();
static StringBuilder x = new StringBuilder();
static int a = 0;
public static void main(String[] args) {
generatingnumber();
}
public static void generatingnumber() {
for (int bv = 0; bv <= 100; bv++) {
int random = rand.nextInt(50);
if (random % 2 == 0) {
x.append(" 0");
} else {
x.append(" 1");
}
if (x.length() == 20) {
System.out.println(x);
}
}
}
}
public class MatrixFilm {
public static void main(String[] args) {
int rows = 100;
int cols = 20;
for (int count1 = 0; count1 < (rows * cols); count1++) {
for (int count2 = 0; count2 < cols; count2++) {
int randomNum = 0 + (int) (Math.random() * 2);
System.out.print(" " + randomNum);
}
System.out.println();
}
}
}
Result:
0 0 1 0 0 0 0 1 0 0 1 1 0 0 1 0 1 1 1 1
1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 0 0 1 0
0 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 0
0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 0
0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 0
....
Your string has length of 20 characters only once. You are not interested in whether x.length() == 20 but if x.length() % 20 == 0.
For a new line you can append "\n" (or "\r\n" for Windows machine) to the string, everytime just before printing it.
Change println to print (which doesn't add new line character at the end of printed string) in order to maintain continuity between prints.
Taking all into account:
if (x.length() % 20 == 0) {
x.append("\r\n");
System.out.print(x);
}
However it still wouldn't be enough, for "\r\n" itself adds to the length of the string. This should work:
if (x.length() % 20 == 0) {
x.replace(x.length() - 2, x.length(), "\r\n");
System.out.print(x);
}
You can also - and it would be better to... - reset the string, as #owlstead has mentioned.
if (x.length() == 20) {
System.out.println(x);
x.setLength(0);
}
Anyway; what I presented is not a solution for the problem. Only solution to - probably improper - approach you have currently taken on it.

Java recursion Issue with the flood fill algorithm

I am trying to write a program to locate and count all connected regions in a grid. A connected region consists of a set of marked cells (value 1) such that each cell in the region can be reached by moving up, down, left or right from another marked cell in the region, cells on a diagonal line are not considered connected.
So, it would take an input of:
10 20
0 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 1 0
0 1 1 1 0 1 1 0 0 1 0 0 1 1 1 0 0 0 1 1
0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 1 1
1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 1 1 0
1 1 0 1 0 0 0 1 1 1 0 0 0 1 1 0 1 1 0 0
1 1 1 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0
0 1 1 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 0 0
0 1 1 1 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 0
0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0
1 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 0
And outputs:
0 1 1 0 0 0 2 0 3 3 0 0 0 0 4 0 0 0 5 0
0 1 1 1 0 2 2 0 0 3 0 0 4 4 4 0 0 0 5 5
0 0 1 0 0 0 2 2 0 3 0 0 0 4 0 0 0 5 5 5
6 0 0 0 0 0 0 0 3 3 0 0 7 0 0 0 5 5 5 0
6 6 0 6 0 0 0 3 3 3 0 0 0 8 8 0 5 5 0 0
6 6 6 6 0 0 0 0 0 0 9 0 8 8 8 0 0 0 0 0
0 6 6 6 0 0 0 9 9 9 9 0 0 8 8 0 8 0 0 0
0 6 6 6 6 6 0 0 9 9 9 0 0 0 8 8 8 8 8 0
0 0 0 6 6 0 0 0 0 9 0 0 0 8 8 0 0 8 8 0
10 0 6 6 6 6 6 0 0 0 0 0 0 0 8 8 0 8 0 0
Right now, when I run the code, I get:
0 2 2 0 0 0 2 0 2 2 0 0 0 0 2 0 0 0 2 0
0 3 3 3 0 3 3 0 0 3 0 0 3 3 3 0 0 0 3 3
0 0 4 0 0 0 4 4 0 4 0 0 0 4 0 0 0 4 4 4
5 0 0 0 0 0 0 0 5 5 0 0 5 0 0 0 5 5 5 0
6 6 0 6 0 0 0 6 6 6 0 0 0 6 6 0 6 6 0 0
7 7 7 7 0 0 0 0 0 0 7 0 7 7 7 0 0 0 0 0
0 8 8 8 0 0 0 8 8 8 8 0 0 8 8 0 8 0 0 0
0 9 9 9 9 9 0 0 9 9 9 0 0 0 9 9 9 9 9 0
0 0 0 10 10 0 0 0 0 10 0 0 0 10 10 0 0 10 10 0
11 0 11 11 11 11 11 0 0 0 0 0 0 0 11 11 0 11 0 0
Here is my code:
package project2;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
public class Project2 {
private static int height;
private static int length;
public static void main(String[] args) {
String inputFile;
Scanner input = new Scanner(System.in);
System.out.print("Enter input file name: ");
inputFile = "test_case_proj2.txt";
try {
Integer grid[][] = loadGrid(inputFile);
System.out.println("Before flood fill");
printGrid(grid);
findGroups(grid, 0, 0, 2, height, length);
System.out.println("After flood fill");
printGrid(grid);
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
public static void findGroups(Integer[][] array, int column, int row,
int counter, int height, int length) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < length; j++) {
if (row < 0 || row >= length || column < 0 || column >= height) {
} else {
if (array[column][j] == 1) {
array[column][j] = counter;
findGroups(array, column, row + 1, counter, height, length);
findGroups(array, column, row - 1, counter, height, length);
findGroups(array, column - row, j, counter, height, length);
findGroups(array, column + row, j, counter, height, length);
}
}
}
counter++;
column++;
row++;
}
}
public static Integer[][] loadGrid(String fileName) throws IOException {
FileInputStream fin;
fin = new FileInputStream(fileName);
Scanner input = new Scanner(fin);
height = input.nextInt();
length = input.nextInt();
Integer grid[][] = new Integer[height][length];
for (int r = 0; r < height; r++) {
for (int c = 0; c < length; c++) {
grid[r][c] = input.nextInt();
}
}
fin.close();
return (grid);
}
public static void printGrid(Integer[][] grid) {
for (Integer[] grid1 : grid) {
for (int c = 0; c < grid[0].length; c++) {
System.out.printf("%3d", grid1[c]);
}
System.out.println();
}
}
}
Does someone see what I am doing wrong?
You put too much responsibilities into one method. You combine the floodfill algorithm with your island numbering algorithm.
I've created this jdoodle.
First of all you better create a single fill method, that does nothing more than filling islands with the value of a counter (I've made it static so you don't need to pass it through the algorithm, although this is arbitrary):
public static void fill(Integer[][] array, int column, int row, int height, int length) {
if (row >= 0 && row < length && column >= 0 && column < height && array[column][row] == 1) {
array[column][row] = counter;
fill(array, column, row + 1, height, length);
fill(array, column, row - 1, height, length);
fill(array, column - 1, row, height, length);
fill(array, column + 1, row, height, length);
}
}
As you can see, it's a simple algorithm that uses recursion.
Secondly, you simply create a method that calls the fill algorithm on all the possible tiles. If you reach a point with a value of 1, you know that this island has not been claimed by another king yet :D. Thus you fill it and claim it to the king with the counter id. Normally one uses a special array of boolean to prevent the fill algorithm to go into an infinite loop. You solved this smartly by starting to assign number from index counter = 2, of course once all island are claimed, you need to decrement the value.
public static void findGroups(Integer[][] array, int column, int row, int height, int length) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < length; j++) {
if (array[i][j] == 1) {
fill(array, i,j, height, length);
counter++;
}
}
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < length; j++) {
if (array[i][j] > 1) {
array[i][j]--;
}
}
}
}
The rest of the algorithm remains the same (the algorithm now reads from stdin, but this is simply to make sure the jdoodle keeps working).
About your algorithm, it's quite hard to understand. For instance you use a fill and part of the calls use column and row, other parts use j. Next your counter is only updated for each row. This causes problems if two idlands start at the same row (as you can see with your output).

Converting very big integer to bit vector fails

import java.math.BigInteger;
import java.util.ArrayList;
public class Factorial {
public static int[] bitVector(int n) {
ArrayList<Integer> bitList = new ArrayList<Integer>();
BigInteger input = computeFactorial(n);
System.out.println(input);
BigInteger[] result = input.divideAndRemainder(new BigInteger(String.valueOf(2)));
if (result[0].intValue()==0) {return new int[]{result[1].intValue()};}
else {
bitList.add(result[1].intValue());
}
while(result[0].intValue() != 0) {
result = result[0].divideAndRemainder(new BigInteger(String.valueOf(2)));
bitList.add(result[1].intValue());
}
int[] array = new int[bitList.size()];
for (int i=0; i<array.length; i++) {
array[i]=bitList.get(i).intValue();
}
return array;
}
public static BigInteger computeFactorial(int n) {
if (n==0) {
return new BigInteger(String.valueOf(1));
} else {
return new BigInteger(String.valueOf(n)).multiply(computeFactorial(n-1));
}
}
public static void main(String[] args) {
int[] bitVector = bitVector(35);
for (int bit: bitVector)
System.out.print(bit+" ");
System.out.println();
}
}
The code above works fine when the input to bitVector is no bigger than 35. However, when I pass 36 as a parameter to bitVector, all but one bit are gone in the output.
I have potentially ruled out the following causes:
It may have nothing to do with the BigInteger type since it was designed to never overflow.
It may not be related to memory usage of the program, which uses only 380M at runtime.
I print out the value of computeFactorial(36), which looks good.
What on earth is going on there?
So what you are trying to do is
public static String factorialAsBinary(int n) {
BigInteger bi = BigInteger.ONE;
for (; n > 1; n--)
bi = bi.multiply(BigInteger.valueOf(n));
return bi.toString(2);
}
public static void main(String... args) {
String fact36 = factorialAsBinary(36);
for (char ch : fact36.toCharArray())
System.out.print(ch + " ");
System.out.println();
}
which prints
1 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
What on earth is going on there?
Your code is much more complicated than it needs to be which also makes it easier to make mistakes and harder to understand.
result[0].intValue() is wrong:
intValue():
Converts this BigInteger to an int. This conversion is analogous to a narrowing primitive conversion from long to int as defined in the Java Language Specification: if this BigInteger is too big to fit in an int, only the low-order 32 bits are returned. Note that this conversion can lose information about the overall magnitude of the BigInteger value as well as return a result with the opposite sign.
in your case it returns the lowest 32 bits which are zero therefore you return 0 after first devision

Add numbers from 100 to 1000 that are divisible by five AND six

My program is correct except for that in the end, the program must output two \n\n. Just like that. Only on the last line, however. At every ten sets, it should only output one \n. THis is what the program should look like:
1 2 0 1 5 0 1 8 0 2 1 0
2 4 0 2 7 0 3 0 0 3 3 0
3 6 0 3 9 0 \n 4 2 0 4 5 0
4 8 0 5 1 0 5 4 0 5 7 0
6 0 0 6 3 0 6 6 0 6 9 0 \n
7 2 0 7 5 0 7 8 0 8 1 0
8 4 0 8 7 0 9 0 0 9 3 0
9 6 0 9 9 0 \n \n
This is my code.
import java.util.Scanner;
public class Exercise4_10 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int count = 1;
for (int i = 100; i <= 1000; i++) {
if (i%5==0 && i%6==0)
System.out.print((count++ % 10 != 0) ? i + " ": i + "\n" );
}
}
}
add this before the closing brace for main:
System.out.println("");
}
import java.util.Scanner;
public class Exercise4_10 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
for (int i = 100; i <= 1000; i++) {
// You can avoid 5 & 6 by using 30 ( 5*6) - optional
if (i%30==0)
//You can skip using another variable count & use i for the same - optional
System.out.print(((i+1) % 10 != 0) ? i + " ": i + "\n" );
}
//Will print \n only in the end
System.out.print("\n" );
}
}

Categories

Resources