File I/O in Java - java

I have problems with the code for my own Vector class.
FIXED. Added reading and writing to file, but this try/catch things look too cumbersome for me. Maybe there's a better way of file I/O?
FIXED-2 Oh, I've just discovered "throws" and now my code looks really good. Thanks everyone for help! Here's the final version of Stack.java:
import java.util.Scanner;
import java.io.*;
class Vector {
private int[] vec;
private int length, pointer;
public Vector(int n) {
pointer = 0;
length = n;
vec = new int[length];
}
public int get(int i) {
return vec[i];
}
public void set(int i, int n) {
vec[i] = n;
}
public void push(int n) {
if (pointer == length) {
int[] nvec = new int[length*2];
for (int i = 0; i < length; i++)
nvec[i] = vec[i];
length *= 2;
vec = null;
vec = nvec;
}
vec[pointer++] = n;
}
public void delete() {
pointer--;
if (pointer == length / 4) {
int[] nvec = new int[length/2];
for (int i = 0; i <= pointer; i++)
nvec[i] = vec[i];
length /= 2;
vec = null;
vec = nvec;
}
}
public int size() {
return pointer;
}
public int actualSize() {
return length;
}
}
public class Stack {
public static void main(String[] args) throws IOException {
File ifile = new File("stack1.in");
BufferedReader reader = new BufferedReader(new FileReader(ifile));
File ofile = new File("stack1.out");
BufferedWriter writer = new BufferedWriter(new FileWriter(ofile));
int n = Integer.parseInt(reader.readLine());
Vector stack = new Vector(10);
for (int i = 0; i < n; i++) {
String s = reader.readLine();
if (s.charAt(0) == '-') {
writer.write(Integer.toString(stack.get(stack.size()-1)));
writer.write("\n");
stack.delete();
} else {
s = s.substring(2);
stack.push(Integer.parseInt(s));
}
}
writer.close();
reader.close();
}
}

Your syntax is wrong. Perhaps you meant something like this:
Vector stack = new Vector(10);
Also, are you sure you want your Vector class inside your Stack class? Also also, it's generally a bad idea to name your classes the same thing as existing Java classes.

Initialise the Vector class as below
Vector stack = new Vector(10);

Vector stack = new Vector(10);

Related

How can I compile this program?

I have a problem with compilation of this program I don't know how can I solve this problem
class ArrayTester{
public void arrayTester(ArrayDeque arrayDeque) {
List evenlist = new ArrayList();
List oddlist = new ArrayList();
for (int n = 0; n < arrayDeque.size(); n++) {
if (arrayDeque.Length() % 2 == 0) {
arrayDeque.addAll(evenlist);
} else {
arrayDeque.addAll(oddlist);
}
System.out.println(evenlist);
System.out.println(oddlist);
}
}
}
class Kodilla {
public static void main(String[] args) {
ArrayDeque<String> arrayDeque = new ArrayDeque<>();
Random random = new Random();
String text = "";
int howLong = random.nextInt(50) + 1;
while (text.length() < howLong) {
text = text + "a";
for (int i = 0; i < 50; i++) {
arrayDeque.add(text);
System.out.println(arrayDeque);
System.out.println(arrayDeque.size());
arrayTester tester = new ArrayTester();
tester.arrayTester(arrayDeque);
System.out.println(arrayTester);
}
}
}
}
what I see is that in this line
arrayTester tester = new ArrayTester();
there is typo in the variable definition. (lowercase a)

My Program stops printing to console, but continues to run in background. No Exception is thrown

