counting the number of zeros [closed] - java

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm trying to write a program that gets a .txt file that only has something like 10000010000010000010001
I'm trying to count the number of zeros and output it like 5 5 5 3. I thought if I convert a string into a double or int I could write an if or for loop.
import java.util.Scanner;
public class test1{
public static void main(String[] args) {
java.io.File test2 = new java.io.File("test3.txt");
try
{
Scanner input = new Scanner(test2);
while(input.hasNext())
{
String num = input.nextLine();
System.out.println(num);
double n = Double.parseDouble(num);
System.out.println(n);
}
}
catch (Exception e){
System.out.println("could not find file");
}
}
}

Here you go:
char[] numArray = num.toCharArray();
int counter=0;
for(int i=0;i<numArray.length;i++) {
if(numArray[i]=='0') {
counter++;
}
if((i==numArray.length-1&&counter>0)||(counter>0&&numArray[i]!='0')) {
System.out.println("Number of Zeroes: "+counter);
counter=0;
}
}
Some important points:
1) It's best to use an array of char values here, instead of operating using a double, because a char array can store many more values- the example you posted is too long for a double to handle.
2) Most of this should be self-explanatory (at least, if you study it bit-by-bit), but in case the i==numArray.length-1 part is confusing, this ensures that if the string ends with a 0, the final count of 0's will be printed out as well.
This should work for any string you can throw at it- including values besides 0 and 1, if you need support for it!

where is your effort?
you can simply try (if your string contains only 1s and 0s):
String[] splitArr = num.split("1");
String countStr = "";
for (int i = 0; i < splitArr.length; i++) {
if( ! splitArr[i].isEmpty() )
countStr += splitArr[i].length();
}
System.out.println(countStr);

import java.util.*;
import java.io.*;
public class ZeroCounter {
ArrayList <Integer> listOfNumbers = new ArrayList <Integer> ();
DataInputStream inStream;
long inFileSize;
long outFileSize;
// Track how many bytes we've read. Useful for large files.
int byteCount;
public ZeroCounter() {
}
//read the file and turn it into an array of integers
public void readFile(String fileName) {
try {
// Create a new File object, get size
File inputFile = new File(fileName);
inFileSize = inputFile.length();
// The constructor of DataInputStream requires an InputStream
inStream = new DataInputStream(new FileInputStream(inputFile));
}
// Oops. Errors.
catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
// Read the input file
try {
// While there are more bytes available to read...
while (inStream.available() > 0) {
// Read in a single byte and store it in a character
int c = (int)inStream.readByte();
if ((++byteCount)% 1024 == 0)
System.out.println("Read " + byteCount/1024 + " of " + inFileSize/1024 + " KB...");
// Print the integer to see them for debugging purposes
//System.out.print(c);
// Add the integer to an ArrayList
fileArray.add(c);
}
// clean up
inStream.close();
System.out.println("File has been converted into an ArrayList of Integers!");
}
// Oops. Errors.
catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
//Print the ArrayList contents for debugging purposes
//System.out.println(fileArray);
}
public void countZeroes() {
int zeroCounter = 0;
for (int i = 0; i < listOfNumbers.size(); i++) {
if (listOfNumbers.get(i) == 0) {
zeroCounter++;
}
else if (listOfNumbers.get(i) != 0 && zeroCounter > 0) {
//this only prints the number of zeroes if the zero counter isn't zero
System.out.println(zeroCounter + " ");
zeroCounter = 0;
}
else {
//do nothing
}
}
}
public static void main(String[] args) {
ZeroCounter comp = new ZeroCounter();
comp.readFile("test3.txt");
comp.countZeroes();
}
}

Related

Creating triple-ended queue with efficient random access

