Java. word positioning in a string - java

I am currently programming java and have been asked to develop a program that analyses a sentence that contains several words without punctuation. when a word in that sentence is input, the program identifies all of the positions where that word occurs in that string..
String example:
ASK NOT WHAT YOUR COUNTRY CAN DO FOR YOU, ASK WHAT YOU CAN DO FOR YOUR COUNTRY.
Code:
String Scan_word;
Scan_word = JOptionPane.showInputDialog("Word to be scanned for");
String Full_Scan;
Full_Scan = "You have entered " + Scan_word + " "; // the input dialog box will display this when a word is inputted
String sentence = "Ask not what your country should do for you but what you should do for you country"; //The sentence
JOptionPane.showMessageDialog(null, Full_Scan);
if (sentence.contains(Scan_word)); {
String[] sentenceWords = sentence.split(" ");
for (int i = 0; i < sentenceWords.length; i++) {
if (sentenceWords[i].equals(Scan_word)); {
} System.out.println(Scan_word + " is located in the: " + i + "th position");
}
ALL code is in Static void section as should be.
SORRY IT HAS CODING COMMENTS.
PLS ignore the CAQ1STOPBLOCKINGTHEM title as my netbeans projects were being locked for no reason or another.

Your bug seems to be related to your if that is not properly written, indeed you put a semicolon just after it meaning that there no instruction to launch, moreover you print your message outside the curly brackets and finally you should print the value of i + 1 not i since it starts from 0, so your code should rather be:
if (sentenceWords[i].equals(Scan_word)) {
System.out.println(Scan_word + " is located in the: " + (i + 1) + "th position");
}
Consider reading some articles about the naming conventions in java like this one for example. In a nutshell, a varaiable name should start with a lower case.

Related

Need Help Fixing An Exception Error in my Code

I am working on a Lab on the site Zybooks and I have completed the following code below:
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String firstName;
String middleName;
String lastName;
firstName = scnr.next();
middleName = scnr.next();
lastName = scnr.nextLine();
if (lastName.contains("")){
System.out.println(middleName + ", " + firstName.charAt(0) + ".");
}
else {
lastName = lastName.substring(1);
System.out.println(lastName + ", " + firstName.charAt(0) + "." + middleName.charAt(0) + ".");
}
}
}
The Exception Error that I receive is this:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at LabProgram.main(LabProgram.java:13)
When I run the following code in an IDE everything works just fine. However when I try running it in Zybooks I get an exception error. I've come to learn that this is because when I don't add a space after I enter two names that Zybooks gives an exception error. However when I add a space after the last name the code compiles as intended. For grading purposes I need the code to compile without a space from the keyboard, thus I am asking how I can get this code to compile. I've tried manually adding whitespace but nothing has worked.
Any help would be very much appreciated
Looking at the code it's obvious that you have three (3) specific User entry prompts to deal with. The User must supply a First Name, then the User needs to supply a Middle Name, and then finally the User needs to supply a Last Name. As with any input each of these names needs to be validated for proper context. This would include the rules for names, for example everyone has a First Name and Last Name but not everyone has a Middle Name also first and last names can contain two name words (ex: De Vanderholt).
When you have three specific prompts for the User to fill in then let them know exactly where they are at. Display on Screen what the User is expected to enter. It's always a good idea to place each prompt into a loop so that the input can be validated and if there is a problem the User is given the opportunity to provide actual valid data (in this case a valid name).
In your code you use the Scanner#next() method to retrieve the input for both First Name and Middle Name(s) however this method will not play well with multi word names since the next() method is token based. This means that if a two word name is supplied to the First Name prompt then only the first word is retrieved and the second word is automatically applied to the Middle Name prompt. You don't even get a chance to enter the middle name. This is no good unless special code is put in place to take car of this situation. It's just better not to use the next() method in this case and simply use the Scanner#nextLine() method for all your prompts. Keep in mind however that the Scanner#next() method will work just fine if you know that only a single name word will be provided by the User but this method is better used in conjunction with the Scanner#hasNext() method.
Look at your code. As said earlier, everyone has a Last Name but not everyone has a Middle Name so why have this line of code (unless your rules include the fact that last names can be nothing):
if (lastName.contains("")){
It should actually never be allowed to come to this scenario where the last name contains nothing, don't even accept the fact unless it's a middle name. If the supplied Last Name was validated then you would never need to worry about this situation unless of course your rules allow it. The example code below does not allow it.
Because there are three prompt which basically do the same thing and require the same basic validation a helper method (getName()) is used so as to eliminate the need for duplicate code:
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
// First Name:
String firstName = getName(scnr, "First");
// Middle Name:
String middleName = getName(scnr, "Middle");
// Last Name:
String lastName = getName(scnr, "Last");
System.out.println(new StringBuilder("")
.append(lastName).append(", ")
.append(firstName.charAt(0))
.append(". ")
.append(middleName.isEmpty() ? "" : middleName.charAt(0))
.append(middleName.isEmpty() ? "" : ".").toString());
// O R
/*
System.out.println(new StringBuilder("")
.append(lastName).append(", ")
.append(firstName)
.append(" ")
.append(middleName)
.toString());
*/
// O R
/*
System.out.println(new StringBuilder("")
.append(firstName)
.append(" ")
.append(middleName)
.append(middleName.isEmpty() ? "" : " ")
.append(lastName)
.toString());
*/
}
The Helper Method (getName()):
private static String getName(final Scanner scnr, final String nameTitle) {
String name = "";
while (name.isEmpty()) {
System.out.print("Enter your " + nameTitle + " Name: --> ");
// Get input and trim off leading/trailing whitespaces, etc
name = scnr.nextLine().trim();
// Is this for a Middle Name?
if (nameTitle.equalsIgnoreCase("middle")) {
// If nothing was supplied then there is no
// middle name so break out of prompt loop.
if (name.isEmpty()) {
break;
}
}
// Validate name...
/* Does the supplied name only contain A to Z characters
in any letter case. Add characters to the regular
expression as you see fit. (?i) means any letter case. */
if (name.matches("(?i)[A-Z. ]+")) {
// Yes, it does...
/* Ensure 'first' character of each name word (if more than one)
is upper letter case. */
String[] tmp = name.split("\\s+");
StringBuilder nme = new StringBuilder("");
for (String str : tmp) {
if (!Character.isUpperCase(str.charAt(0))) {
str = str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
if (!nme.toString().isEmpty()) {
nme.append(" ");
}
nme.append(str);
}
name = nme.toString();
}
// No it doesn't so inform User of the mistake and to try again.
else {
System.err.println("Invalid " + nameTitle + " Name Supplied! (" + name + ") Try Again...");
name = ""; // Set to null string so as to re-prompt.
}
}
return name;
}

Scanner & .hasNext() issue

I am new to Java and very new to the Scanner class. I am writing a program which asks the user for a word and then this word is searched for within a file. Each time the word is found, it is printed on a new line in a JOptionPane, as well as the word before and after it. Everything is functioning as it should, with two exceptions:
If the word being searched for happens to be the last word in the file then a "NoSuchElementException" is thrown.
If the word being searched for appears twice in a row (unlikely, but still a problem I discovered), it only returns it once. For example, if the word being searched for was "had" and "He said that he had had enough. He had been up all night" were sentences in the file, then the output is:
he had had
He had been
whereas it should be:
he had had
had had enough.
He had been
I believe that my problem lies in the fact that I use a while(scan.hasNext()) and within this loop I use scan.next() twice. I cannot find a solution for this though, while still achieving what I would like the program to return.
Here is my code:
//WordSearch.java
/*
* Program which asks the user to enter a filename followed
* by a word to search for within the file. The program then
* returns every occurrence of this word as well as the
* previous and next word it appear with. Each of these
* occurrences are printed on a new line when displayed
* to the user.
*/
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class WordSearch {
public static void main(String[] args) throws FileNotFoundException {
String fileName = JOptionPane.showInputDialog("Enter the name of the file to be searched:");
FileReader reader = new FileReader(fileName);
String searchWord = JOptionPane.showInputDialog("Enter the word to be searched for in \"" + fileName + "\":");
Scanner scan = new Scanner(reader);
int occurrenceNum = 0;
ArrayList<String> occurrenceList = new ArrayList<String>();
String word = "", previousWord, nextWord = "", message = "", occurrence, allOccurrences = "";
while(scan.hasNext()){
previousWord = word;
word = scan.next();
if(word.equalsIgnoreCase(searchWord)){
nextWord = scan.next();
if(previousWord.equals("")){
message = word + " is the first word of the file.\nHere are the occurrences of it:\n\n";
occurrence = word + " " + nextWord;
}
else{
occurrence = previousWord + " " + word + " " + nextWord;
}
occurrenceNum++;
occurrenceList.add(occurrence);
}
}
for(int i = 0; i < occurrenceNum; i++){
allOccurrences += occurrenceList.get(i) + "\n";
}
JOptionPane.showMessageDialog(null, message + allOccurrences);
scan.close();
}
}
Also, on a side note: How can I implement scan.useDelimeter() to ignore any, question marks, commas, periods, apostrophes etc?
If the word being searched for happens to be the last word in the file then a NoSuchElementException is thrown.
This is because of this line:
if(word.equalsIgnoreCase(searchWord)) {
nextWord = scan.next();
...
}
You do not check if the scan actually hasNext(), going straight for scan.next(). You can fix this by adding a conditional with a call to scan.hasNext()
If the word being searched for appears twice in a row (unlikely, but still a problem I discovered), it only returns it once.
That the same problem is in play here: when you find a word, you retrieve the next one right away.
Fixing this is a little tricky: you need to change your algorithm to look at one word at a time, and use previousWord (which you store anyway) for use of subsequent iterations of the while loop.
What you could do is just call hasNext before using next again.
while(scan.hasNext()){
previousWord = word;
word = scan.next();
if(word.equalsIgnoreCase(searchWord) && scan.hasNext()){ // this line change
nextWord = scan.next();
if(previousWord.equals("")){
message = word + " is the first word of the file.\nHere are the occurrences of it:\n\n";
occurrence = word + " " + nextWord;
}
else {
occurrence = previousWord + " " + word + " " + nextWord;
}
occurrenceNum++;
occurrenceList.add(occurrence);
}
}
You want to not use equals with ignore case. You want to just use .equals().
The solution would be to save two words the way you are currently saving previousWord. Something like:
while (scan.hasNext()) {
previousWord = word;
word = nextWord;
nextWord = scan.next();
Then you check word. If it matches what you need, then you can print it together with previousWord and nextWord. That is, in every iteration, you are checking the word you read in the previous iteration.
This way you only need one hasNext() and one next() in your loop.
Note that after the end of the loop, nextWord might actually be your word. This would mean your word is the last word in the file, and you should check for this and print it accordingly.

Store user input in Arraylist<String> until new line

The problem requires to input different values for each attribute.Ex:
Color Black White
Water Cool Hot Medium
Wind Strong Weak
I made ArrayList of ArrayList of String to store such thing as no. of values of each attribute is not fixed.The user inputs Black White and on hitting new line the program has to start taking values of NEXT attribute( Cool Hot Medium).The no. of attributes has been already specified.I followed some (almost related) answers here and wrote the following code:
ArrayList<ArrayList<String>> attributes = new ArrayList<ArrayList<String>>();
String input;
for(i=0; i<num_of_Attributes ;i++)
{ System.out.print(" Enter attribute no." + i+1 + " : ");
ArrayList<String> list = new ArrayList<String>();
while(! input.equals("\n"))
{
list.add(input);
input = sc.nextLine();
}
attributes.add(list);
}
The program prints "Enter Attribute 1 : " but even after new line it doesn't print "Enter attribute 2 : ".It goes into infinite loop. How can I achieve what the program requires to do? sc is my Scanner object.
You should read:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine%28%29
specifically the part that states:
This method returns the rest of the current line, excluding any line separator at the end
So, if the user inputs an empty line with only the line separator \n, you will read an empty line without such line separator.
Check while (!input.isEmpty()) or, even better, while (!input.trim().isEmpty())
As a more general rule, you can debug your program (or even just print input) to try to find out yourself what is the actual value you are checking.
As a quick-Hack you can do sth. like
for (i = 0; i < num_of_Attributes; i++) {
input = " ";
System.out.print(" Enter attribute no." + (i + 1) + " : ");
ArrayList<String> list = new ArrayList<String>();
while (!input.isEmpty()) {
list.add(input);
input = sc.readLine();
}
attributes.add(list);
}
not nice but it works. Please also watch out for calculating in String concaternation. In you code it will print 01, 11, 21 and so on. With brackets it will work.

Having trouble with Java GUI String formatting in JList

I am making a homework planner GUI program in Java. One GUI takes in data from the user about the assignment, determines priority for the order the homework should be done in, then allows the user to view their schedule as another GUI that displays all their assignments in the appropriate days of the week that they will work on them.
My problem is that I can't get the Strings to format correctly in the JLists. See here:
I'm filling the JLists with String representations of Homework Objects from a PriorityQueue, like this:
while(!sun.isEmpty())
sundayListItems.add(sunday.poll().toString());
.
.
.
sundayList = new JList(sundayListItems.toArray());
My toString method in my Homework class looks like this, which works as it's supposed to in the console when I put in System.out.prints to see how it's working:
String string = nameOfAssignment + " for " + hoursPerDay +" hours";
if (string.length()>17) {//17 characters per line in this JList
String[] words = string.split(" ");
string = "";
int count = words.length;
int i = 0;
while(count>0) {
do{
string += words[i] + " "; //adding words to a line until 17 characters
i++;
count--;
} while(string.length() <= 17);
string += "\n";//skips line when 17 characters
do{
string += words[i] + " ";
count--;
i++;
} while(i < words.length);
string += "\n\n";//separates assignments w/ 2 lines
}
}
return string;
But, in the GUI JLists, the Strings are not formatting the way I want. I want the String to wrap around to the next line after 17 characters. Anyone have any ideas?

Can't get out of my while loop

I was wondering if someone can tell me why my while loop is acting funny. When I input a 3 word phrase it should create an acronym. For a reason beyond my java understanding the while loop executes but then keeps executing even when the client inputs the right answer. Any idea why? I have read what seems million posts and watch youtube videos about it, but no clue.
import javax.swing.*;
import java.util.*;
public class ThreeLetterAcronym
{
public static void main(String args[])
{
//variables
String phrase;
int wordCount;
String acronym;
//input
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase.");
String [] word = phrase.split("\\s+");
wordCount = word.length;
//loop for error when less than 3 words
do
{
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
+ "Please try again.");
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");
}
while(wordCount !=3);
//create acronym
acronym = Character.toString(word[0].charAt(0)).toUpperCase() +
Character.toString(word[1].charAt(0)).toUpperCase() +
Character.toString(word[2].charAt(0)).toUpperCase();
//output
JOptionPane.showMessageDialog(null, "The phrase you inputed is " + "."
+ phrase + "\nYour 3 letter acronym is " + acronym + ".");
}
}
enter code here
Your loop will fail if the user types 4 or more words. Change wordCount != 3 to wordCount < 3 or be ready to handle longer phrases like North Atlantic Treaty Organization.
A do-while loop always executes at least once. Here, where you are checking for errors, that's actually reasonable, but you are also never recalculating your word array, so the error condition persists. You want logic like:
String[] words; // words, not word. There is more than one.
while (true) {
// 1. Fill in the word array from the user's input.
// 2. Check the input for errors.
// a. If there are none, break out of the loop with a break statement.
// b. Otherwise, show the error message.
}
// Create the acronym. Try to use a loop for this too, as in:
StringBuilder acronym = new StringBuilder();
for (String word: words) {
// Append to acronym.
}
// report acronym.
Finally, try not to do all your work in main. Create a ThreeLetterAcronym object, give it instance variables and methods, and tell it to do the work. Break up the work in main into smaller methods. Now, you can test those methods.
Your loop is executing after entering a three-word phrase because, as Eric mentioned, a 'do-while' loop will always execute at least once. The best, simple solution to resolve that issue would be to use a while loop instead, as follows:
while(wordCount != 3)
{
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");enter code here
}
A do-while loop performs an action and then checks if it should perform that action again. A while loop checks if it should perform an action first, which is what you want to be doing.
There are also some other significant issues that would be worth resolving at the same time.
Your variables word and wordCount are not being updated once the program enters your do-while loop. If a user first enters a three-word phrase, they're fine. If they enter a phrase of any other length the program will loop indefinitely. Since the program is executing the logic inside the do-while loop only, and that does not include saving new words into the variable word or figuring their length an dstoring it in wordCount, there is no way to exit the loop.
As a quick fix I added these two lines to solve those issues:
word = phrase.split("\\s+");
wordCount = word.length;
You could also eliminate the wordCount variable entirely by checking, but I'm honestly not sure if there's value in doing that versus having the variable in use. phrase.split("\\s+").length in the while loop.
Your main problem is that your loop will never terminate; wordCount is not being updated inside of your do...while block.
Your next problem is that a do...while loop always runs at least once.
What you can do to fix this issue is move another instantiation of word into your loop body, remove the unnecessary wordCount variable (since it's a property of the array, and we only need it in one spot), and change your do...while to a while.
//input
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase.");
String[] word = phrase.split("\\s+");
//loop for error when less than 3 words
while(word.length < 3) {
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
+ "Please try again.");
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");
word = phrase.split("\\s+");
}
Solved
use this code -
import javax.swing.*;
public class ThreeLetterAcronym
{
public static void main(String args[])
{
//variables
String phrase;
int wordCount;
String acronym;
//input
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase.");
String [] word = phrase.split(" ");
wordCount = word.length;
//loop for error when other than 3 words
while(wordCount!=3)
{
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
+ "Please try again.");
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");
}
//create acronym
acronym = Character.toString(word[0].charAt(0)).toUpperCase() +
Character.toString(word[1].charAt(0)).toUpperCase() +
Character.toString(word[2].charAt(0)).toUpperCase();
//output
JOptionPane.showMessageDialog(null, "The phrase you inputed is " + "."
+ phrase + "\nYour 3 letter acronym is " + acronym + ".");
}
}

Categories

Resources