Tracking while reading a text file in Java - java

I'm trying to build a program with BufferedReader that reads a file and keeps track of vowels, words, and can calculate avg # of words per line. I have the skeleton in place to read the file, but I really don't know where to take it from here. Any help would be appreciated. Thanks.
import java.io.*;
public class JavaReader
{
public static void main(String[] args) throws IOException
{
String line;
BufferedReader in;
in = new BufferedReader(new FileReader("message.txt"));
line = in.readLine();
while(line != null)
{
System.out.println(line);
line = in.readLine();
}
}
}

Here's what I got. The word counting is questionable, but works for an example that I will give. Changes can be made (I accept criticism).
import java.io.*;
public class JavaReader
{
public static void main(String[] args) throws IOException
{
BufferedReader in = new BufferedReader(new FileReader("message.txt"));
String line = in.readLine();
// for keeping track of the file content
StringBuffer fileText = new StringBuffer();
while(line != null) {
fileText.append(line + "\n");
line = in.readLine();
}
// put file content to a string, display it for a test
String fileContent = fileText.toString();
System.out.println(fileContent + "--------------------------------");
int vowelCount = 0, lineCount = 0;
// for every char in the file
for (char ch : fileContent.toCharArray())
{
// if this char is a vowel
if ("aeiou".indexOf(ch) > -1) {
vowelCount++;
}
// if this char is a new line
if (ch == '\n') {
lineCount++;
}
}
double wordCount = checkWordCount(fileContent);
double avgWordCountPerLine = wordCount / lineCount;
System.out.println("Vowel count: " + vowelCount);
System.out.println("Line count: " + lineCount);
System.out.println("Word count: " + wordCount);
System.out.print("Average word count per line: "+avgWordCountPerLine);
}
public static int checkWordCount(String fileContent) {
// split words by puncutation and whitespace
String words[] = fileContent.split("[\\n .,;:&?]"); // array of words
String punctutations = ".,:;";
boolean isPunctuation = false;
int wordCount = 0;
// for every word in the word array
for (String word : words) {
// only check if it's a word if the word isn't whitespace
if (!word.trim().isEmpty()) {
// for every punctuation
for (char punctuation : punctutations.toCharArray()) {
// if the trimmed word is just a punctuation
if (word.trim().equals(String.valueOf(punctuation)))
{
isPunctuation = true;
}
}
// only add one to wordCount if the word wasn't punctuation
if (!isPunctuation) {
wordCount++;
}
}
}
return wordCount;
}
}
Sample input/output:
File:
This is a test. How do you do?
This is still a test.Let's go,,count.
Output:
This is a test. How do you do?
This is still a test.Let's go,,count.
--------------------------------
Vowel count: 18
Line count: 4
Word count: 16
Average word count per line: 4.0

You can use a Scanner to pass over the the line and retrieve every token of the string line.
line = line.replaceAll("[^a-zA-Z]", ""); //remove all punctuation
line = line.toLowerCase(); //make line lower case
Scanner scan = new Scanner(line);
String word = scan.next();
Then you could loop through each token to calculate the vowels in each word.
for(int i = 0; i < word.legnth(); i++){
//get char
char c = word.charAt(i);
//check if the char is a vowel here
if("aeiou".indexOf(c) > -1){
//c is vowel
}
}
All you need to do is set a couple of counter ints to keep track of these and you're laughing.
Ahh, if you want to make sure that there are no non-words such as " - " counting as a word, the easiest way would probably be to strip all non-alphanumeric characters out of the text.
I also added it above.
line = line.replaceAll("[^a-zA-Z]", "");
line = line.toLowerCase();
Oh and since you are new to java don't forget to import
import java.util.Scanner;

Related

ROT13 in Java doesn´t want to work properly

