Hey guys, I'm new to Java (well, 3/4 of a year spent on it).
So I don't know much about it, I can do basic things, but the advanced concepts have not been explained to me, and there is so much to learn! So please go a little but easy on me...
Ok, so I have this project where I need to read lines of text from a file into an array but only those which meet specific conditions. Now, I read the lines into the array, and then skip out on all of those which don't meet the criteria. I use a for loop for this. This is fine, but then when I print out my array (required) null values crop up all over the place where I skipped out on the words.
How would I remove the null elements specifically? I have tried looking everywhere, but the explanations have gone way over my head!
Here is the code that I have to deal with the arrays specifically: (scanf is the scanner, created a few lines ago):
//create string array and re-open file
scanf = new Scanner(new File ("3letterWords.txt"));//re-open file
String words [] = new String [countLines];//word array
String read = "";//to read file
int consonant=0;//count consonants
int vowel=0;//count vowels
//scan words into array
for (int i=0; i<countLines; i++)
{
read=scanf.nextLine();
if (read.length()!=0)//skip blank lines
{
//add vowels
if (read.charAt(0)=='a'||read.charAt(0)=='e'||read.charAt(0)=='i'||read.charAt(0)=='o'||read.charAt(0)=='u')
{
if (read.charAt(2)=='a'||read.charAt(2)=='e'||read.charAt(2)=='i'||read.charAt(2)=='o'||read.charAt(2)=='u')
{
words[i]=read;
vowel++;
}
}
//add consonants
if (read.charAt(0)!='a'&&read.charAt(0)!='e'&&read.charAt(0)!='i'&&read.charAt(0)!='o'&&read.charAt(0)!='u')
{
if (read.charAt(2)!='a'&&read.charAt(2)!='e'&&read.charAt(2)!='i'&&read.charAt(2)!='o'&&read.charAt(2)!='u')
{
words[i]=read;
consonant++;
}
}
}//end if
//break out of loop when reached EOF
if (scanf.hasNext()==false)
break;
}//end for
//print data
System.out.println("There are "+vowel+" vowel words\nThere are "+consonant+" consonant words\nList of words: ");
for (int i=0; i<words.length; i++)
System.out.println(words[i]);
Thanks so much for any help received!
Just have a different counter for the words array and increment it only when you add a word:
int count = 0;
for (int i=0; i<countLines; i++) {
...
// in place of: words[i] = read;
words[count++] = read;
...
}
When printing the words, just loop from 0 to count.
Also, here's a simpler way of checking for a vowel/consonant. Instead of:
if (read.charAt(0)=='a'||read.charAt(0)=='e'||read.charAt(0)=='i'||read.charAt(0)=='o'||read.charAt(0)=='u')
you can do:
if ("aeiou".indexOf(read.charAt(0)) > -1)
Update: Say read.charAt(0) is some character x. The above line says look for that character in the string "aeiou". indexOf returns the position of the character if found or -1 otherwise. So anything > -1 means that x was one of the characters in "aeiou", in other words, x is a vowel.
public static String[] removeElements(String[] allElements) {
String[] _localAllElements = new String[allElements.length];
for(int i = 0; i < allElements.length; i++)
if(allElements[i] != null)
_localAllElements[i] = allElements[i];
return _localAllElements;
}
Related
I'm tasked to take the words out of a txt file and then eliminate the duplicates and print out the rest. However there seems to be something weird going on when I place the for loop used to print out the array of words that are taken from the txt file.
When I do
for (String word:arr)
{
words = word.split(" ");
for (int i = 0; i < words.length; i++)
{
// Printing the elements of String array
System.out.print(words[i] + " ");
}
}
where, arr is an array of string; filled with sentences from the text file , and words is the individual words of the text file stored in array of strings, printing the array words will give what it is supposed to,
however when I do
for (String word:arr)
{
words = word.split(" ");
}// not nested so happens seperately
for (int i = 0; i < words.length; i++)
{
// Printing the elements of String array
System.out.print(words[i] + " ");
}
I only obtain 4 words out of the hundreds that are stored in the txt file.
Can someone help explain this? Thanks in advance!
In the second case you are processing outside of the first for, and you process just the last String that is in your array. Words variable gets overwritten in each itteration. My suggestion is to learn how to debug, it will greatly help you to learn.
I am a beginner coder at my Uni. We are tasked with reading a text file, verifying all the first letters of each word are capital, and then they are put in alphabetical order. I am trying to tackle one point at a time. So I decided to go with verifying all the first letters are capital by just making my own array of words and then figuring out how to do it from a text file after. This is what I have so far and it's nothing
I have tried Character.isUpperCase(arr.charAt(0));
but i am gettin an error
public void sortStrings() throws IOException {
String[] arr = {"Zebra", "test","Butter"};
String[] arr2 = {"Legends","Apex","Best"};
for(int i = 0; i < arr.length; i++) {
if(Character.isUpperCase(arr.charAt(0)));
}
Cannot invoke charAt(int) on the array type String] is the error I am getting with arr.charAt(0)
Appreciate any tips !
You forgot the index to access the item in your array. Replace arr.charAt(0) with arr[i].charAt(0)
String[] arr = {"Zebra", "test","Butter"};
for(int i = 0; i < arr.length; i++) {
if(Character.isUpperCase(arr[i].charAt(0)))
doSomethingHere();
}
I am a little confused how to approach this problem. The userKeyword is passed as a parameter from a previous section of the code. My task is to remove any duplicate chars from the inputted keyword(whatever it is). We have just finished while loops in class so some hints regarding these would be appreciated.
private String removeDuplicates(String userKeyword){
String first = userKeyword;
int i = 0;
while(i < first.length())
{
if (second.indexOf(first.charAt(i)) > -1){
}
i++;
return "";
Here's an update of what I have tried so far - sorry about that.
This is the perfect place to use java.util.Set, a construct which is designed to hold unique elements. By trying to add each word to a set, you can check if you've seen it before, like so:
static String removeDuplicates(final String str)
{
final Set<String> uniqueWords = new HashSet<>();
final String[] words = str.split(" ");
final StringBuilder newSentence = new StringBuilder();
for(int i = 0; i < words.length; i++)
{
if(uniqueWords.add(words[i]))
{
//Word is unique
newSentence.append(words[i]);
if((i + 1) < words.length)
{
//Add the space back in
newSentence.append(" ");
}
}
}
return newSentence.toString();
}
public static void main(String[] args)
{
final String str = "Words words words I love words words WORDS!";
System.out.println(removeDuplicates(str)); //Words words I love WORDS!
}
Have a look at this answer.
You might not understand this, but it does the job (it cleverly uses a HashSet that doesn't allow duplicate values).
I think your teacher might be looking for a solution using loops however - take a look at William Morisson's answer for this.
Good luck!
For future reference, StackOverflow normally requires you to post what you have, and ask for suggestions for improvement.
As its not an active day, and I am bored I've done this for you. This code is pretty efficient and makes use of no advanced data structures. I did this so you could more easily understand it.
Please do try to understand what I'm doing. Learning is what StackOverflow is for.
I've added comments in the code to assist you in learning.
private String removeDuplicates(String keyword){
//stores whether a character has been encountered before
//a hashset would likely use less memory.
boolean[] usedValues = new boolean[Character.MAX_VALUE];
//Look into using a StringBuilder. Using += operator with strings
//is potentially wasteful.
String output = "";
//looping over every character in the keyword...
for(int i=0; i<keyword.length(); i++){
char charAt = keyword.charAt(i);
//characters are just numbers. if the value in usedValues array
//is true for this char's number, we've seen this char.
boolean shouldRemove = usedValues[charAt];
if(!shouldRemove){
output += charAt;
//now this character has been used in output. Mark that in
//usedValues array
usedValues[charAt] = true;
}
}
return output;
}
Example:
//output will be the alphabet.
System.out.println(removeDuplicates(
"aaaabcdefghijklmnopqrssssssstuvwxyyyyxyyyz"));
I've seen similar questions asked about how to find a blank line. I know how to find a blank line, but the sheer nature of finding it retrieves it and screws up the rest of your code.
Consider the following while loop:
while(file.hasNextLine()){
if(file.nextLine.equals("")){
continue;
}
String[] words = file.nextLine().split(" ");
for(int i = 0; i < words.length; i++){
System.out.print(words[i]);
}
}
The idea here is to say, if there is a blank line, skip this iteration and move to the next line only extracting words. But just checking to see if the line is blank retrieves the next line (blank or not) and then retrieves the FOLLOWING line and stores it in words.
What is the proper way to find blank lines without actually retrieving 'nextLine' to do so?
Call file.nextLine(), but store it in a variable before checking it for emptiness. That way you'll only call it once per iteration.
while(file.hasNextLine()){
final String line = file.nextLine();
if(line.isEmpty()){
continue;
}
String[] words = line.split(" ");
for(int i = 0; i < words.length; i++){
System.out.print(words[i]);
}
}
I'm working on a program for Java on how to find a list of palindromes that are embedded in a word list file. I'm in an intro to Java class so any sort of help or guidance will be greatly appreciated!
Here is the code I have so far:
import java.util.Scanner;
import java.io.File;
class Palindromes {
public static void main(String[] args) throws Exception {
String pathname = "/users/abrick/resources/american-english-insane";
File dictionary = new File(pathname);
Scanner reader = new Scanner(dictionary);
while (reader.hasNext()) {
String word = reader.nextLine();
for (int i = 0; i > word.length(); i++) {
if (word.charAt(word.indexOf(i) == word.charAt(word.indexOf(i)) - 1) {
System.out.println(word);
}
}
}
}
}
There are 3 words that are 7 letters or longer in the list that I am importing.
You have a few ways to solve this problem.
A word is considered a palindrome if:
It can be read the same way backwards as forwards.
The first element is the same as the last element, up until we reach the middle.
Half of the word is the same as the other half, reversed.
A word of length 1 is trivially a palindrome.
Ultimately, your method isn't doing much of that. In fact, you're not doing any validation at all - you're only printing the word if the first and last character match.
Here's a proposal: Let's read each end of the String, and see if it's a palindrome. We have to take into account the case that it could potentially be empty, or be of length 1. We also want to get rid of any white space in the string, as that can cause errors on validation - we use replaceAll("\\s", "") to solve that.
public boolean isPalindrome(String theString) {
if(theString.length() == 0) {
throw new IllegalStateException("I wouldn't expect a word to be zero-length");
}
if(theString.length() == 1) {
return true;
} else {
char[] wordArr = theString.replaceAll("\\s", "").toLowerCase().toCharArray();
for(int i = 0, j = wordArr.length - 1; i < wordArr.length / 2; i++, j--) {
if(wordArr[i] != wordArr[j]) {
return false;
}
}
return true;
}
}
I'm assuming that you're reading in strings. Use string.toCharArray() to convert each string to a char[]. Iterate through the character array using a for loop as follows: on iteration 1, if the first character is equal to the last character, then proceed to the next iteration, else return false. On iteration 2, if the second character is equal to the second-to-last character then proceed to the next iteration, else return false. And so on, until you reach the middle of the string, at which point you return true. Be careful of off-by-one errors; some strings will have an even length, some will have an odd length.
If your palindrome checker is case insensitive, then use string.toLowerCase().toCharArray() to preprocess the character array.
You can use string.charAt(i) instead of string.toCharArray() in the for loop; in this case, if the palindrome checker is case insensitive then preprocess the string with string = string.toLowerCase()
Let's break the problem down: In the end, you are checking if the reverse of the word is equal to the word. I'm going to assume you have all of the words stored in an array called wordArray[].
I have some code for getting the reverse of the word (copied from here):
public String reverse(String str) {
if ((null == str) || (str.length() <= 1)) {
return str;
}
return new StringBuffer(str).reverse().toString();
}
So, now we just need to call that on every word. So:
for(int count = 0; count<wordArray.length;count++) {
String currentWord = wordArray[count];
if(currentWord.equals(reverse(currentWord)) {
//it's a palendrome, do something
}
}
Since this is homework, i'll not supply you with code.
When i code, the first thing i do is take a step back and ask myself,
"what am i trying to get the computer to do that i would do myself?"
Ok, so you've got this huuuuge string. Probably something like this: "lkasjdfkajsdf adda aksdjfkasdjf ghhg kajsdfkajsdf oopoo"
etc..
A string's length will either be odd or even. So, first, check that.
The odd/even will be used to figure out how many letters to read in.
If the word is odd, read in ((length-1)/2) characters.
if even (length/2) characters.
Then, compare those characters to the last characters. Notice that you'll need to skip the middle character for an odd-lengthed string.
Instead of what you have above, which checks the 1st and 2nd, then 2nd and 3rd, then 3rd and fourth characters, check from the front and back inwards, like so.
while (reader.hasNext()) {
String word = reader.nextLine();
boolean checker = true;
for (int i = 0; i < word.length(); i++) {
if(word.length()<2){return;}
if (word.charAt(i) != word.charAt(word.length()-i) {
checker = false;
}
}
if(checker == true)
{System.out.println(word);}
}