How to implement dfs using recursion? - java

I'm trying to implement DFS with recursion using the following code,
public static void dfs(int i, int[][] mat, boolean [] visited){
visited[i] = true; // Mark node as "visited"
System.out.print(i + "\t");
for ( int j = 0; j < visited.length; j++ ){
if ( mat[i][j] ==1 && !visited[j] ){
dfs(j, mat, visited); // Visit node
}
}
}
I have a matrix and an array for tracking visited nodes,
// adjacency matrix for uni-directional graph
int [][] arr = {
// 1 2 3 4 5 6 7 8 9 10
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 1
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, // 2
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 3
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // 4
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // 5
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 6
{ 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}, // 7
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 8
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, // 9
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // 10
};
boolean [] visited = new boolean[10];
for (int i =0; i< visited.length; ){
visited[i++] = false;
}
I'm making the call as following,
dfs(1, arr, visited);
This return
// 1 6 7 8 9
which is not correct. It should return : [1 2 7 8 9 10 3 4 5 6]
The graph is as following,
How can I improve my code ?

Your code is perfectly correct, just call is incorrect.
You're calling the dfs on the 1st node, but root is at 0th node.
So if you just replace
dfs(1, arr, visited);
with
dfs(0, arr, visited);
it would print the correct order of indices, which means every element would be one less than your required result as Java array index starts at 0.
Also there's no need to initialize a primitive array as Java primitive arrays are already initialized and default value of boolean is false.
Following is the code after modifications
public class Dfs {
public static void main(String[] args) {
int[][] arr = {
// 1 2 3 4 5 6 7 8 9 10
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, // 1
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 2
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 4
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // 5
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 6
{ 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 7
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 8
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, // 9
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // 10
};
boolean [] visited = new boolean[10];
dfs(0, arr, visited);
}
public static void dfs(int i, int[][] mat, boolean[] visited) {
if(!visited[i]) {
visited[i] = true; // Mark node as "visited"
System.out.print( (i+1) + " ");
for (int j = 0; j < mat[i].length; j++) {
if (mat[i][j] == 1 && !visited[j]) {
dfs(j, mat, visited); // Visit node
}
}
}
}
}
Output
1 2 7 8 9 10 3 4 5 6

Related

For Loop Map Overwrites Previous Value

Essentially I am making a board game using sockets. Each client connected is stored in a map .
When the user makes a move to a coordinate in the 2D Array i.e. "move 2,3", it should put the connectionID in that position.
Currently my issue is, because I have a for loop; when i use the move command, the connection ID is replaced with the last value in the loop.
public void move(int x, int y) {
for (int value : gs.returnClients().values()) {
storeArray[x][y] = value;
}
}
i.e. If i have 2 clients connected: {62029=1, 62032=2} and my board
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Let's say I want to have client 1 move to 0, 3 it should be:
[[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
But instead I get:
[[0, 0, 0, 2, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Since it's overwriting the last value of the map in the for loop.
How would I make it move dependent on its client "id" from the map?
Edit
In my server i have clients.put(socket.getPort(), connectionID); and methods to return the map and id. I have a class GameService that executes command which is
switch (request.type) {
case MOVE:
int clientID = Integer.parseInt(request.params[0]);
int getX = Integer.parseInt(request.params[1]);
int getY = Integer.parseInt(request.params[2]);
game.move(clientID,getX, getY);
return game.returnBoard();
In a file Request
String[] items = line.trim().split("\\s+");
switch (items[0].toUpperCase()) {
case "MOVE":
return new Request(RequestType.MOVE, items[1], items[2], items[3]);
As far as I understand your code, you need to do your move the following way:
public void move(int client, int x, int y) {
storeArray[x][y] = client;
}
where client is one (!) of the numbers within the gs.returnClients().values()-list. If you need to take it out of that map, you need to deliver the appropriate key for that, e.g.:
public void move(int clientId, int x, int y) {
storeArray[x][y] = gs.returnClients().get(clientId);
}

How do I set specific index in two dimension arrayList

I have the following
ArrayList<ArrayList<Integer>> row = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> column = new ArrayList<Integer>();
for(int i = 0; i < 12; i++) {
column.add(0);
}
for(int j=0; j < 12 ; j++) {
row.add(column);
}
which it gave me
[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]
[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]
[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]
[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]
what I want is to replace a specific index in the arrayList. let's say 2nd arrayList of 3rd index with a 9.
row.get(2).set(3, 9);
but above replaces entire column with 9 instead. how should I set the arrayList to be specific without affecting other rows.
You currently add the same exact column 12 times, but you should add 12 different ones, all shaped in the same way initially:
ArrayList<ArrayList<Integer>> row = new ArrayList<ArrayList<Integer>>();
for(int j=0; j < 12 ; j++) {
ArrayList<Integer> column = new ArrayList<Integer>();
for(int i = 0; i < 12; i++) {
column.add(0);
}
row.add(column);
}
This is because you add the same instance of ArrayList as many times as you have columns, you need to create a copy first as next otherwise indeed all your columns will be affected by a modification:
for(int j=0; j < 12 ; j++) {
row.add(new ArrayList<>(column));
}
It doesn't replace all the values, it only replaces the one value. Your problem is that all 12 elements of the row list is referencing the same column list.
You need to create a new column list for each row.
Also, indexes are zero-based, so to set the 2nd arrayList of 3rd index, you need to specify indexes 1 and 2, not 2 and 3.
If you know the exact size of the matrix, you should use regular arrays, not ArrayList.

Side Collisions

I'm making a tilemap game and I've got the simple collisions down. However to make the game work I have to know which side of the rectangle hit the wall/brick. Just putting a simple collision code inside of the main collision:
if(spriteX < brickX + brickwidth) {}
doesn't work. The main collision code at the moment is:
for(int counter = 0; counter < 31; counter++) {
if(spriteX + 40 >= collisionX[counter] && collisionX[counter] + 100 >= spriteX
&& spriteY + 40 >= collisionY[counter] && collisionY[counter] + 100 >= spriteY) {
velX = 0;
velY = 0;
collisions = counter;
} else {
if(counter == collisions && jumping == false) {
fall();
}
}
}
If you want the entire class:
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class Panel extends JPanel implements Runnable, KeyListener {
// dimensions
public static final int width = 800;
public static final int height = 800;
public static final int scale = 1;
// main loop
private Thread thread;
private boolean running = false;
private int FPS = 60;
private int targetTime = 1000 / FPS;
// drawing
private Graphics2D g;
private BufferedImage image;
int x;
int y;
boolean makeCollision = false;
// sprite
int spriteX = 210;
int spriteY = 200;
int velX = 0;
int velY = 10;
public boolean notOnGround = true;
int counter;
int collisionsCounter;
int jumps = 0;
public int row;
public int column;
public boolean collision;
public boolean jumping = false;
public String side = null;
// tilemap
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
int[] collisionX = {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, 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, 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, 0, 0, 0, 0, 0, 0,
};
int[] collisionY = {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, 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, 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, 0, 0, 0, 0, 0, 0,
};
int[] jump = {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, 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, 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, 0, 0, 0, 0, 0, 0,
};
int collisions;
public Panel() {
setPreferredSize(new Dimension(width * scale, height * scale));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if(thread == null) {
running = true;
addKeyListener(this);
thread = new Thread(this);
thread.start();
}
}
public void init() {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
}
public void update() {
if(spriteY < jump[0]) {
System.out.println(jump[0]);
jumping = false;
fall();
}
}
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
x = 0;
y = 0;
for(column = 0; column <= 7; column++) {
x = 0;
for(row = 0; row <= 7; row++) {
changeColor(row, column, g);
g.fillRect(x, y, 100, 100);
x = x + 100;
}
y = y + 100;
}
g.setColor(Color.YELLOW);
g.fillRect(spriteX, spriteY, 40, 40);
spriteX += velX;
spriteY += velY;
for(int counter = 0; counter < 31; counter++) {
if(spriteX + 40 >= collisionX[counter] && collisionX[counter] + 100 >= spriteX
&& spriteY + 40 >= collisionY[counter] && collisionY[counter] + 100 >= spriteY){
velX = 0;
velY = 0;
collisions = counter;
} else {
if(counter == collisions && jumping == false) {
fall();
}
}
}
}
public void changeColor(int rowGive, int columnGive, Graphics g) {
if(map[rowGive][columnGive] == 1) {
g.setColor(Color.BLACK);
if(counter < 30) {
collisionX[counter] = x;
collisionY[counter] = y;
}
counter++;
} else {
g.setColor(Color.WHITE);
}
}
public void fall() {
velY = 5;
}
public void drawToScreen() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, width * scale, height * scale, null);
g2.dispose();
}
public void run() {
init();
long wait;
long elapsed;
long start;
while(running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0) wait = 5;
try {
thread.sleep(wait);
} catch(Exception e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_RIGHT) {
velX = 5;
}
if(code == KeyEvent.VK_LEFT) {
velX = -5;
}
if(code == KeyEvent.VK_SPACE && jumping == false) {
jumping = true;
velY = -5;
jump[0] = spriteY - 100;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}}
Let's try to divide the problem a little bit. You don't need to find out when a rectange hit a wall: you need to find when the left side of the rectangle hit the right side of the wall and when the right side of the rectangle hit the left side of the wall.
To be more precise: don't test objects. Divide your object in collision surfaces (left and right sides in your case), find a way to modelize them (usually x and x+width are the left and right side of your rectangle, if x is the x coordinate of your topleft corner). And test both at the same time with an "or" condition.
if(spriteX < brickX + brickwidth || spriteX + spritewidth > brickX) {}
edit Reading your complete class a little more closely, it looks like you do something similar but you use "&&" condition, meaning you can never be true since both side collisions cannot happen at the same time. But I may be wrong, can you tell me ?
While not strictly about your collision problem I've noticed a "bug" in draw() that is causing your map array to be displayed flipped around the -45 angle.
You should be incrementing y when row is incremented and x when column is incremented. Do this and your display will look the same as your map initialization code.
In other words this:
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
x = 0;
y = 0;
for(column = 0; column <= 7; column++) {
y = 0;
for(row = 0; row <= 7; row++) {
changeColor(row, column, g);
g.fillRect(x, y, 100, 100);
y = y + 100;
}
x = x + 100;
}
...
will make this
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
look like this
instead of this

Multidimensional arrays: Java. How does this code work?

I've been following a tutorial about creating a basic tile-based tower defense game in Java and have encountered a piece of code I cannot wrap my brain around and would like some help. (My main question is at the bottom after the code)
At this point we are iterating through a multidimensional array of 0's and 1's that we pass to a constructor which has a method that assigns a grass tile for 0's and stone tile for 1's and then another method to draw them to the screen creating our game screen. Simple enough, right?
Here is the class:
package data;
import static helpers.Artist.*;
public class TileGrid {
public Tile[][] map;
public TileGrid(int[][] newMap){
map = new Tile[20][15];
for(int i = 0; i < map.length; i++){
for(int j = 0; j <map[i].length; j++){
switch(newMap[j][i]){
case 0:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.GRASS);
break;
case 1:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.STONE);
break;
case 2:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.WATER);
break;
}
}
}
}
public void Draw(){
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[i].length; j++){
Tile t = map[i][j];
DrawQuadTex(t.getTexture(), t.getX(), t.getY(), t.getWidth(), t.getHeight());
}
}
}
}
And here is the array we are passing in:
int[][] map = { //20 tiles wide, 15 tiles high
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
};
So my main question has to do with the switch statement in the constructor for the TileGrid.
Why do the i and the j get switched newMap[j][i] when checking what it equals? I get that this code works, well, because it does and I understand nested for loops to iterate through a multidimensional array.
But why wouldn't newMap[i][j] work?
As well at the very beginning of that same constructor why do we create an array (of type Tile) with the dimension of map = new Tile[20][15] when we are passing in an array with the dimensions of map[15][20]?
I have tried to figure this out and study this on my own and will continue to do so until I understand it but any help would be soooo appreciated!
You are passing to the TileGrid constructor a 2D array of 15 rows and 20 columns, but inside the constructor you create a 2D array of 20 rows and 15 columns. That's why map[i][j] corresponds with newMap[j][i].
If the input int[][] map was also of 20 rows and 15 columns, you wouldn't have to switch the order of the indices inside the constructor.
This would give an index out of bounds error if it was really switched. However, there is a col variable in the second for loop that is not defined anywhere so it's hard to tell what's going on. This code will not compile.
If it is some code pulled off a a tutorial on some web page, I would just assume that it was a typo and continue on with that in mind. OR better yet, contact the author.