At some point I have trouble programming ROT13 in Java. So the User shall write whatever he wants and the programm should rewrite it in ROT13. So here´s my programm until now:
import java.io.*;
public class rot13
{
public static void main (String [] args) throws IOException
{
BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));// Buffered Reader reads the number inputed
String key [] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
String keyA [] = {"N","O","P","Q","R","S","T","U","V","W","X","Y","Z","A","B","C","D","E","F","G","H","I","J","K","L","M"};
String letter;
System.out.println("Enter a phrase:");
String phrase = myInput.readLine();
int y = 0, i = 0;
while ( y <= phrase.length()){
letter = Character.toString(phrase.charAt(y));
while(i <= y){
if (letter != key[i]){
keyA [i] = keyA[i];
}
i++;
}
System.out.println(keyA [i]);
y++;
}
}
}
The problem is the following:
It only does go for a few letters, but stops working after like 3 lines or rather after 3 latters and puts up errors which are:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(Unknown Source)
at rot13.main(rot13.java:19)
I´ve tried different words, but it keeps printing out the same problem. Does anyone knows how to fix it or at least a way to do it more proberly?
Thanks in advance!!
Why it doesn't work
import java.io.*;
public class rot13
{
public static void main (String [] args) throws IOException
{
BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));// Buffered Reader reads the number inputed
String key [] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
String keyA [] = {"N","O","P","Q","R","S","T","U","V","W","X","Y","Z","A","B","C","D","E","F","G","H","I","J","K","L","M"};
String letter;
System.out.println("Enter a phrase:");
String phrase = myInput.readLine();
int y = 0, i = 0;
while ( y <= phrase.length()){
letter = Character.toString(phrase.charAt(y));
//Each time you go throught the first loop, you are comparing your actual position in the string and i
//But as you don't reset i back to 0, you only try to compare your previous index and your actual index : if y == 3, so i takes only the values 2 and 3
//Moreover, when y > 26, you try to access the key array outside of its bounds
while(i <= y){
// letter is a string so you should be using equals
if (letter != key[i]){
// You are putting the value at the i index in the i index, so you do basically nothing with this line
keyA [i] = keyA[i];
}
i++;
}
System.out.println(keyA [i]);
y++;
}
}
}
Alternative
Here's a solution you can use :
import java.io.*;
public class rot13 {
public static void main(String[] args) throws IOException {
BufferedReader myInput = new BufferedReader(new InputStreamReader(System.in));// Buffered Reader reads the number inputed
System.out.println("Enter a phrase:");
String input = myInput.readLine();
//We loop through every char in the string
for (char c : input.toCharArray()) {
//We check if the character is a letter, so we don't add the offset to special characters like space or dot
if (Character.isAlphabetic(c)) {
//Here we get the lower case version of the char and remove it 97, which is the ascii value of 'a'
//With this, we are mapping letters from a to z to numbers from 0 to 25
char lowerChar = (char) (Character.toLowerCase(c) - 97);
//We add the offset of 13
lowerChar += 13;
//We then use the modulo to move numbers higher than 15 back to the beginning
lowerChar %= 26;
//We finally come back to the ascii value of our lower case char
lowerChar += 97;
System.out.print(Character.isUpperCase(c) ? Character.toUpperCase(lowerChar) : lowerChar);
} else {
//If it's not a letter, we just print the char
System.out.print(c);
}
}
//We don't forget to close our BuffererReader
myInput.close();
}
}
This is a described version but you can shorten it by doing all the char operations on one line

Find word using Java