I have been tasked to solve a question concerning the creation of a triple-ended queue with efficient random access, as outlined in this: https://open.kattis.com/problems/teque. I created a program based around using 2 very large arrays, one containing the front half of all stored integers so far and the other the back half, with both being of the same size or the front half containing at most 1 more element than the back half after every insertion operation. This should allow all insertion and retrieval operations to be of O(1) time complexity, but the code just keeps exceeding the given time limit. Can anyone tell me what is wrong with my code? Here it is:
import java.util.*;
import java.io.*;
public class Teque3 {
static int[] front = new int[1_000_000];
static int[] back = new int[1_000_000];
static int frontHead = 499_999;
static int backHead = 499_999;
static int frontSize = 0;
static int backSize = 0;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
String[] line = br.readLine().split(" ");
if (line[0].equals("get")) {
int index = Integer.parseInt(line[1]);
if (index >= frontSize) System.out.println(back[backHead + index - frontSize]);
else System.out.println(front[frontHead + index]);
continue;
}
if (frontSize == backSize) {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
frontSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
front[frontHead + frontSize] = back[backHead];
frontSize++;
backHead++;
} else if (line[0].equals("push_middle")) {
front[frontHead + frontSize] = Integer.parseInt(line[1]);
frontSize++;
}
} else {
if (line[0].equals("push_front")) {
frontHead--;
front[frontHead] = Integer.parseInt(line[1]);
backHead--;
back[backHead] = front[frontHead + frontSize];
backSize++;
} else if (line[0].equals("push_back")) {
back[backHead + backSize] = Integer.parseInt(line[1]);
backSize++;
} else if (line[0].equals("push_middle")) {
backHead--;
back[backHead] = Integer.parseInt(line[1]);
backSize++;
}
}
}
}
}
You could try to minimze IO-Operations: Collect your programm output. Instead of writing System.out.println better create a new StringBuilder to collect everything. In the end write all at once.
static StringBuilder result = new StringBuilder();
...
private static void result(int value) {
result.append(value).append("\n");
}
...
if (index >= frontSize) result(back[backHead + index - frontSize]);
else result(front[frontHead + index]);
...
System.out.println(result);
Decouple read from parse and process: Create one thread for reading the operations. But the operations in a Queue. Start another thread for the process.