My program Runs and prints the first few system.out statements, then stops printing them. There is no exception thrown, and the program continues to run until manually terminated.
I've tried System.out.flush(); but am not even sure where to put that
import java.io.*;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) throws
FileNotFoundException {
String inputFileStr = args[0];//"input.txt";
String outputFileStr = args[1];//"output.txt";
String deleteFileStr = args[2];//"CS401Project5Delete_Varner_Sav58.txt";//
String replaceFileStr = args[3]; //"CS401Project5Replace_VARNER_SAV58.txt";
// create files w/ corresponding file names
try{
File inputFile = new File(inputFileStr);
File outputFile = new File(outputFileStr);
File deleteFile = new File(deleteFileStr);
File replaceFile = new File(replaceFileStr);
// create arrayLists
ArrayList<StringBuilder> deleteArray;
ArrayList<StringBuilder> replaceArray;
ArrayList<StringBuilder> inputArray;
ArrayList<String> inputStringArray = new ArrayList<>();
ArrayList<String> tokensArray = new ArrayList<>();
ArrayList<Integer> frequenciesArray = new ArrayList<>();
// turn Files into arrayLists of StringBuilders
deleteArray = fileToArray(deleteFile);
replaceArray = fileToArray(replaceFile);
inputArray = fileToArray(inputFile);
System.out.println("# words in original file: " + wordCount(inputArray));
// create a deleteList object
DeleteList delete = new DeleteList();
delete.compareArray(inputArray, deleteArray);
System.out.println("Word Count After Deleteing noise: " + delete.wordCount(inputArray));
System.out.flush();
// create a replacelist object
ReplaceList replace = new ReplaceList();
replace.compareArray(inputArray, replaceArray);
System.out.println("Word count after replacing words: " + replace.wordCount(inputArray));
System.out.println("New input printed to 'output.txt'");
}
catch (FileNotFoundException e){
System.out.println("File not found");
}
}
// turns a file into an arraylist of string builders
public static ArrayList<StringBuilder> fileToArray(File fileName) throws FileNotFoundException {
ArrayList<String> array = new ArrayList<>();
ArrayList<StringBuilder> sbArray = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null)
{
if (!line.isEmpty()) {
Stream.of(line.split("\\s+")).forEachOrdered(word -> array.add(word));
}
}
} catch (Exception e) {
System.out.printf("Caught Exception: %s%n", e.getMessage());
e.printStackTrace();
}
for(int i = 0; i < array.size(); i++) {
StringBuilder sb = new StringBuilder();
sb.append(array.get(i));
sbArray.add(sb);
}
for(int i = 0; i < sbArray.size(); i ++) {
if
(sbArray.get(i).toString().endsWith(",") ||
sbArray.get(i).toString().endsWith(".") ||
sbArray.get(i).toString().endsWith(" ")
||sbArray.get(i).toString().endsWith(":")) {
sbArray.get(i).deleteCharAt(array.get(i).length() - 1);
}
}
return sbArray;
}
public static int wordCount(ArrayList<StringBuilder> array) {
int count = 0;
for (int i = 0; i < array.size(); i++) {
count++;
}
return count;
}
}
import java.util.ArrayList;
public class DeleteList extends ArrayList<Object> implements MyInterface {
/**
*
*/
private static final long serialVersionUID = 1L;
//constructor
#Override
public ArrayList<StringBuilder>
compareArray(ArrayList<StringBuilder> inputArray, ArrayList<StringBuilder> deleteArray) {
for (int i = 0; i < deleteArray.size(); i++) {
for (int j = 0; j < inputArray.size(); j++) {
if (deleteArray.get(i).toString().equals(inputArray.get(j).toString())){
inputArray.remove(j);
}
}
}
return inputArray;
}
#Override
public int wordCount(ArrayList<StringBuilder> inputArray) {
int count = 0;
for (int i = 0; i < inputArray.size(); i++) {
count++;
}
return count;
}
}
import java.util.ArrayList;
public class ReplaceList extends ArrayList<Object> implements MyInterface {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public ArrayList<StringBuilder>
compareArray(ArrayList<StringBuilder> inputArray, ArrayList<StringBuilder> replaceArray) {
String wordToReplace, wordReplacingWith = null;
for (int i = 0; i < replaceArray.size(); i++) {
wordToReplace = replaceArray.get(i).toString();
wordReplacingWith = replaceArray.get(i +1).toString();
for (int j = 0; j < inputArray.size(); j++) {
if (inputArray.get(j).toString().equalsIgnoreCase((wordToReplace))) {
StringBuilder strB = new StringBuilder();
strB.append(wordReplacingWith);
inputArray.set(j, strB);
}
}
}
return inputArray;
}
#Override
public int wordCount(ArrayList<StringBuilder> inputArray) {
int count = 0;
for (int i = 0; i < inputArray.size(); i++) {
count++;
}
return count;
}
}
It should be printing to the console:
words in the original file :
words after deleting noise:
words after replacing words:
New Input printed to "output.txt" <--- (i haven't coded this part yet)
Note:
I have to use string builders, implement an interface, and have the
delteList and replaceList extend ArrayList & handle all exceptions in
main
You're problem is this:
ReplaceList#compareArray
while (i < replaceArray.size()) {
wordReplacingWith = replaceArray.get(i + 1).toString();
}
You probably want to increment i at some point or more likely you need a different counter here.
And those System.exit() commands that prevent compilation ;)
The only thing I am seeing in the updated version is a potential ArrayIndexOutOfBoundsException for
for (int i = 0; i < replaceArray.size(); i++) {
...
wordReplacingWith = replaceArray.get(i +1).toString();
...
}
Unrelated to any endless loop problem you might still have:
DeleteList#compareArray is likely to skip elements after a remove operation,
as the new element on position j (the former j+1) element is not covered by your loop.

