I'm trying to slice a string for the first time.
With this code, if I input, for example 'one two three' it works fine until the last word.
This is the last few lines of the output:
Current word is thr
Sentence is now e
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.substring(String.java:1907)
at TestCurr.main(testCurrentWord.java:18)
Has anyone any idea why it does that to the last word?
class TestCurr
{
public static void main (String []args)
{
String s;
int i;
String currentWord;
int length;
int spacePos;
System.out.println("Enter a sentence ");
s = EasyIn.getString();
spacePos = s.indexOf(" ");
length = s.length();
for (i = length -1; i >= 0; i--)
{
currentWord = s.substring(0,spacePos);
s = s.substring(spacePos +1);
System.out.println("Current word is " + currentWord);
System.out.println("Sentence is now " + s);
}
}
}
First of all, you call
spacePos = s.indexOf(" ");
length = s.length();
only once, but these values should change with each iteration of the loop. Furthermore,
s.substring(spacePos +1);
with
spacePos == s.length()-1
means you are passing an index beyond the end of the string as the start index for substring(). Once you fix the first error, this will be your next exception.
Your problem is that you only get the index of the space once. This causes the program to cut the string every three characters, as the first word is three letters long. You need to update spacePos after each iteration.
I believe your problem is in your usage of your spacePos variable.
Outside the loop, you initialize the variable like so:
spacePos = s.indexOf(" ");
Which in your example string of "one two three", yields 3.
But then inside your loop, you never set the variable again, based on what whatever is left that you haven't processed.
Try re-calculating spacePos's value inside the loop and your problem should go away.
Your current approach is too error prone.
And you have too many variables.
Try this just as an idea.
class TestCurr {
public static void main(String[] args) {
String s = null;
System.out.println("Enter a sentence: ");
s = " one two three ";
System.out.println("|" + s + "|");
int i = 0;
int j = 0;
while (true){
while (i<s.length() && s.charAt(i)==' ') i++;
j = i;
if (i>=s.length()) break;
while (i<s.length() && s.charAt(i)!=' ') i++;
System.out.println("Current word is: [" + s.substring(j, i)+ "]");
System.out.println("Sentence is now: [" + s.substring(i) + "]");
if (i>=s.length()) break;
}
}
}
As others have stated, you only get the index once. But I'm curious, why re-invent the wheel?
String s = "one two three";
String[] split = s.split(" ");
for (String out : split) {
System.out.println("Word: " + out);
}
Related
I have a program that takes whatever string is entered and prints it backwards. However, the statement I want to print prints after each iteration because it is in the for loop. However, when I move it outside the for loop, it doesn't recognize the variable "letter". How can I fix this?
import java.util.Scanner;
public class ReadBackwards {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String word;
char letter;
int counter, wordLength;
System.out.print("Please type a word: ");
word = keyboard.next();
wordLength = word.length();
for(counter = wordLength-1; counter >= 0; counter--) {
letter = word.charAt(counter);
System.out.print(word + " backwards is " + letter);
}
}
}
By appending each letter to something like a StringBuilder and then printing that. You should also try to limit the scope of your variables (and I'm not sure I see the value in most of them). You could do
String word = keyboard.next();
StringBuilder sb = new StringBuilder();
for (int counter = word.length() - 1; counter >= 0; counter--) {
sb.append(word.charAt(counter));
}
System.out.println(word + " backwards is " + sb.toString());
And, that might be further simplified to
String word = keyboard.next();
System.out.println(word + " backwards is "
+ new StringBuilder(word).reverse().toString());
One option would be to use System.out.print() instead of println() and just print single characters in a single row:
System.out.println(word + " backwards is: ");
for (counter = wordLength-1; counter >= 0; counter--) {
letter = word.charAt(counter);
System.out.print(letter);
}
Demo
I am quite new to programming and I am writing this code to count a string (length) to a point when I encounter a space. The aim is - when the user enters his/her name AND surname, the program should split the name from surname and count how many letters/characters were there in the name (and surname).
My code doesn't seem to reach/execute the "if-statement", if I enter two strings (name & surname) separated by space (output: Your name is: (empty space) and it has 0 letters. However, if I enter only one string, the if-statement, it gets executed.
What I am doing wrong?
My example code:
public class Initials {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String nameAndSurname, nameOnly;
int c = 0, count = 0;
System.out.println("Enter your full name please:");
nameAndSurname = scan.nextLine();
int space = nameAndSurname.indexOf(' ');
for(int x = 0; x<=nameAndSurname.length()-1; x++) {
c++;
if(nameAndSurname.indexOf(x) == space) //if there is a space
{
count = c; //how many characters/letters was there before space
System.out.println(count);
}
}
nameOnly = nameAndSurname.substring(0, count);
System.out.println("Your name is: " + nameOnly.toUpperCase() + " and it has " + count + " letters");
scan.close();
}
Why bother with all that code? Just skip the for-loop, have an
if (space != -1) nameOnly = nameAndSurname.substring(0,space);
and if you really want to know the amount of letters, it is
space+1
No need for all that complicated stuff.
if(nameAndSurname.indexOf(x) == space)
This line isn't doing what you think it is doing.
It's getting a char (character) from the index of x, and comparing it to the value of space. Space is an integer, so you are comparing the character at position x to the integer position of the first space. In this case, the letter at position x is cast into an integer, and then compared to the actual number value of the first space!
To fix the program, replace your entire if statement with this.
if (nameAndSurname.charAt(x) == ' ') //if there is a space
{
count = c-1; //how many characters/letters was there before space
System.out.println(count);
}
Extra:
Since the way you've solved this problem is a bit overkill, I've posted another solution below which solves it in a way that is easier to read. Also it won't break if you put in more or less than 1 space.
Scanner scan = new Scanner(System.in);
String nameAndSurname;
System.out.println("Enter your full name please:");
nameAndSurname = scan.nextLine().trim();
int indexOfFirstSpace = nameAndSurname.indexOf(' ');
if (indexOfFirstSpace > -1) {
String firstName = nameAndSurname.substring(0, indexOfFirstSpace);
System.out.println("Your first name is " + firstName.toUpperCase());
System.out.println("It is " + firstName.length() + " characters long.");
}
You can verify if your string has space before start the loop, something like this:
public class Initials {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String nameAndSurname, nameOnly;
int c = 0, count = 0;
System.out.println("Enter your full name please:");
nameAndSurname = scan.nextLine();
int space = nameAndSurname.indexOf(' ');
if(space == -1) {
System.out.println("Your name has no spaces");
} else {
for(int x = 0; x<nameAndSurname.length(); x++) {
c++;
if(nameAndSurname.indexOf(x) == space) //if there is a space
{
count = c; //how many characters/letters was there before space
System.out.println(count);
}
}
nameOnly = nameAndSurname.substring(0, count);
System.out.println("Your name is: " + nameOnly.toUpperCase() + " and it has " + count + " letters");
}
scan.close();
}
I need a java program to find the second-longest word in a sentence (without using an array).
This is the code I have so far:
import java.io.*;
class Second_longest_Trial {
public static void main(String args[]) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the sentence");
String s = in .readLine();
s = s.trim() + " ";
String longest = s.substring(0, s.indexOf(' '));
String sec = longest;
int l = s.length();
String temp = " ", str = " ";
for (int i = s.indexOf(' ') + 1; i < l; i++) {
char ch = s.charAt(i);
if (ch != ' ')
temp = temp + ch;
else {
if (temp.length() > longest.length()) {
sec = longest;
longest = temp;
} else if (temp.length() > sec.length()) {
sec = temp;
}
temp = " ";
}
}
System.out.println("Longest word is " + longest);
System.out.println("Second Longest word is " + sec);
}
}
When I am giving the input-
Sayan goes home.
This outputs-
Longest word is Sayan
Second Longest word is Sayan
I should have got the output as follows-
Longest word is Sayan
Second Longest word is goes
Drop your wonky initial setting of longest and sec. Create them and temp the following way:
String longest="";
String sec="";
String temp="";
for(int i = 0; i < l; i++) {
...
Why would you set longest and sec both to the first word - guess what happens if that first word is the longest in the sentence?
Then your code produces the output:
Longest word is Sayan
Second Longest word is home.
That is more correct than what you currently have but still not what you would expect ... because there is the . at the end of the sentence you have to take care of - maybe make the check for ch!=' ' a bit more complex and check against '.' as well. I leave it for you to figure out how to do that correctly.
This is happening because you have initialized the longest element as first word and sec also as longest(which is Sayan itself). Now longest = "Sayan" and sec = "Sayan", you went inside the array but you never found any word which is bigger than longest or sec.
Here is a very basic code to find the second longest word:
class Second
{
public static void main(String str)//str has the required sentence
{
String m="",q="";
int lar=0;
str=str+" ";
for(int i=1;i<=2;i++)
{
for(int k=0;k<str.length();k++)
{
char ch=str.charAt(k);
if(ch!=' ')
m=m+ch;
else
{
if(m.length()>lar)
{
q=m;
lar=q.length();
}
m="";
}
}
if(i==1)
{
System.out.println("The longest word is: "+q);
str=str.replace(q," ");
lar=0;
}
}
System.out.println("The second longest word is: "+q);
}
}
I have a trouble with the for loop method that only loop 1 times whats is the problem? In the array was no problem at all, it able to print the value I want to.
here is my code:
public static void main(String[] args){
String s = "Apple0, Apple1, Apple2, Apple3, Apple4";
String[] word = s.split(",");
StringBuffer str = new StringBuffer();
Integer total = 0;
for (int y = 0; y < word.length; y++){
if(word[y].toString().equals("Apple2") ){
total++;
//str.append(word[y].toString());
}else if(word[y].toString().equals("Apple3") ){
total++;
//str.append(word[y].toString());
}else if(word[y].toString().equals("Apple4") ){
total++;
//str.append(word[y].toString());
}
else if(word[y].toString().equals("Apple1") ){
total++;
//str.append(word[y].toString());
}
}
System.out.println( word[0] + word[1] + word[2] + word[3] + word[4] + word.length);
System.out.println(str + "hihi" + total);
}
The others have nailed the cause of your problem. However, the fix they suggest is rather too specific ... and fragile. (Splitting with split("\\s*,\\s*") is better but it won't cope with whitespace at the start / end of the entire string.)
I suggest that you continue to use split(","), but trim the words before testing; e.g.
for (int y = 0; y < word.length; y++) {
String trimmed = word[y].trim();
if (trimmed.equals("Apple2")) {
total++;
//str.append(trimmed.toString());
} else if (trimmed.equals("Apple3")) {
// etcetera
or better still:
String[] words = s.split(",");
for (String word : words) {
String trimmed = word.trim();
if (trimmed.equals("Apple2")) {
total++;
//str.append(trimmed.toString());
} else if (trimmed.equals("Apple3")) {
// etcetera
That will make your code work irrespective of the whitespace characters around the commas and at the start and end of the string. Robustness is good, especially if it costs next to nothing to implement.
Finally, you could even replace the if / else if / ... stuff with a Java 7 String switch statement.
Try splitting on ", " (with space)
String[] word = s.split(", ");
without that space in split word[1] would look like " Apple1" instead "Apple1"
Other option would be calling word[y].trim().equals("Apple2") to get rid of that additional space, but I would say including it in split is better. If you aren't sure how many white-spaces can be near comma you can split this way split("\\s*,\\s*") to include all white-spaces around comma.
Also as Matt Ball pointed in his comment you don't need to call toString() on word[y] since it is already String.
you ignore the space during split. String[] word = s.split(", ");
You'are split by "," but your String contains ", ".
You can change the s.split(","); to s.split(", ");
Or trim the split's result like this :
public static void main(String[] args) {
String s = "Apple0, Apple1, Apple2, Apple3, Apple4";
String[] word = s.split(",");
StringBuffer str = new StringBuffer();
Integer total = 0;
for (int y = 0; y < word.length; y++) {
if (word[y].trim().equals("Apple2")) {
total++;
// str.append(word[y].toString());
} else if (word[y].trim().equals("Apple3")) {
total++;
// str.append(word[y].toString());
} else if (word[y].trim().equals("Apple4")) {
total++;
// str.append(word[y].toString());
} else if (word[y].trim().equals("Apple1")) {
total++;
// str.append(word[y].toString());
}
}
System.out.println(word[0] + word[1] + word[2] + word[3] + word[4]
+ word.length);
System.out.println(str + "hihi" + total);
}
There is nothing wrong with your code but the problem lies in the String that you are giving to the variable.
String s = "Apple0, Apple1, Apple2, Apple3, Apple4";
Here the string contains spaces between them after the comma. So that when you split your string it splits like
word[0]= "Apple0"
word[1]= " Apple1"
word[2]= " Apple2"
word[3]= " Apple3"
and so on.
So that when you compare like
word[y].equals("Apple1") it returns false because " Apple1" and "Apple1" are two different strings. So that initialize your string like this
String s = "Apple0,Apple1,Apple2,Apple3,Apple4"; // without white spaces
It will work fine. Or you can use trim method in your existing code without changing String like
word[y].trim().equals("Apple1") //It will trim all the leading and trailing white spaces.
Hope this helps.
I have to find the last word in a string and can't understand why my code isn't working. This is what I have:
int i, length;
String j, lastWord;
String word = "We the people of the United States in order to form a more perfect union";
length = word.length();
for (i = length - 1; i > 0; i--)
{
j = word.substring(i, i + 1);
if (j.equals(" ") == true);
{
lastWord = word.substring(i);
System.out.println("Last word: " + lastWord);
i = -1; //to stop the loop
}
}
However, when I run it, it prints the last letter. I know I could use
String lastWord = word.substring(word.lastIndexOf(" ") + 1)
But I'm pretty sure my teacher doesn't want me to do it this way. Any help?
You need to remove the ; after the if to make it work:
if (j.equals(" ")) // <== No semicolon, and no == true
{
lastWord = word.substring(i);
System.out.println("Last word: " + lastWord);
i = -1; //to stop the loop
}
You do not need == true for booleans inside control statements, either.
Finally, making single-character substrings is more expensive than using single characters. Consider using charAt(i) instead:
if (word.charAt(i) == ' ') // Single quotes mean one character
{
lastWord = word.substring(i+1);
System.out.println("Last word: " + lastWord);
break; // there is a better way to stop the loop
}
You've terminated the if statement. It should be,
if(j.equals(" "))
{
...
}
Just take that ; from if (j.equals(" ") == true); out.
Your code remade cleaner:
String word = "We the people of the United States in order to form a more perfect union";
for (int i = word.length() - 1; i > 0; i--)
if (word.charAt(i - 1) == ' ') {
System.out.println("Last word: " + word.substring(i));
break; // To stop the loop
}
Minimum iterations.
Convert the string to char array and look for space from the end of array. Don't forget to remove white spaces from the end using trim() as they could be counted as separate words.
s = s.trim();
char[] c = s.toCharArray();
for(int i=0; i<c.length; i++)
{
if(c[c.length-1-i]==' ')
{
return s.substring(c.length-1-i);
}
}
return s;
This also covers the null string case.
Another alternative using split.
s = s.trim();
String[] strs = new s.split(' ');
return str[str.length-1];
The semicolon after your "if" statement means "do nothing." Also, the "== true" is redundant. Lastly, you don't want to include the space you just found. Try this:
for (i = length - 1; i > 0; i--)
{
j = word.substring(i, i + 1);
if (j.equals(" "))
{
lastWord = word.substring(i + 1);
System.out.println("Last word: " + lastWord);
i = -1; //to stop the loop
}
}
There's a method for strings to split up at http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split%28java.lang.String%29
Splits this string around matches of the given regular expression.
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
A good, fast and easier way would be:
word = word.split(" ")[word.length-1];
split() returns an array of substrings based on " ". Since an array starts with 0, its last element is the length of the array - 1.