I need to write for loop to iterate through a String object (nested within a String[] array) to operate on each character within this string with the following criteria.
first, add a hyphen to the string
if the character is not a vowel, add this character to the end of the string, and then remove it from the beginning of the string.
if the character is a vowel, then add "v" to the end of the string.
Every time I have attempted this with various loops and various strategies/implementations, I have somehow ended up with the StringIndexOutOfBoundsException error.
Any ideas?
Update: Here is all of the code. I did not need help with the rest of the program, simply this part. However, I understand that you have to see the system at work.
import java.util.Scanner;
import java.io.IOException;
import java.io.File;
public class plT
{
public static void main(String[] args) throws IOException
{
String file = "";
String line = "";
String[] tempString;
String transWord = ""; // final String for output
int wordTranslatedCount = 0;
int sentenceTranslatedCount = 0;
Scanner stdin = new Scanner(System.in);
System.out.println("Welcome to the Pig-Latin translator!");
System.out.println("Please enter the file name with the sentences you wish to translate");
file = stdin.nextLine();
Scanner fileScanner = new Scanner(new File(file));
fileScanner.nextLine();
while (fileScanner.hasNextLine())
{
line = fileScanner.nextLine();
tempString = line.split(" ");
for (String words : tempString)
{
if(isVowel(words.charAt(0)) || Character.isDigit(words.charAt(0)))
{
transWord += words + "-way ";
transWord.trim();
wordTranslatedCount++;
}
else
{
transWord += "-";
// for(int i = 0; i < words.length(); i++)
transWord += words.substring(1, words.length()) + "-" + words.charAt(0) + "ay ";
transWord.trim();
wordTranslatedCount++;
}
}
System.out.println("\'" + line + "\' in Pig-Latin is");
System.out.println("\t" + transWord);
transWord = "";
System.out.println();
sentenceTranslatedCount++;
}
System.out.println("Total number of sentences translated: " + sentenceTranslatedCount);
System.out.println("Total number of words translated: " + wordTranslatedCount);
fileScanner.close();
stdin.close();
}
public static boolean isVowel (char c)
{
return "AEIOUYaeiouy".indexOf(c) != -1;
}
}
Also, here is the example file from which text is being pulled (we are skipping the first line):
2
How are you today
This example has numbers 1234
Assuming that the issue is StringIndexOutOfBoundsException, then the only way this is going to occur, is when one of the words is an empty String. Knowing this also provides the solution: do something different (if \ else) when words is of length zero to handle the special case differently. This is one way to do this:
if (!"".equals(words)) {
// your logic goes here
}
another way, is to simply do this inside the loop (when you have a loop):
if ("".equals(words)) continue;
// Then rest of your logic goes here
If that is not the case or the issue, then the clue is in the parts of the code you are not showing us (you didn't give us the relevant code after all in that case). Better provide a complete subset of the code that can be used to replicate the problem (testcase), and the complete exception (so we don't even have to try it out ourselves.
Related
I have an assignment due two days and I have been trying a lot of days to do this, but I am burned, tried to come back to it, still no progress.
THE ASSIGNMENT is the following:
Java program that computes the above statistics from
any text file. Here’s what it might look like in action:
Name of the input file: example.txt
The proportion of 1-letter words: 3.91% (74 words)
The proportion of 2-letter words: 18.52% (349 words)
The proportion of 3-letter words: 24.24% (456 words)
The proportion of 4-letter words: 19.80% (374 words)
The proportion of 5-letter words: 11.33% (212 words)
…
…
The proportion of 12-letter words: 0.45% (8 words)
Proportion of 13- (or more) letter words: 0.51% (9 words)
Now In order to do this, I thought to divide my program into three methods: Read the method, count the letters and distinguish them and finally display it as the example above. Now that I said that, here is my code right now:
/*like make smaller functions
where each function has one task
like to loop through the file and return an array of words
then use that as input to another function whose purpose is to count the
letters
and then pass that array into a function for printing that.
*/
import java.io.*;
import java.util.Scanner;
class Autorship {
public static void main(String[] args) {
try {
System.out.println("Name of input file: ");
Scanner sc1 = new Scanner(System. in );
sc1.useDelimiter("[^a-zA-Z]");
String fname = sc1.nextLine();
sc1.close();
sc1 = new Scanner(new FileReader(fname));
sc1.useDelimiter("[^a-zA-Z]");
String line;
System.out.println(WordCount(fname, sc1));
} catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
public static int WordCount(String fname, Scanner sc1) {
int wordCount = 0;
int lineCount = 0;
while (sc1.hasNextLine()) {
String line;
line = sc1.nextLine();
lineCount++;
String[] strings = line.split(" ");
int[] counts = new int[14];
for (String str: strings)
if (str.length() < counts.length) counts[str.length()] += 1;
System.out.println("This is counts length: " + counts.length);
for (int i = 1; i < counts.length; i++)
System.out.println(i + " letter words: " + counts[i]);
}
return 0;
}
}
Now please I do not want the answer, as that would be plagiarism, and I am not that kind of person, I just want a bit of help to continue to progress, I'm so stuck right now, thanks ^^
Here is an adjusted and working version. I commented the lines I edited.
Your code wasn't that bad and it was working quite well. The only problem you had was that you've printed out the letter counts inside the while-loop instead of doing it outside. Therefore it repeated with every new line that was read from the file.
Please note: I strongly recommend to always use curly brackets even though Java syntax allows to not use them with if-statements and for-loops if they're followed by only one line of code to execute. But not using them makes the code harder to read and error prone.
public static void main(String[] args) {
try {
System.out.println("Name of input file: ");
Scanner sc1 = new Scanner(System. in );
sc1.useDelimiter("[^a-zA-Z]");
String fname = sc1.nextLine();
sc1.close();
sc1 = new Scanner(new FileReader(fname));
sc1.useDelimiter("[^a-zA-Z]");
String line;
System.out.println("WordCount: " + WordCount(fname, sc1)); // edited
} catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
public static int WordCount(String fname, Scanner sc1) {
int wordCount = 0;
int lineCount = 0;
final int MAXIMUM_LENGTH = 14; // edited. Better use a constant here.
int[] counts = new int[MAXIMUM_LENGTH]; // edited. Constant applied
while (sc1.hasNextLine()) {
String line = sc1.nextLine();
// increment line count
lineCount++;
String[] strings = line.split(" ");
// increment word count
wordCount += strings.length; // added
// edited. curly brackets and constant MAXIMUM_LENGTH
for (String str: strings) {
if (str.length() < MAXIMUM_LENGTH) {
counts[str.length()] += 1;
}
}
}
// edited / added. finally show the results
System.out.println("maximum length: " + MAXIMUM_LENGTH);
System.out.println("line count: " + lineCount);
System.out.println("word count: " + wordCount);
// edited. moved out of the while-loop. MAXIMUM_LENGTH applied.
for (int i = 1; i < MAXIMUM_LENGTH; i++) {
System.out.println(i + " letter words: " + counts[i]);
}
// edited.
return wordCount;
}
I am new to java and I am trying to work with the stringBuilder at the moment. my current project will allow the user to input a "colors.txt" file. I want to verify that the entered string is valid. The information that is entered is:
Had to parenthesize the # but it need to be taken out and reentered on the valid output.
(#)F3C- valid, ouput(#FF33CCFF)
(#)aa4256- valid, output(AA4256FF)
(#)ag0933 - is invalid because 'g' is not hexadecimal
(#)60CC- valid, output(6600CCFF)
095- valid, output(009955FF)
Be0F- valid, output(BBEE00FF)
(#)AABB05C- invalid, to many characters (7)
So the output to another file called "-norm" appended to the name of the file before the dot ".". I want to verify if the entered line is a true hexadecimal color. Also the out put has to have the validated line equal 8 by doubling the characters, if the double does not equal 8 then "FF" has to be appended to it.
I was able to input the file however without verification. It will read each line and go through 2 methods(Just learning as well) for verification. I am having a lot of issues with my code. I can visualize and know what I want to do, I am having an issue translating that into code.
Thank you for all your help!
import java.util.*; // for Scanner
import java.io.*; // for File, etc.
import java.lang.*;
//import java.awt.* //to use the color class
public class RGBAColor
{
//Scanner file = new Scanner(new File("colors.txt"));
public static void main(String[] args) //throws IOException
throws FileNotFoundException
{
Scanner console = new Scanner(System.in);
System.out.println("Please make sure you enter the colors.txt ");
//assigning the colors file
String fileName = console.nextLine();
Scanner inputFile = new Scanner(new File(fileName));
//outputing to colors-norm file
int dotLocation;
StringBuilder dot = new StringBuilder(fileName);
dotLocation = dot.indexOf(".");
//PrintWriter FileName =
//new PrintWriter("colors-norm.txt");
while (inputFile.hasNextLine())
{
String currLine = inputFile.nextLine();
int lineLenght = currLine.length();
//System.out.printf("line length is %s \n", currLine);
verification(currLine);
}
inputFile.close();
}
//this will verify the color
public static void verification(String line)
{
StringBuilder newString = new StringBuilder(line);
//will be used to compare the length
int stringLength;
//will remove the # if in string
if (newString.charAt(0) == '#')
{
newString = newString.deleteCharAt(0);
}
//assigns the length
stringLength = newString.length();
//checks the length of the string
//prompt will show if the number of digits is invalid
if (!(stringLength == 3 || stringLength == 4 || stringLength == 6 || stringLength == 8))
{
System.out.println("invalid number # of digits " + stringLength + " in "
+ newString);
}
StringBuilder errorLessString = new StringBuilder("");
//checks number and letter for valid entries for hexadecimal digit
for (int i = 0; i < newString.length(); i++ )
{
char valid = newString.toString().toUpperCase().charAt(i);
if (!(valid >= '0' && valid <= '9' || valid >= 'A' && valid <= 'F'))
{
System.out.println("invalid color '" + newString.charAt(i) +
"' in " + newString );
}
errorLessString.append(valid);
}
System.out.println("this is the length of " + errorLessString + " " + errorLessString.length());
String resultingString = " ";
// validating length only allowing the correct lengths of 3,4,6,and 8
switch (errorLessString.length())
{
case 3: System.out.println("begin case 3");
dbleAppend(newString.toString());
addFF(newString.toString());
System.out.println("end case 3");
break;
case 4: dbleAppend(newString.toString());
break;
case 6: addFF(newString.toString());
break;
case 8:
}
}
//method to have two characters together
public static String dbleAppend(String appd)
{
StringBuilder charDouble = new StringBuilder("");
//pass in append string to double the characters
for (int i = 0; i < appd.length(); i++)
{
charDouble.append(appd.charAt(i));
charDouble.append(appd.charAt(i));
}
return appd;
}
//method will append ff to string
public static String addFF(String putFF)
{
StringBuilder plusFF = new StringBuilder("FF");
plusFF.append(putFF.toString());
System.out.println(plusFF);
return putFF;
}
}
1) someone suggested finding the index of the "." and appending the "-norm" so the output file will be whatever file name the user enters with "-norm" attached but before the ".".
So you are unsure whats the best way to get from colors.txt to colors-norm.txt or from foo.txt to foo-norm.txt?
One option is to find the index of the (last) dot in the file name and to split the filename at this point and use the parts to construct the new filename:
String filename = "colors.txt"
int indexOfDot = filename.lastIndexOf(".");
String firstPart = filename.substring(0, indexOfDot); // Will be "colors"
String lastPart = filename.substring(indexOfDot); // Will be ".txt"
return firstPart + "-norm" + lastPart;
A more elegant option is to use a regular expression:
String filename = "colors.txt"
Matcher filenameMatcher = Pattern.compile("(.*)\\.txt").matcher(filename);
if (matcher.matches()) {
String firstPart = matcher.group(1) // Will be "colors"
return firstPart + "-norm.txt"
} else {
//Invalid input, throw an Exeption and/or show an error message
}
If other file extensions than .txt are allowed you'd have to capture the extension too.
2) I want to validate the text file to make sure they are entering a valid file. Do I have to validate each separate part? or the whole string?
The easiest way is to first separate the different color values an then validate each color value. You might want to develop a grammar first, so writing the actual code will be easier.
Since there is only one value per line you could use something like this:
List<String> outputColors = Files.lines(new File(fileName).toPath())
.filter(line -> isValidColor(line))
.map(validColor -> convertToOutputFormat(validColor))
.collect(Collectors.toList());
Files.write(new File(outputFileName).toPath(), outputColors);
3) also writing to a file is a huge issue, I was able to read in the file.
Google is you friend:
http://www.baeldung.com/java-write-to-file
How do I create a file and write to it in Java?
https://www.mkyong.com/java/how-to-write-to-file-in-java-bufferedwriter-example/
4) the output file can only hold the valid inputs.
After you solved 2) properly, this shouldn't be a big problem
I have a text which is on a website. I am scanning that page and counting the number of several characters, including spaces caused by a line break or "enter press" and "tabs".
I have found an answer for counting the number of lines and such.
How can I do this in java? Counting whitespace is easy, there's a method for it, but not the line breaks or tabs as far as I know.
The website is this http://homepage.lnu.se/staff/jlnmsi/java1/HistoryOfProgramming.txt and I'm counting uppercase and lowercase letters, as well as spaces of any sort.
So far my output is correct for upper and lowercases but not spaces. I'm missing 15, which is exactly the number of line breaks.
public class CountChar
{
public static void main(String[] args) throws IOException
{
int upperCase = 0;
int lowerCase = 0;
int whitespace = 0;
int others = 0;
String url = "http://homepage.lnu.se/staff/jlnmsi/java1/HistoryOfProgramming.txt";
URL page = new URL(url);
Scanner in = new Scanner(page.openStream());
while (in.hasNextLine())
{
whitespace++; // THIS IS THE SOLUTION FOR THOSE WHO COME LATER <<<<<
String line = in.nextLine();
for (int i = 0; i < line.length(); i++)
{
if (Character.isUpperCase(line.charAt(i)))
{
upperCase++;
}
else if (Character.isLowerCase(line.charAt(i)))
{
lowerCase++;
}
else if (Character.isWhitespace(line.charAt(i)))
{
whitespace++;
}
else
{
others++;
}
}
}
System.out.print(lowerCase + " " + upperCase + " " + whitespace + " " + others);
}
}
You can use the Pattern and Matcher classes in the standard library to create a regular expression to search for all the characters you are looking for and count the number of occurrences using find() but don't know if this is more complex than what you require and you could just split the string on all required whitespace characters you need... (similar to Krishna Chikkala's answer)
If we assume that your data is stored in a String called data:
String[] arrayOfLines= data.split("\r?\t?\n");
int length=arrayOfLines.length-1;
length would give the number of newline characters in data.
In my course, we are tasked with determining three key statistics about a file that is passed via the console input: 1) number of characters, 2) number of lines, 3) number of words. Before closing this question as a duplicate, please read on to see what unique problem I'm encountering. Thank you :)
I originally wrote a solution with three separate methods and three separate Scanner variables, but I realized that for larger files, this solution would be very inefficient. Instead, I decided to write up a solution that only runs through the file a single time and calculates all three statistics in one go. Here is what I have so far:
import java.util.*;
import java.io.*;
public class FileStatistics
{
// Note: uncomment (A) and (B) below to test execution time
public static void main( String [] args ) throws IOException
{
/* (A)
long startTime = System.currentTimeMillis();
*/
File file = new File(args[0]);
Scanner input = new Scanner(file);
int numChars = 0, numWords = 0, numLines = 0;
/* Calculations */
while( input.hasNextLine() )
{
String currentLine = input.nextLine();
numLines++;
numChars+= currentLine.length();
String [] words = currentLine.split(" ");
numWords += words.length;
}
input.close();
/* Results */
System.out.println( "File " + file.getName() + " has ");
System.out.println( numChars + " characters");
System.out.println( numWords + " words");
System.out.println( numLines + " lines");
/* (B)
long endTime = System.currentTimeMillis();
System.out.println("Execution took: " + (endTime-startTime)/1000.0 + " seconds");
*/
}
}
I've been comparing the results of my program to Microsoft Word's own file statistics by simply copy/pasting the contents of whatever file I'm using into Word. The number of characters and number of lines are calculated correctly.
However, my program does not properly count the number of words. I decided to include a test statement in there to print out the contents of the array words, and it seems that certain "spatial formatting" (like tabs from a Java source code file) are being treated as individual elements in the split array. I tried doing currentLine.replace("\t", "") before invoking the split method to remove those tabs, but this didn't change a thing.
Could someone please offer some advice or hints as to what I'm doing wrong?
This is because the String array returned by currentLine.split(" ") can contain elements which are empty Strings: "". You can see this if you call System.out.println(Arrays.toString(words)).
To create the desired behavior, you can store words.length in a variable count and decrement count for each instance of the empty string "" in words.
Here is a sample solution:
while( input.hasNextLine() )
{
String currentLine = input.nextLine();
numLines++;
numChars+= currentLine.length();
String [] words = currentLine.split("\\s+");
int count = words.length;
for (int i = 0; i < words.length; i++) {
if (words[i].equals("")) {
count--;
}
}
numWords += count;
}
Alternatively, you can convert words to an ArrayList and use the removeAll() functions:
while( input.hasNextLine() )
{
String currentLine = input.nextLine();
numLines++;
numChars+= currentLine.length();
ArrayList<String> words = new ArrayList<>(Arrays.asList(currentLine.split("\\s+")));
words.removeAll(Collections.singleton(""));
numWords += words.size();
}
I need some help with a palindrome detector that I am doing for homework. I need the user to enter a statement, so more then one word, and the program needs to detect which words are a palindrome and which ones are not. However, something in my loop is going wrong in that, it will only detect the first word then blend the others after together. I'm not sure what I'm doing wrong.
import javax.swing.JOptionPane;
public class Main {
static int numpali = 0;
public static void main(String[] args) {
// ask the user to enter a statement
String statement = JOptionPane.showInputDialog("Enter a Statement");
String reverse = "";
// Array to split the sentence
String[] words = statement.split(" ");
// Run a loop to seperate the words in the statement into single Strings
for (String word : words) {
// Print out original word
System.out.println(word + "\n");
int wordlength = word.length();
// send the word to lowercase so capitals are negligible
String wordlower = word.toLowerCase();
// Run a loop that reverses each individual word to see if its a
// palindrome
for (int t = wordlength; t > 0; t--) {
reverse += wordlower.substring(t - 1, wordlength);
wordlength--;
}
System.out.println(reverse);
// show a message if the word is a palindrome or not, and add 1 to the
// total number of palindromes
if (reverse.equals(wordlower)) {
JOptionPane.showMessageDialog(null, word + " is a Palindrome!");
numpali = numpali + 1;
}
word = "";
}
System.out.println("Number of Palindromes:" + "\n" + numpali);
}
}
I've tried to explain what its doing the best I can inside the program.
You never reset the "reverse" value inside your loop. So after the first word your just adding more characters to "reverse" every iteration.
Put
reverse = "";
inside your main for loop
Reset the value of reverse to reverse=""; just like what you have done word="";