How to overcome this stack overflow issue when finding SCCs?

This is the code I wrote to find SCCs usigng Kosaraju's Two-Passed Algorithm. When I run the main method, I get a StackOverFlowError on SCC.revDFS. How can I avoid the stack overflow error when having a large amount of recursive calls?
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.Scanner;
public class SCC {
int n = 875714;
Map<Integer,List<Integer>> adjList;
Map<Integer,List<Integer>> adjListRev;
int[] ft;
int t;
int s;
boolean[] marked;
int[] leaders;
public SCC() {
init();
t = 0;
s = 0;
marked = new boolean[n + 1];
leaders = new int[n + 1];
}
void init() {
adjList = new HashMap<Integer,List<Integer>>();
adjListRev = new HashMap<Integer,List<Integer>>();
ft = new int[n + 1];
List<Integer> adj;
try {
Scanner scanner = new Scanner (new InputStreamReader(this.getClass().
getClassLoader().getResourceAsStream("SCC.txt")));
while(scanner.hasNextLine()) {
String s = scanner.nextLine().trim();
String[] num = s.split(" ");
if (!adjList.containsKey(Integer.parseInt(num[0]))) {
adjList.put(Integer.parseInt(num[0]), new ArrayList<Integer>());
}
adj = adjList.get(Integer.parseInt(num[0]));
adj.add(Integer.parseInt(num[1]));
adjList.put(Integer.parseInt(num[0]), adj);
if (!adjListRev.containsKey(Integer.parseInt(num[1]))) {
adjListRev.put(Integer.parseInt(num[1]), new ArrayList<Integer>());
}
adj = adjListRev.get(Integer.parseInt(num[1]));
adj.add(Integer.parseInt(num[0]));
adjListRev.put(Integer.parseInt(num[1]), adj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void DFS_Loop() {
for (int i = 1; i < n + 1; i++) {
marked[i] = false;
}
for (int i = n; i > 0; i--) {
if (!marked[i]) {
revDFS(i);
}
}
for (int i = 1; i < n + 1; i++) {
marked[i] = false;
leaders[i] = 0;
}
for (int i = n; i > 0; i--) {
if (!marked[ft[i]]) {
s = ft[i];
DFS(ft[i]);
}
}
}
public void revDFS(int i) {
marked[i] = true;
List<Integer> edges = adjListRev.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
revDFS(j);
}
}
}
t += 1;
ft[t] = i;
}
public void DFS(int i) {
marked[i] = true;
leaders[s] += 1;
List<Integer> edges = adjList.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
DFS(j);
}
}
}
}
public static void main(String[] args) {
SCC scc = new SCC();
scc.DFS_Loop();
Arrays.sort(scc.leaders);
for (int i = scc.n; i < scc.n - 5; i--) {
System.out.println(scc.leaders[i]);
}
}
}
Maybe you can try to convert the logic to iterative approach. Also, do check if you have base and edge cases handled properly.
The basic idea for converting a recursive function into an iterative function is that a recursive function consumes arguments from a stack.
So you can create a stack and push the values into it and then consume them in a loop.
public void _revDFS(int _i) {
LinkedList<Integer> stack = new LinkedList<>();
stack.push(_i);
while(!stack.isEmpty()){
int i = stack.pop();
marked[i] = true;
List<Integer> edges = adjListRev.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
stack.push(j);
//revDFS(j);
}
}
}
t += 1;
ft[t] = i;
}
}
I can't really test it to see if I made a mistake of some kind and revDFS is a function with a lot of side effect and it does not return a value, so is a bit difficult to reason with it.
But the gist is that instead of calling the function itself you can just push the edge indexes onto the stack and then consume them.
The child edges will be processed in reverse order so if you want to keep the same order of processing of the original you should read the edges in reverse order :
ListIterator<Integer> li = edges.listIterator(edges.size());
while(li.hasPrevious()){
int j = li.previous();
if (!marked[j]) {
stack.push(j);
//revDFS(j);
}
}
you have implemented your Dfs function recursively which causes "stack overflow". To overcome this issue you need to implement it using stack data structure.
see link bellow for more motivations
https://github.com/sinamalakouti/MyFavoriteAlgorithmProblems