I am trying to write a Java class to find word surrounded by ( ) in text file and output the word and its occurrences in different line.
How can I write this in Java?
Input file
School (AAA) to (AAA) 10/22/2011 ssss(ffs)
(ffs) 7368 House 8/22/2011(h76yu) come 789 (AAA)
Car (h76yu) to (h76yu) extract9998790
2/3/2015 (AAA)
Output file
(AAA) 4
(ffs) 2
(h76yu) 3
This is what I got so far..
public class FindTextOccurances {
public static void main(String[] args) throws IOException {
int sum=0
String line = value.toString();
for (String word : line.split("(\\W+")) {
if (word.charAt(0) == '(‘ ) {
if (word.length() > 0) {
sum +=line.get();
}
context.write(new Text(word), new IntWritable(sum));
}
}
}
You can find the text between brackets without splitting or using regular expressions like so (assuming that all brackets are closed, and you don't have nested brackets):
int lastBracket = -1;
while (true) {
int start = line.indexOf('(', lastBracket + 1);
if (start == -1) {
break;
}
int end = line.indexOf(')', start + 1);
System.out.println(line.substring(start + 1, end - 1);
lastBracket = start;
}
If you split on "(\W+)" you are going to keep ALL the things that ARE NOT between parenthesis (as you are splitting on the parenthesized words).
What you want is a matcher:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
...
Map<String, Int> occurrences = new HashMap<>();
Matcher m = Pattern.compile("(\\W+)").matcher(myString);
while (m.find()) {
String matched = m.group();
String word =matched.substring(1, matched.length()-1); //remove parenthesis
occurrences.put(word, occurences.getOrDefault(word, 0)+1);
}
This may help i did it with regular expressions i did not declared variables adjust them as to your needs.I wish this may solve your problem
BufferedReader fr = new BufferedReader(new InputStreamReader(new FileInputStream(file), "ASCII"));
while(true)
{
String line = fr.readLine();
if(line==null)
break;
String[] words = line.split(" ");//those are your words
}
for(int i = 0;i<=words.length();i++)
{
String a = words[i];
if(a.matches("[(a-z)]+"))
{
j=i;
while(j<=words.length();)
{
count++;
}
System.out.println(a+" "+count);
}
}

Need help figuring out how to capitalize any lower case "i" read from a text file

Intro to CS student here.
I've been struggling to find a solution after spending a lot of time reading my text book and reviewing my professors slides.
Basically my program needs to read from an input file and make corrections, one of the corrections must be capitalizing all individual lowercase "i"s and outputting the corrected file.
I have the input/output part taken care of but now I'm just plain stuck.
import java.io.*;
import java.util.*;
public class WP {
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(new File(args[0])); // first argument is input filename
PrintStream output = new PrintStream(new File(args[1])); // second arg is output filename
stripSpaces(input, output);
capCorrection(input, output);
}
static void stripSpaces(Scanner input, PrintStream output) {
String text = "";
while (input.hasNextLine()) {
text += input.nextLine() + "\n";
}
final int State_INIT = 0;
final int State_SEEN_SPACE = 1;
int state = State_INIT;
for (char c : text.toCharArray()) {
if (state == State_INIT) {
if (c == ' ') {
output.print(c);
state = State_SEEN_SPACE;
} else {
output.print(c);
}
} else if (state == State_SEEN_SPACE) {
if (c != ' ') {
output.print(c);
state = State_INIT;
}
}
}
}
static void capCorrection(input, output);
String text = "";
while (input.hasNextLine()) {
text += input.nextLine() + "\n";
}
final int State_INIT = 0;
final int State_SEEN_I = 1;
int state = State_INIT;
Start off with asking yourself with what you are trying to do and how you can do it. Like you will need to locate the charachter "i" between two spaces so you can say: IF there is a " " befor "i" AND a " " after then character the capitalize.
You should replace the character before writing it. So What I would do is read each line in the file, check for "i" between two spaces, capitalize it, and then write over the line with the corrected line

Counting the letters (uppercase and lowercase) of a string

I have here a program that enters a paragraph and writes it into a file. After that, it should count the occurrences of each letters (case sensitive). However, it doesn't count the number of letter occurrences. I think I put the for loop in the wrong place.
import java.io.*;
import java.util.*;
public class Exercise1 {
public static int countLetters (String line, char alphabet) {
int count = 0;
for (int i = 0; i <= line.length()-1; i++) {
if (line.charAt(i) == alphabet)
count++;
}
return count;
}
public static void main(String[] args) throws IOException {
BufferedReader buffer = new BufferedReader (new InputStreamReader(System.in));
PrintWriter outputStream = null;
Scanner input = new Scanner (System.in);
int total;
try {
outputStream = new PrintWriter (new FileOutputStream ("par.txt"));
System.out.println("How many lines are there in the paragraph you'll enter?");
int lines = input.nextInt();
System.out.println("Enter the paragraph: ");
String paragraph = buffer.readLine();
outputStream.println(paragraph);
int j;
for (j = 1; j<lines; j++) {
paragraph = buffer.readLine();
outputStream.println(paragraph);
}
outputStream.close();
System.out.println("The paragraph is written to par.txt");
for (int k=1; k<lines; k++) {
paragraph = buffer.readLine();
total = countLetters (paragraph, 'A');
if (total != 0)
System.out.println("A: "+total);
//I'll do bruteforce here up to lowercase z
}
}
catch(FileNotFoundException e) {
System.out.println("Error opening the file par.txt");
}
}
}
Please help me fix the code. I'm new in programming and I need help. Thank you very much!
First, your initial reading user input is a bit of a waste since you read once then enter the for loop for the rest - this is not a problem, just a better code.
// your code
String paragraph = buffer.readLine();
outputStream.println(paragraph);
int j;
for (j = 1; j<lines; j++) {
paragraph = buffer.readLine();
outputStream.println(paragraph);
}
You can just put them in the loop:
// better code
String paragraph;
int j;
for (j = 0; j<lines; j++) {
paragraph = buffer.readLine();
outputStream.println(paragraph);
}
Then your first problem comes from the way you read the lines:
// your code - not working
outputStream.close();
for (int k=1; k<lines; k++) {
paragraph = buffer.readLine();
total = countLetters (paragraph, 'A');
Consider what happened above:
The input is already DONE, the output is already written and stream is closed - up to here everything is good
Then when you try to count the number of characters, you do: paragraph = buffer.readLine(); - what does this code do? It waits for another user input (instead of reading what's been inserted)
To fix the problem above: you need to read from what's already been written - not asking for another input. Then instead of brute forcing every character one by one, you can just put them into a list and write a for loop.
So now, you want to read from the existing file that you already created (ie. reading what WAS inputted by the user):
BufferedReader fileReader = new BufferedReader(new FileReader(new File("par.txt")));
String allCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String aLineInFile;
// Read the file that was written earlier (whose content comes from user input)
// This while loop will go through line-by-line in the file
while((aLineInFile = fileReader.readLine()) != null)
{
// For every line in the file, count number of occurrences of characters
// This loop goes through every character (a-z and A-Z)
for(int i = 0; i < allCharacters.length(); i++)
{
// For each single character, check the number of occurrences in the current line
String charToLookAt = String.valueOf(allCharacters.charAt(i));
int numOfCharOccurancesInLine = countLetters (aLineInFile, charToLookAt);
System.out.println("For line: " + aLineInFile + ", Character: " + charToLookAt + " appears: " + numOfCharOccurancesInLine + " times " );
}
}
The above gives you the number of occurrences of every character in every line - now you just need to organize them to keep track of how many are in total for the whole file.
Code-wise, there might be better way to write this to have cleaner implementation, but the above is easy to understand (and I just wrote it very quickly).
Do everything in one loop:
for (j = 1; j<lines; j++) {
paragraph = buffer.readLine();
total = countLetters (paragraph, 'A');
if (total != 0)
System.out.println("A: "+total);
outputStream.println(paragraph);
}
You can use a HashTable for count each case sentitive letters :
final Pattern patt = Pattern.compile("A-Za-z]");
final HashMap<Character, Integer> tabChar = new HashMap<Character, Integer>(
52);
// replace : paragraph = buffer.readLine();
// Unless you use it outside, you can declare it 'final'
final char[] paragraph = "azera :;,\nApOUIQSaOOOF".toCharArray();
for (final Character c : paragraph ) {
if (Character.isLetter(c)) {
Integer tot = tabChar.get(c);
tabChar.put(c, (null == tot) ? 1 : ++tot);
}
}
Output :
{F=1, A=1, O=4, I=1, U=1, Q=1, S=1, e=1, a=3, r=1, p=1, z=1}
You can use final TreeSet<Character> ts = new TreeSet(tabChar.keySet()); to sort the characters and then get(c); them from tabChar
The previous answers would have solved your problem but another way of avoiding brute force might be to use a loop using ASCII character value.

Reversing characters in each word in a sentence - Stack Implementation

This code is inside the main function:
Scanner input = new Scanner(System.in);
System.out.println("Type a sentence");
String sentence = input.next();
Stack<Character> stk = new Stack<Character>();
int i = 0;
while (i < sentence.length())
{
while (sentence.charAt(i) != ' ' && i < sentence.length() - 1)
{
stk.push(sentence.charAt(i));
i++;
}
stk.empty();
i++;
}
And this is the empty() function:
public void empty()
{
while (this.first != null)
System.out.print(this.pop());
}
It doesn't work properly, as by typing example sentence I am getting this output: lpmaxe. The first letter is missing and the loop stops instead of counting past the space to the next part of the sentence.
I am trying to achieve this:
This is a sentence ---> sihT si a ecnetnes
Per modifications to the original post, where the OP is now indicating that his goal is to reverse the letter order of the words within a sentence, but to leave the words in their initial positions.
The simplest way to do this, I think, is to make use of the String split function, iterate through the words, and reverse their orders.
String[] words = sentence.split(" "); // splits on the space between words
for (int i = 0; i < words.length; i++) {
String word = words[i];
System.out.print(reverseWord(word));
if (i < words.length-1) {
System.out.print(" "); // space after all words but the last
}
}
Where the method reverseWord is defined as:
public String reverseWord(String word) {
for( int i = 0; i < word.length(); i++) {
stk.push(word.charAt(i));
}
return stk.empty();
}
And where the empty method has been changed to:
public String empty() {
String stackWord = "";
while (this.first != null)
stackWord += this.pop();
return stackWord;
}
Original response
The original question indicated that the OP wanted to completely reverse the sentence.
You've got a double-looping construct where you don't really need it.
Consider this logic:
Read each character from the input string and push that character to the stack
When the input string is empty, pop each character from the stack and print it to screen.
So:
for( int i = 0; i < sentence.length(); i++) {
stk.push(sentence.charAt(i));
}
stk.empty();
I assume that what you want your code to do is to reverse each word in turn, not the entire string. So, given the input example sentence you want it to output elpmaxe ecnetnes not ecnetnes elpmaxe.
The reason that you see lpmaxe instead of elpmaxe is because your inner while-loop doesn't process the last character of the string since you have i < sentence.length() - 1 instead of i < sentence.length(). The reason that you only see a single word is because your sentence variable consists only of the first token of the input. This is what the method Scanner.next() does; it reads the next (by default) space-delimited token.
If you want to input a whole sentence, wrap up System.in as follows:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
and call reader.readLine().
Hope this helps.
Assuming you've already got your input in sentence and the Stack object is called stk, here's an idea:
char[] tokens = sentence.toCharArray();
for (char c : tokens) {
if (c == ' ') {
stk.empty();
System.out.print(c);
} else {
stk.add(c);
}
}
Thus, it will scan through one character at a time. If we hit a space character, we'll assume we've hit the end of a word, spit out that word in reverse, print that space character, then continue. Otherwise, we'll add the character to the stack and continue building the current word. (If you want to also allow punctuation like periods, commas, and the like, change if (c == ' ') { to something like if (c == ' ' || c == '.' || c == ',') { and so on.)
As for why you're only getting one word, darrenp already pointed it out. (Personally, I'd use a Scanner instead of a BufferedReader unless speed is an issue, but that's just my opinion.)
import java.util.StringTokenizer;
public class stringWork {
public static void main(String[] args) {
String s1 = "Hello World";
s1 = reverseSentence(s1);
System.out.println(s1);
s1 = reverseWord(s1);
System.out.println(s1);
}
private static String reverseSentence(String s1){
String s2 = "";
for(int i=s1.length()-1;i>=0;i--){
s2 += s1.charAt(i);
}
return s2;
}
private static String reverseWord(String s1){
String s2 = "";
StringTokenizer st = new StringTokenizer(s1);
while (st.hasMoreTokens()) {
s2 += reverseSentence(st.nextToken());
s2 += " ";
}
return s2;
}
}
public class ReverseofeachWordinaSentance {
/**
* #param args
*/
public static void main(String[] args) {
String source = "Welcome to the word reversing program";
for (String str : source.split(" ")) {
System.out.print(new StringBuilder(str).reverse().toString());
System.out.print(" ");
}
System.out.println("");
System.out.println("------------------------------------ ");
String original = "Welcome to the word reversing program";
wordReverse(original);
System.out.println("Orginal Sentence :::: "+original);
System.out.println("Reverse Sentence :::: "+wordReverse(original));
}
public static String wordReverse(String original){
StringTokenizer string = new StringTokenizer(original);
Stack<Character> charStack = new Stack<Character>();
while (string.hasMoreTokens()){
String temp = string.nextToken();
for (int i = 0; i < temp.length(); i ++){
charStack.push(temp.charAt(i));
}
charStack.push(' ');
}
StringBuilder result = new StringBuilder();
while(!charStack.empty()){
result.append(charStack.pop());
}
return result.toString();
}
}
public class reverseStr {
public static void main(String[] args) {
String testsa[] = { "", " ", " ", "a ", " a", " aa bd cs " };
for (String tests : testsa) {
System.out.println(tests + "|" + reverseWords2(tests) + "|");
}
}
public static String reverseWords2(String s) {
String[] sa;
String out = "";
sa = s.split(" ");
for (int i = 0; i < sa.length; i++) {
String word = sa[sa.length - 1 - i];
// exclude "" in splited array
if (!word.equals("")) {
//add space between two words
out += word + " ";
}
}
//exclude the last space and return when string is void
int n = out.length();
if (n > 0) {
return out.substring(0, out.length() - 1);
} else {
return "";
}
}
}
This can pass in leetcode

Categories

Resources