I have a task where I need to print words from an array in reverse(the word itself). This is what the task states :
Create an array of words called ‘wordList’ and assign the values ‘Stressed’, ‘Parts’, ‘Straw’, ‘Keep’, ‘Wolf’
Create a string called ‘reversedWord’ and do not assign it a value.
Similar to the above challenge, however, instead of reversing a sentence, reverse the order of the letters
within each string.
a. You will need to create a for-loop to access each word in turn. Immediately within the loop set
‘reversedWord = “”;’
b. Then create another for-loop inside of the first one to iterate backwards through the current
word. Update the value of ‘reversedWord’ on each iteration.
c. Print the reversed word on the screen.
STRETCH CHALLENGE: Handle the word so that it reads properly backwards. (Stressed becomes Dessert)
I don't know wether I'm just not understanding the wording of the task or not, but this is the code I have at the moment:
String[] wordList = {"Stressed", "Parts", "Straw", "Keep", "Wolf"};
String reversedWord;
for (int i = wordList.length; i >= 0; i++) {
reversedWord = "";
for (int j = wordList[i].length() - 1; i >= 0; j--) {
reversedWord += wordList[i].charAt(j);
System.out.println(reversedWord);
}
}
It gives me this error when i run it:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at Main.main(Main.java:22)
Any help explanation would be helpful.
There are a few issues here. In the line
for (int i = wordList.length; i >= 0; i++) {
you are setting i to be the length of the wordList, which is 5. Remember, though, that array indexes start at 0. So the valid indexes of wordList are 0, 1, 2, 3, and 4, but not 5. To fix this, you can just subtract 1 from the length.
for (int i = wordList.length - 1; i >= 0; i++) {
The next problem is that you are increasing i at the end of each loop. Since it seems like you're trying to iterate backwards, you're gonna want to decrease i, not increase it.
for (int i = wordList.length - 1; i >= 0; i--) {
There is a simpler solution using Java's StringBuilder class:
public static void main(String[] args) {
String[] wordList = {"Stressed", "Parts", "Straw", "Keep", "Wolf"};
for (int i = 0; i < wordList.length; i++) {
String word = wordList[i]; // Get the word from array
word = new StringBuilder(word).reverse().toString(); // use StringBuilder to reverse the word
wordList[i] = word; // put word back in the array
}
System.out.println(Arrays.asList(wordList));
}
This outputs
[dessertS, straP, wartS, peeK, floW]
UPDATE:
For the words to read properly (first character in uppercase), You could do something like this:
word = word.toLowerCase();
word = word.replace(word.substring(0,1), word.substring(0,1).toUpperCase());
wordList[i] = word; // put word back in the array
There are more effective ways to do this, but is simpler for you to understand. This obviously outputs:
[Desserts, Strap, Warts, Peek, Flow]
substring(0,1) returns the first character (substring from index 0 to index 1; where the last index is not inclusive) as a String. Then, you are replacing the same substring with the uppercase substring.
Related
So I was trying to build a solitaire encryption program, but I keep running into a problem when it comes to this method. The char array a represents the word the user inputs (converted it into an array to make it easier) and the char array b represents the alphabets so it has 25 indexes. What I am trying to do is match the alphabet to its number. It seemed simple enough but I am having a hard time as it keeps throwing an ArrayIndexOutOfBoundsException. I have tried to use for loops, nested for loops and other tests but it keeps throwing the exception or just outputs unexpected results such as [0, 0, 0, 0, 0]. I have debugged it and it seems like b[i] never equals a[j] so j will always be 0.
public static int[] converter(char[] a, char[] b){
int[] res = new int[a.length];
int i = 0;
int j = 0;
while(i < a.length){
if(b[i] == Character.toUpperCase(a[j])){ //Does not run through the first loop at all
res[j] = i + 1;
j = j + 1;
} else {
i = i + 1;
}
}
return res;
}
Please do not link the similar question. It does not answer my question.
The code below is a solution. We want the wordCharacterIndex to iterate through the word to see the place where a character is. The characterIndex iterates through the characters to compare with the word's character present at the wordCharacterIndex. After setting the result, we need to reset the characterIndex so that it goes back to the first character in the character array to compare with the other word characters, if we didn't, the following characters of the word would need to be at a higher character index, which is not what we want. Naming variables actual words is very important to better understand what you are trying to do within your code. You were comparing i < a.length while you were iterating through b[i] which made it possible to go larger than b's bounds and therefore cause an ArrayIndexOutOfBoundsException. I hope this helps you better understand.
public static int[] converter(char[] word, char[] characters){
int[] result = new int[word.length];
int characterIndex = 0;
int wordCharacterIndex = 0;
while(wordCharacterIndex < word.length){
if(characters[characterIndex] == Character.toUpperCase(word[wordCharacterIndex])){
result[wordCharacterIndex] = characterIndex + 1;
wordCharacterIndex++;
characterIndex = 0;
} else {
characterIndex++;
}
}
return result;
}
This is my assignment. I am not allowed to use if statements.
Write a program NumStrings.java that receives two strings through the command line as
input and then prints out the number of times the second string occurs as a substring in the
first.
My bad code:
public class Test {
public static void main(String[] args) {
String a = "HelloHelloHelloHello";
String b = "Hello";
int times = 0;
for(int i=0; i <= a.length()-5; i++){
for (int z=4; z<=(a.length()-1) && a.compareTo(b)==0; z++){
times = times +1;
}
}
System.out.print(times);
}
}
Here is the correct way to do it, using subString() (documentation here: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int)):
String a = "HelloHelloHelloHello";
String b = "Hello";
int times = 0;
for (int i = 0; i <= a.length() - b.length(); i++) {
String substring = a.subString(i, i + b.length());
if (substring.equals(b)) {
times = times + 1;
}
}
System.out.println(times);
And here is a way to do it without if statements... Which I don't recommend. But if you have to do it that way, this will work.
String a = "HelloHelloHelloHello";
String b = "Hello";
int times = 0;
for (int i = 0; i <= a.length() - b.length(); i++) {
String substring = a.substring(i, i + b.length());
for (int j = 0; substring.equals(b) && j < 1; j++) {
times = times + 1;
}
}
System.out.println(times);
Look at it this way: you don't have to count how often you find the second string in the first String, because you always have to check if you found it or not. So, to avoid all sorts of conditions or if statements, consider using firstString.split(secondString).
split(someString) will return you an array of remaining substrings once you "split" the base string everytime it finds your substring:
String first = "bababa";
String second = "a";
String[] substrings = first.split(second);
now substrings will look like this: ["b", "b", b"] because every a has been removed and the rest put in separate Strings.
Next you have to check the size of the array and you'll see how often your first String was split.
int count = substrings.length; // 3
However, this is not the end of it because we still have the following case:
String first = "bababaa";
With the above solution you would get an array of size 3: ["b", "b", "b"]. The last occurrence of a will only be removed without leaving any substring behind (not even an empty one '').
So you can take advantage of another (slightly different) split():
first.split(second, limit);
Where limit is the maximum number of occurrences the method tries to find. So how often can you find your second string in the first one? As many letters the first string has: int limit = first.length
first.split(second, first.length); // will produce [b, b, b, , ]
Can you see what happens? there are two empty strings at the end where there where two a. You get an array of substrings for everything that is found before or after the occurrence of the second String.
Naturally, when you split the string ba you would get ["b", ] so 2 substrings. But you don't care about the b just the "commas" in the middle (for every a a ,).
first.split(second, first.length).length -1; // that's how many commas there are, and thats how many second strings there are
EDIT
(thanks #saka1029 !) So, the "split" method still misses something when first="aaa" and second="aa" because it counts only 1 not 2 occurrences.
To correct that I thought of looping through the whole first string and checking only for the very first occurrence, and then removing the first letter and continuing (since OP already accepted another answer, I just post my code):
String first = "ZZZ";
String second = "ZZ";
int counter = 0; // counts the number of occurrences
int n = first.length(); // needs to be fixed, because we'll change the length of the first string in the loop
for(int i = 0; i < n; i++){ // check the first string letter by letter
String[] split = first.split(second, 2); // we want one substring and the rest (2 in total) like: ['', 'Z'] when we cut off the first 'ZZ'
counter += split.length - 1; // now add the number of occurrences (which will be either 0 or 1 in our case)
first = first.substring(1); // cut off the first letter of the first string and continue
}
System.out.println("counter = " + counter); // now we should get 3 for 'ZZZ'
My NEW sample text i was testing: My mom is a good cook. Although sometimes at around noon she will leave and forget to make me lunch and some pop. #Old homework become relevant again
my problem is just that i am not getting the correct output, as my method only prints *Mom a noon i
This is all GUI based.I am reading in a file and checking for palindromes and printing them out in my JTextArea afterwards using Stacks and Queue's.
Issue is, all of this is working and when i start the program and attach the text file, i only get the first palindrome. SO it will print "mom" which is my first testcase, but it won't go to any of the other palindromes following it?
I thought i might have got bogged down in my code blocking at some point but after tinkering with it for a day now i'm sort of stuck.
EDIT 1: I am now getting more results
my method is,
public void fileDecode() throws FileNotFoundException
{
if (fileChoice.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{
file = fileChoice.getSelectedFile();
scanInput = new Scanner(file);
while(scanInput.hasNext())
{
int nextPalindrome = 0;
int counter = 0;
String token = scanInput.next();
Stack<Character> stk = new Stack<Character>();
Queue<Character> que = new LinkedList<Character>();
for (int i = 0; i < token.length(); ++i)
{
stk.push(token.charAt(i)); //pushing all char's onto the stack/queue
que.add(token.charAt(i));
}
for (int j = 0; j < token.length(); ++j)
{
char tempStk = stk.pop(); //removing them one at a time and checking if they are equal and incrementing counter
char tempQue = que.remove();
if (tempStk == tempQue)
{
counter++;
}
}
if (counter == token.length())
{
build.append(token + " "); //if the counter # was the same as the token's length, than it is indeed a palindrome and we append it into our StringBuilder that we pass to the JTextArea
nextPalindrome = token.length();
}
}
}
}
You set counter to 0 outside your while loop, so the count of the second word is going to start at the count of the first word. Move counter = 0 inside the while loop and it should work.
Also, nextPalindrome doesn't appear to be used, and even if it is, if you set it at the bottom of the loop, it's immediately set to 0 at the top, so it will only remain non-zero if the last word is a palindrome.
Also, think about what's happening in the second for loop. You're looping over all the characters and comparing the one from the stack and the one from the queue. If ever those are different, you know you don't have a palindrome, so once you find a difference, it's pointless to continue with the loop. You also already have a loop counter, j, so you don't need another one. So I'd rewrite the second loop and following condition as follows:
for (int j = 0; j < token.length(); ++j)
{
char tempStk = stk.pop(); //removing them one at a time and checking if they are equal and incrementing counter
char tempQue = que.remove();
if (tempStk != tempQue)
break;
}
if (j == token.length())
That works because the only way j can equal token.length() after the loop is done is if the loop completed, which can only happen if no pairs of characters aren't equal (in other words, all pairs of characters are equal, which is what you want).
So our teacher gave us this homework, we had to write a program that went something along the lines of
Write an application that reads a line of text from the keyboard and prints a table indicating the number of occurrences of each letter
of the alphabet in the text, For example, the phrase
To be, or not to be: that is the question:
Contains one “a,” two “b’s,” no “c’s,” and so on.
Well I've written the code, but I've ran into one small problem when I enter the to be or not to be part the code continually loops forever. I've looked at this program forever, I even tried asking some folks at Yahoo (but I think I confused them). So I am hoping someone here will spot something I missed or have some advice to give me.
public class occurances {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
String str;
char ch;
int count = 0;
System.out.println("Enter the string:");
str = inp.nextLine();
while (str.length() > 0) {
ch = str.charAt(0);
int i = 0;
while (i < str.length() && str.charAt(i) == ch) {
count = count++;
i++;
}
str = str.substring(count);
System.out.println(ch);
System.out.println(count);
}
}
}
There are many problems with your code, but start with count = count++. It will always have its initial values (0 in your case). That causes the infinite loop. If you manage this one you'll be good to go with debugging your code further. Learn how to use debugger and/or print for checking your code. Good luck.
It seems your approach is not necessarily the one the teacher wants. Your approach (if it worked at all) would display the character counts in the order the characters appear in the string. So, for example, for "To be, or not to be: that is the question" you would show the character count for "T" first, whereas the teacher probably wants you to show the character count for "a" first. Your approach also doesn't show the character counts for the characters that are missing in the answer.
It has been suggested in the other two answers to use a Map. I recommend that approach, although you could use a simple int[] array where the index is (ch - 'a') assuming that it is between 0 and 25. See Character.toLowerCase() for how to convert a character into a lowercase one, because the correct answer would probably treat "T" and "t" as the same.
You need only one loop through the array, incrementing the counts for the characters that appear. Obviously all of the counts should be initialized to 0 prior to the loop.
I've not done JAVA in a while i came here to help someone with Javascript... but i'll give it go
while(str.length()>0)
This will obviously enter an endless loop because you have no breakout terms... i'd probably use a for loop instead... also you need something to store your counts inside of for each unique letter you find.
-- EDIT based on the comment below i find myself agreeing that answering your homework is not a good thing but here is what i'd suggest you look at...
Look at Hashtables or Maps and thing about "storing the dictionary counts as you find them"
Bare in mind upper and lower case letter, i'd just cast to lowercase and count
use a for loop instead of the while loop, use the strings length as the limit e.g. count from 0 to string.length()
This should get you on the right path :http://www.java2s.com/Tutorial/Java/0140__Collections/GettingelementskeyvaluepairsfromaHashtabletheentrySetmethod.htm
Some things to resolve in your code:
while(str.length()>0) : Infinite loop here. You could go through the string, with a for (int index = 0; index < str.length(); index++).
ch = str.charAt(0); : Here you are always taking the first letter of the String, you should take each letters with ch = str.charAt(index);.
count = count++; : count++; would be enough or count = count + 1;.
count = count++; : count should be re-initialized for each letter count = 0; before your while inner loop.
str = str.substring(count); : No need to substring here. You would loose letters for next computation.
Your code should work with one disavantages. The letters and their count will be written as many times as their is their occurence. If a is 3 times in the String, a : 3 will be written 3 times.
So you should whether you had already print the letter (maybe an array), but performance would be bad. For a String of n letters, you would have n * n computations (Complexity O(n^2)). If you take an HashMap between letter and their count, you will just of to go through the String one time, incrementing your counter while iterating on the loop. Then you would have only n computations. (Complexity O(n)).
HashMap<Char, Integer> letters = new HashMap<Char, Integer>();
for (int i = 0; i < str.length(); i++) {
char letter = str.charAt(i);
if (!letters.contains(letter)) {
letters.put(letter, 1);
} else {
letters.put(letter, letters.get(letter) + 1);
}
}
Then you go through the map to display the count.
Here is your corrected code for the problem you asked..Try this..
import java.util.*;
public class Occurence {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
String str;
char ch;
int count = 0;
System.out.println("Enter the string:");
str = inp.nextLine();
int length = str.length();
int i = 0, j = 0;
for (i = 0; i < length; i++) {
j = 0;
count=0;
for (j = 0; j < length; j++) {
if (str.charAt(j) == str.charAt(i)) {
count++;
}
System.out.println(str.charAt(i)+" "+count);
}
}
}
}
Basically what I need to do is only save the first ten words of a sentence into the Array. I know from my code that all the words will be saved if it is greater than 10, but I only iterate through the loop 10 times so it stops. However, if the sentence has less than 10 words, I need to fill it with an empty string. So I can get it to work if it has 10 or more words. However, I cannot get it to work if there is less than 10 words. Does anyone know of a way to make it work? I have to have an Array size of 10.
String[] tempString = new String[10];
tempString = sentence.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s+");
for(int i = 0; i < tempString.length; i++)
{
System.out.println(tempString[i]);
}
EDIT:
So essentially if I entered the sentence: "one two three four five six seven eight nine ten," it would work. However, if I entered "one, two, three" it would give me an ArrayOutofBoundsException. What I need the other 7 indexes to be filled with is an empty string.
You can use the following :
for(int i = 0; i < 10; i++)
{
if (i < tempString.length)
System.out.println(tempString[i]);
else
System.out.println("");
}
Since you need 10 prints then you iterate 10 times. Each iteration you check that you are still in the splitted string array bound. If not just fill the rest with an empty space as you desire.
do like this
if(tempString.length<10)
tempString = Arrays.copyOf(tempString, 10);
String[] tempString = new String[10];
tempString = sentence.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s+");
The two above lines don't make much sense. The first line creates a new array of length 10 and assigns it to the variable tempString, but the second line says: let's forget about this array, and reasign a new array, containing all the words of the sentence, to the tempString variable.
So you actually need two variable:
String[] result = = new String[10];
String allWords = sentence.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s+");
// now copy at most 10 elements from allWords to result:
for (int i = 0; i < result.length && i < allWords.length; i++) {
result[i] = allWords[i];
}
// and now initialize the rest of the array with empty strings
for (int i = allWords.length; i < result.length; i++) {
result[i] = "";
}
String[] tempString = Arrays.copyOf(sentence.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s+"), 10);
There are 2 ways to achieve this..
Initailize all Strings to empty "" (in a for loop..) before you call the for loop shown in your code.
After looping, if length is less than 10, then set remaining items to ""
if ( tempString.length < 10) ;
int diff = 10 - tempString.length -1;
Loop diff times and add "" each time..
Sorry about the formatting..