Getting WA(Wrong asnwer) for http://www.spoj.com/problems/IITWPC4I/

I have used disjoint set concept to solve this problem. Starting with all milkmen as visited, whenever a new person can be reached with new branch, he is marked as visited. I have already tested following edge cases:
There is no milkmen in the city
Everyone is milkman
Some milkman is not connected to anyone
Some person is not connected to anyone
Multiple paths between 2 people
Milkmen and people are forming disjoint set
Still i am getting WA. Any idea about missing case?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
* Created by VIVEK VERMA on 9/25/2016.
*/
public class SpojIITWPC4I {
public static void main(String[] arge) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(reader.readLine());
for (int t = 0; t < T; t++) {
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
int n = Integer.parseInt(tokenizer.nextToken());
int m = Integer.parseInt(tokenizer.nextToken());
int totalIncludedNodes = 0;
ManNode[] people = new ManNode[n];
Queue<ManLink> links = new PriorityQueue<>();
tokenizer = new StringTokenizer(reader.readLine());
for(int i=0;i<n;i++){
int val=Integer.parseInt(tokenizer.nextToken());
people[i] = new ManNode(i);
if(val==1){
people[i].isIncluded = true;
totalIncludedNodes++;
}
}
for(int i = 0; i<m;i++){
tokenizer = new StringTokenizer(reader.readLine());
int start = Integer.parseInt(tokenizer.nextToken()) -1;
int destination = Integer.parseInt(tokenizer.nextToken()) -1;
int value = Integer.parseInt(tokenizer.nextToken());
ManLink link = new ManLink(people[start], people[destination], value);
people[start].AddChild(link);
people[destination].AddChild(link);
if(people[start].isIncluded ^ people[destination].isIncluded){
links.add(link);
}
}
int minCost = 0;
while(!links.isEmpty() && totalIncludedNodes <n){
ManLink link = links.poll();
ManNode nextAddedNode = (link.source.isIncluded==true?link.destinationNode:link.source);
if(nextAddedNode.isIncluded){
continue;
}
minCost += link.value;
nextAddedNode.isIncluded = true;
totalIncludedNodes++;
for(int i=0;i<nextAddedNode.children.size();i++){
if((nextAddedNode.isIncluded ^ nextAddedNode.children.get(i).source.isIncluded)
|| (nextAddedNode.isIncluded ^ nextAddedNode.children.get(i).destinationNode.isIncluded)){
links.add(nextAddedNode.children.get(i));
}
}
}
if(totalIncludedNodes == n){
System.out.println(minCost);
}else{
System.out.println("impossible");
}
}
}
}
class ManNode{
boolean isIncluded = false;
List<ManLink> children = new ArrayList<>();
int index;
ManNode(int index){
this.index = index;
}
void AddChild(ManLink link){
children.add(link);
}
}
class ManLink implements Comparable{
ManNode destinationNode, source;
int value;
ManLink(ManNode source, ManNode node, int value){
this.source = source;
this.destinationNode = node;
this.value = value;
}
#Override
public int compareTo(Object o) {
return this.value - ((ManLink)o).value;
}
}

Why isn't the bubbleDown method working as intended (Heap Sort)?