use fileReader in java to read one character at a time

As a part of a school exercise, I am trying to read characters from a text file and count the frequency of the characters appeared the text file. I stored the frequency in an array, where the index is the ASCII code of the char, and the number in the array is the frequency.
int c;
FileReader fr = new FileReader (inputFile);
int [] freq = new int [200];
while ( (c= fr.read())!= -1){
int index = c;
freq [index]= freq [index]+1;
}
PrintWriter pw = new PrintWriter(new FileWriter(outputFile));
for (int i =0; i<frequency.length; i++) {
if(frequency[i]!=0){
pw.println( ((char)i) + " " +frequency[i]);
Somehow this method only works with text files with a single line, like "abcdefgh". It doesn't work with files with multiple lines, like "ab /newline cde /newline..." For this type of file, it will generate a blank line and some numbers on top of the result when I print out the array. I really couldn't figure out why.
It looks fine to me.
import java.io.FileReader;
import java.util.Arrays;
public class Foo {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("/tmp/a");
int[] freq = new int[200];
int c;
while ((c = fr.read()) != -1) {
freq[c] = freq[c] + 1;
}
System.out.println(Arrays.toString(freq));
}
}
Example contents of /tmp/a:
abc
def
Output:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 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, 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]
edit - In response to the revised question:
The output is
2
a 1
b 1
c 1
d 1
e 1
f 1
The file has two line breaks, so the program is writing a line break, and then "2".
I'm guessing you want to convert the characters to something like their Java escape sequences. Here's a solution using Apache commons-lang:
import org.apache.commons.lang3.StringEscapeUtils;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Foo {
public static void main(String[] args) throws Exception {
write(read());
}
static int[] read() throws IOException {
FileReader fr = new FileReader("/tmp/a");
int[] freq = new int[200];
int c;
while ((c = fr.read()) != -1) {
freq[c] = freq[c] + 1;
}
return freq;
}
static void write(int[] freq) throws IOException {
try (PrintWriter pw = new PrintWriter(new FileWriter("/tmp/b"))) {
for (int i = 0; i < freq.length; i++) {
if (freq[i] != 0) {
char c = (char) i;
String s = StringEscapeUtils.escapeJava("" + c);
pw.println(s + " " + freq[i]);
}
}
}
}
}
Output:
\n 2
a 1
b 1
c 1
d 1
e 1
f 1

Categories