I want to parse a string of values and divide the output from array values by position. Why are my odd array elements not displaying? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Why is the else statement not giving the values of sub[1], sub[3], sub[5], etc (odd array positions)?
What am I doing wrong? I thought that i % 2 == 0 would give me the even array positions? Therefore, the else statement should give me the odd, correct?
public class PolyValues {
public PolyValues() {
String value = "5 6 8 9 1 9";
String sub[] = value.split(" ");
double coeff = 0;
int exp = 0;
for (int i = 0; i < sub[i].length(); i++) {
if (sub[i].isEmpty()) {
System.out.println("No input");
}
if (i % 2 == 0) {
try {
coeff = Double.parseDouble(sub[i]);
System.out.println(coeff);
} catch (NumberFormatException e) {
System.out.println("Fix This");
}
} else {
try {
exp = Integer.parseInt(sub[i]);
System.out.println(exp);
} catch (NumberFormatException e) {
System.out.println("Fix This");
}
}
}
public static void main(String[] args) {
Polyvalues p1 = new Polyvalues();
}
} //end of class
You are getting the length of the strings from sub array and not the length of that array.
Change in the for:
i<sub[i].length()
to
i<sub.length

Integer.toBinaryString() Loses Leading 0's [duplicate]

This question already has answers here:
How to get 0-padded binary representation of an integer in java?
(17 answers)
Closed 5 years ago.
I'm currently working with a Huffman Tree to compress/decompress text files. Currently my problem is that when writing bytes and reading them, I lose any leading 0's in my numbers.
In my OutputStream class, my writeBit()method, I am fed one bit at a time and when my count of bits reaches 8, I write the byte to the file. Currently using a String to build this binary number, although the problem occurs when actually writing the bit.
HuffmanOutputStream.java:
/**
* Created by Sully on 3/20/2017.
*/
import java.io.IOException;
public class HuffmanOutputStream extends BitOutputStream {
private int count = 0;
private String bytes = "";
public HuffmanOutputStream(String filename, String tree, int totalChars) {
super(filename);
try {
d.writeUTF(tree);
d.writeInt(totalChars);
} catch (IOException e) {
}
}
public void writeBit(int bit) {
//PRE bit == 0 || bit == 1
if (count < 8) {
bytes += bit;
count++;
}
try {
if (count == 8) {
d.writeByte(Integer.parseInt(bytes, 2));
count = 0;
bytes = "";
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void close() {
}
}
An example of when things go wrong, for my text file, the first byte that I construct is 01100001, although when I use Integer.parseInt(byte,2), the integer given is 97, which when it is then read as a binary number, only returns 1100001. As Huffman Trees rely on these 0's being included, how can I keep this 0 in place? Also to make sure that it is read correctly with the 0's remaining in place?
HuffmanInputStream.java:
/**
* Created by Sully on 3/20/2017.
*/
import java.io.IOException;
public class HuffmanInputStream extends BitInputStream {
private String tree;
private int totalChars;
private int currentByte;
private int bitCount;
private static final int BYTE_SIZE = 8;
private int[] bufferedBits = new int[BYTE_SIZE];
public HuffmanInputStream(String filename) {
super(filename);
try {
tree = d.readUTF();
totalChars = d.readInt();
currentByte = 0;
bitCount = 8;
} catch (IOException e) {
}
}
public int readBit() {
if (currentByte == -1) {
return -1;
}
if (bitCount == 8) {
try {
currentByte = d.read();
if(currentByte == -1){
return -1;
}
String binary = Integer.toBinaryString(currentByte);
for (int x = 0; x < binary.length(); x++) {
bufferedBits[x] = Character.valueOf(binary.charAt(x));
}
bitCount = 0;
} catch (IOException e) {
e.printStackTrace();
}
}
int val = bufferedBits[bitCount];
bitCount++;
return val % 2;
}
public String getTree() {
return tree;
}
public int totalChars() {
return totalChars;
}
public void close() {
try {
d.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I know it's a bit lengthy of a question but any help is greatly appreciated!
I assume that you're looking to have enough leading 0s to make the length of the String that is returned from Integer#toBinaryString 8; the following code will achieve this for you:
String binary = String.format("%8s", Integer.toBinaryString(currentByte)).replace(' ', '0');

Write data to text file from array of objects in Java [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
public class ReaderWriter extends Bank {
private final String FILENAME = "clients.txt";
public void writeToFile() {
int i = 0;
boolean repeat = true;
Formatter output = null; // Used to write to file
try {
output = new Formatter(FILENAME);
// Open the file
while ((i <= accounts.length - 1) && (accounts[i] != null)) {
output.format("%s\n", accounts[i].getAccountHolder());
output.format("%d%n", accounts[i].getAccountNumber());
output.format("%d%n", accounts[i].getAmount());
i = i + 1;
}catch (Exception ex) {
ex.printStackTrace();
} finally {
output.close(); // Make sure to close the resource after usage.
}
}
And this is Bank class:
public class Bank {
public final int MAX_NUMBER_OF_ACCOUNTS = 10;
public int max = 0;
String name1;
int money1;
int number1;
Scanner input = new Scanner(System.in);
BankAccount[] accounts = new BankAccount[MAX_NUMBER_OF_ACCOUNTS];
public void greateAccount() {
int i = 0;
boolean repeate2 = true;
System.out.println("You have chosen to create a new account.");
System.out.println("Enter the name of the account holder: ");
name1 = input.next();
System.out.println("Enter the account no.");
number1 = input.nextInt();
System.out.println("Enter the initiating amount: ");
money1 = input.nextInt();
while (repeate2 == true) {
if (accounts[i] == null) {
if (i < 1) {
accounts[i] = new BankAccount();
accounts[i].setAccountHolder(name1);
accounts[i].setAccountNumber(number1);
accounts[i].setAmount(money1);
repeate2 = false;
} else {
if (ifAccountExist(number1) != true) {
accounts[i] = new BankAccount();
accounts[i].setAccountHolder(name1);
accounts[i].setAccountNumber(number1);
accounts[i].setAmount(money1);
repeate2 = false;
} else {
System.out.println("****This account ALREADY EXIST!****");
System.out.println("*************************************");
System.out.println();
max = max - 1;
repeate2 = false;
}
}
}
i = i + 1;
}
max++;
}
Now I want to write to text file account number, name and money.
My code doesn't work. I does not write it can not retrieve values from array I don't know why?
Can you help me?
The code is not going to compile, for many reasons...
For example:
Why this line:
ex.printStackTrace();
is floating in your class ReaderWriter (line 21) and away a catch block?
Why you don't have include declarations?

I am trying to solve '15 puzzle', but I get 'OutOfMemoryError' [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
Is there a way that I can optimize this code as to not run out of memory?
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Stack;
public class TilePuzzle {
private final static byte ROWS = 4;
private final static byte COLUMNS = 4;
private static String SOLUTION = "123456789ABCDEF0";
private static byte RADIX = 16;
private char[][] board = new char[ROWS][COLUMNS];
private byte x; // Row of the space ('0')
private byte y; // Column of the space ('0') private String representation;
private boolean change = false; // Has the board changed after the last call to toString?
private TilePuzzle() {
this(SOLUTION);
int times = 1000;
Random rnd = new Random();
while(times-- > 0) {
try {
move((byte)rnd.nextInt(4));
}
catch(RuntimeException e) {
}
}
this.representation = asString();
}
public TilePuzzle(String representation) {
this.representation = representation;
final byte SIZE = (byte)SOLUTION.length();
if (representation.length() != SIZE) {
throw new IllegalArgumentException("The board must have " + SIZE + "numbers.");
}
boolean[] used = new boolean[SIZE];
byte idx = 0;
for (byte i = 0; i < ROWS; ++i) {
for (byte j = 0; j < COLUMNS; ++j) {
char digit = representation.charAt(idx++);
byte number = (byte)Character.digit(digit, RADIX);
if (number < 0 || number >= SIZE) {
throw new IllegalArgumentException("The character " + digit + " is not valid.");
} else if(used[number]) {
throw new IllegalArgumentException("The character " + digit + " is repeated.");
}
used[number] = true;
board[i][j] = digit;
if (digit == '0') {
x = i;
y = j;
}
}
}
}
/**
* Swap position of the space ('0') with the number that's up to it.
*/
public void moveUp() {
try {
move((byte)(x - 1), y);
} catch(IllegalArgumentException e) {
throw new RuntimeException("Move prohibited " + e.getMessage());
}
}
/**
* Swap position of the space ('0') with the number that's down to it.
*/
public void moveDown() {
try {
move((byte)(x + 1), y);
} catch(IllegalArgumentException e) {
throw new RuntimeException("Move prohibited " + e.getMessage());
}
}
/**
* Swap position of the space ('0') with the number that's left to it.
*/
public void moveLeft() {
try {
move(x, (byte)(y - 1));
} catch(IllegalArgumentException e) {
throw new RuntimeException("Move prohibited " + e.getMessage());
}
}
/**
* Swap position of the space ('0') with the number that's right to it.
*/
public void moveRight() {
try {
move(x, (byte)(y + 1));
} catch(IllegalArgumentException e) {
throw new RuntimeException("Move prohibited " + e.getMessage());
}
}
private void move(byte movement) {
switch(movement) {
case 0: moveUp(); break;
case 1: moveRight(); break;
case 2: moveDown(); break;
case 3: moveLeft(); break;
}
}
private boolean areValidCoordinates(byte x, byte y) {
return (x >= 0 && x < ROWS && y >= 0 && y < COLUMNS);
}
private void move(byte nx, byte ny) {
if (!areValidCoordinates(nx, ny)) {
throw new IllegalArgumentException("(" + nx + ", " + ny + ")");
}
board[x][y] = board[nx][ny];
board[nx][ny] = '0';
x = nx;
y = ny;
change = true;
}
public String printableString() {
StringBuilder sb = new StringBuilder();
for (byte i = 0; i < ROWS; ++i) {
for (byte j = 0; j < COLUMNS; ++j) {
sb.append(board[i][j] + " ");
}
sb.append("\r\n");
}
return sb.toString();
}
private String asString() {
StringBuilder sb = new StringBuilder();
for (byte i = 0; i < ROWS; ++i) {
for (byte j = 0; j < COLUMNS; ++j) {
sb.append(board[i][j]);
}
}
return sb.toString();
}
public String toString() {
if (change) {
representation = asString();
}
return representation;
}
private static byte[] whereShouldItBe(char digit) {
byte idx = (byte)SOLUTION.indexOf(digit);
return new byte[] { (byte)(idx / ROWS), (byte)(idx % ROWS) };
}
private static byte manhattanDistance(byte x, byte y, byte x2, byte y2) {
byte dx = (byte)Math.abs(x - x2);
byte dy = (byte)Math.abs(y - y2);
return (byte)(dx + dy);
}
private byte heuristic() {
byte total = 0;
for (byte i = 0; i < ROWS; ++i) {
for (byte j = 0; j < COLUMNS; ++j) {
char digit = board[i][j];
byte[] coordenates = whereShouldItBe(digit);
byte distance = manhattanDistance(i, j, coordenates[0], coordenates[1]);
total += distance;
}
}
return total;
}
private class Node implements Comparable<Node> {
private String puzzle;
private byte moves; // Number of moves from original configuration
private byte value; // The value of the heuristic for this configuration.
public Node(String puzzle, byte moves, byte value) {
this.puzzle = puzzle;
this.moves = moves;
this.value = value;
}
#Override
public int compareTo(Node o) {
return (value + moves) - (o.value + o.moves);
}
}
private void print(Map<String, String> antecessor) {
Stack toPrint = new Stack();
toPrint.add(SOLUTION);
String before = antecessor.get(SOLUTION);
while (!before.equals("")) {
toPrint.add(before);
before = antecessor.get(before);
}
while (!toPrint.isEmpty()) {
System.out.println(new TilePuzzle(toPrint.pop()).printableString());
}
}
private byte solve() {
if(toString().equals(SOLUTION)) {
return 0;
}
PriorityQueue<Node> toProcess = new PriorityQueue();
Node initial = new Node(toString(), (byte)0, heuristic());
toProcess.add(initial);
Map<String, String> antecessor = new HashMap<String, String>();
antecessor.put(toString(), "");
while(!toProcess.isEmpty()) {
Node actual = toProcess.poll();
for (byte i = 0; i < 4; ++i) {
TilePuzzle t = new TilePuzzle(actual.puzzle);
try {
t.move(i);
} catch(RuntimeException e) {
continue;
}
if (t.toString().equals(SOLUTION)) {
antecessor.put(SOLUTION, actual.puzzle);
print(antecessor);
return (byte)(actual.moves + 1);
} else if (!antecessor.containsKey(t.toString())) {
byte v = t.heuristic();
Node neighbor = new Node(t.toString(), (byte)(actual.moves + 1), v);
toProcess.add(neighbor);
antecessor.put(t.toString(), actual.puzzle);
}
}
}
return -1;
}
public static void main(String... args) {
TilePuzzle puzzle = new TilePuzzle();
System.out.println(puzzle.solve());
}
}
The problem
The root cause is the tons of String objects you are creating and storing in the toProcess Queue and the antecessor Map. Why are you doing that?
Look at your algorithm. See if you really need to store >2 million nodes and 5 million strings in each.
The investigation
This was hard to spot because the program is complex. Actually, I didn't even try to understand all of the code. Instead, I used VisualVM – a Java profiler, sampler, and CPU/memory usage monitor.
I launched it:
And took a look at the memory usage. The first thing I noticed was the (obvious) fact that you're creating tons of objects.
This is an screenshot of the app:
As you can see, the amount of memory used is tremendous. In as few as 40 seconds, 2 GB were consumed and the entire heap was filled.
A dead end
I initially thought the problem had something to do with the Node class, because even though it implements Comparable, it doesn't implement equals. So I provided the method:
public boolean equals( Object o ) {
if( o instanceof Node ) {
Node other = ( Node ) o;
return this.value == other.value && this.moves == other.moves;
}
return false;
}
But that was not the problem.
The actual problem turned out to be the one stated at the top.
The workaround
As previously stated, the real solution is to rethink your algorithm. Whatever else can be done, in the meantime, will only delay the problem.
But workarounds can be useful. One is to reuse the strings you're generating. You're very intensively using the TilePuzzle.toString() method; this ends up creating duplicate strings quite often.
Since you're generating string permutations, you may create many 12345ABCD strings in matter of seconds. If they are the same string, there is no point in creating millions of instances with the same value.
The String.intern() method allows strings to be reused. The doc says:
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals() method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
For a regular application, using String.intern() could be a bad idea because it doesn't let instances be reclaimed by the GC. But in this case, since you're holding the references in your Map and Queue anyway, it makes sense.
So making this change:
public String toString() {
if (change) {
representation = asString();
}
return representation.intern(); // <-- Use intern
}
Pretty much solves the memory problem.
This is a screenshot after the change:
Now, the heap usage doesn't reach 100 MB even after a couple of minutes.
Extra remarks
Remark #1
You're using an exception to validate if the movement is valid or not, which is okay; but when you catch them, you're just ignoring them:
try {
t.move(i);
} catch(RuntimeException e) {
continue;
}
If you're not using them anyway, you can save a lot of computation by not creating the exceptions in the first place. Otherwise you're creating millions of unused exceptions.
Make this change:
if (!areValidCoordinates(nx, ny)) {
// REMOVE THIS LINE:
// throw new IllegalArgumentException("(" + nx + ", " + ny + ")");
// ADD THIS LINE:
return;
}
And use validation instead:
// REMOVE THESE LINES:
// try {
// t.move(i);
// } catch(RuntimeException e) {
// continue;
// }
// ADD THESE LINES:
if(t.isValidMovement(i)){
t.move(i);
} else {
continue;
}
Remark #2
You're creating a new Random object for every new TilePuzzle instance. It would be better if you used just one for the whole program. After all, you are only using a single thread.
Remark #3
The workaround solved the heap memory problem, but created another one involving PermGen. I simply increased the PermGen size, like this:
java -Xmx1g -Xms1g -XX:MaxPermSize=1g TilePuzzle
Remark #4
The output was sometimes 49 and sometimes 50. The matrices were printed like:
1 2 3 4
5 6 7 8
9 A B C
D E 0 F
1 2 3 4
5 6 7 8
9 A B C
D E F 0
... 50 times

Categories