This was an assignment that was due, and I attempted it in both C++ and Java, but in both versions, the bubbleDown method wasn't working as intended, though I believe the logic says it should. I've already handed in both versions, but since the Java version is the most recent, I'll post it here.
Here's the Java version:
import java.io.*;
import java.util.Scanner;
public class HeapSort {
static int[] heap;
Integer[] sorted;
String in, out;
int fullLength = 0;
public HeapSort(String inf, String outf) throws FileNotFoundException {
in = inf;
out = outf;
Scanner scan = new Scanner(new File(in));
while (scan.hasNextInt()) {
fullLength++;
scan.nextInt();
}
sorted = new Integer[fullLength];
heap = new int[fullLength+1];
heap[0] = 0;
scan.close();
}
public boolean isFull() {
return heap[0] == fullLength;
}
public boolean isEmpty() {
return heap[0] == 0;
}
public void buildHeap() throws IOException {
Scanner scan = new Scanner(new File(in));
while (scan.hasNextInt())
insertOneDataItem(scan.nextInt());
scan.close();
}
public void deleteHeap() throws IOException {
while (!isEmpty()) {
deleteRoot();
printHeap();
}
}
public void deleteRoot() throws IOException {
if (isEmpty())
return;
FileWriter f = new FileWriter(out, true);
f.write("Deleting " + heap[1] + "\n");
f.close();
int i;
for(i = 0; sorted[i] != null; i++);
sorted[i] = heap[1];
heap[1] = heap[heap[0]--];
bubbleDown();
}
public void insertOneDataItem(int num) throws IOException {
if (isFull()) {
p("Heap is full");
return;
}
heap[++heap[0]] = num;
bubbleUp();
printHeap();
}
public void printHeap() throws IOException {
FileWriter f = new FileWriter(out, true);
f.write("Current Heap:\t");
for (int i = 1; i <= heap[0]; i++) {
if (i > 10) break;
f.write(heap[i] + " ");
}
f.write("\n");
f.close();
}
public void printSorted() throws IOException {
FileWriter f = new FileWriter(out, true);
f.write("Current Sorted:\t");
for (int i = 1; i <= sorted.length; i++) {
if (i > 10) break;
f.write(sorted[i] + " ");
}
f.write("\n");
f.close();
}
public void bubbleUp() {
int h = heap[0];
while (h >= 2 && heap[h] < heap[h/2]) {
int x = heap[h];
heap[h] = heap[h/2];
heap[h/2] = x;
h = h/2;
}
}
public void bubbleDown() {
int k = 1;
// make sure we have at least a left child
// before continuing on
while (2*k <= heap.length) {
int left = 2*k;
int right = 2*k+1;
if (heap[k] >= heap[left]) {
int x = heap[k];
heap[k] = heap[left];
heap[left] = x;
k = left;
continue;
}
if (right <= heap.length &&
heap[k] >= heap[right]) {
int x = heap[k];
heap[k] = heap[right];
heap[right] = x;
k = right;
} else {
return;
}
}
}
public void begin() throws IOException {
buildHeap();
deleteHeap();
printSorted();
}
public static void main(String[] args) throws IOException {
if (args.length < 2) {
p("Please start with: program file1.txt file2.txt");
System.exit(1);
}
// empty the output file
(new FileOutputStream(args[1])).close();
(new HeapSort(args[0], args[1])).begin();
}
public static void p(String s) {
System.out.println(s);
}
}
The input file (args[0]) with have only integers in the file, with some on the same row, and on different lines. args[1] is the output file name.
When the program goes through bubbleDown, it starts to work as intended in the beginning, but then it skips some numbers, and towards the end I'll eventually see a number that should have been at the top. Can someone explain to me what I did wrong in this function?
Your code looks suspicious for a number of reasons. 1 -- you are mixing the actual data structure implementation with reading a file which makes no sense. Very hard to follow. Then this piece can't be right:
sorted[i] = heap[1];
heap[1] = heap[heap[0]--];
First line suggests that heap array contains actual data elements.
But second line is treating heap contents as indexes of some sort? heap[0]-- will decrement the value stored at location 0 of the heap array, but first it will use it to move the contents of heap[heap[0]] to heap[1]? What? Are you using heap[0] as a special thing to store the index of the last element in the array? I suggest you start by rewriting code w/o hacks like this, it should make it easier to understand and fix. In reality your heap should start at element 0 and your left node will be at 2k+1 and right will be at 2k+2.
Now this smells like it is wrong:
right <= heap.length
you should be comparing right to that terrible heap[0], because heap.length will not be shrinking when you remove things from it.
for (int i = 1; i <= sorted.length; i++) {
should be
for (int i = 0; i < sorted.length; i++) {
and the final main mistake is in the bubbleDown method. When bubbling down you need to be swapping the downward shifting node with the smaller of its children. So that is 7 is bubbling down and its left child is 6 and right child is 4, you need to swap 7 and 4, otherwise you get invalid tree of
6
/ \
7 4
So code should be
if (heap[k] >= heap[left] && heap[left] < heap[right]) {
You are welcome. And your professor owes me lunch for doing his job for him.

Categories

Resources