input: "Who lives in a pineapple under the sea?"
expected output: "Who sevil in a elppaenip rednu the sea?" (reverse size 5 and above words)
I think the if statement is the problem but I don't know why it's not working. I tried using the code from the if statement block inside the main method and it works fine.
public class Testing {
public static void main(String[] args) {
String sentence = "Who lives in a pineapple under the sea?";
System.out.println(spinWords(sentence));
}
public static String spinWords(String sentence) {
String[] words = sentence.split(" ");
int length = words.length;
String spinned = "";
for (int i = 0; i < length; i++) {
String word = words[i];
int wlength = word.length();
if (wlength > 4) {
String reversed = "";
for (i = wlength - 1; i >= 0; i--) {
reversed += "" + word.charAt(i);
}
spinned += reversed + " ";
} else {
spinned += word + " ";
}
}
spinned = spinned.trim();
return spinned;
}
}
This is my first stack overflow question btw and I don't really know what I'm doing.
I would also love to see better implementations of this code ( for learning purposes ), thanks.
Replace the "if" block with below code. You were using the variable "i" which is used by the first "for" loop. This caused the infinite loop.
if (wlength > 4) {
String reversed = "";
for(int j = 0; j < wlength; j++) {
reversed = word.charAt(j) + reversed;
}
spinned += reversed + " ";
} else {
spinned += word + " ";
}
The issue in your code is the duplicate use of the local variable i as others have pointed out. Typically you never want a nested loop counter to use the same variable name as the outer loop counter.
There is a reason why for (int i = wlength - 1; i >= 0; i--) is a compilation error (with the int declaration added). Instead simply use another variable name:
for (int j = wlength - 1; j >= 0; j--)
This will fix the error in the code. However, since you asked for other implementations I thought I would show another option using StringBuilder, which I believe is easier to read:
public static void main(String[] args) {
String sentence = "Who lives in a pineapple under the sea?";
System.out.println(spinWords(sentence));
}
public static String spinWords(String sentence) {
String[] words = sentence.split(" ");
StringBuilder sb = new StringBuilder();
for (String str : words) {
if (str.length() >= 5) {
sb.append(new StringBuilder(str).reverse());
} else {
sb.append(str);
}
sb.append(" ");
}
return sb.toString().trim();
}
StringBuilder is often used when concatenating a String inside of a loop, see this answer.
Additionally, StringBuilder has the reverse() method which you can use to reverse individual words instead of using a nested loop. You then just use toString to convert the StringBuilder object into a String.
Lastly, I used an enhanced for loop of for (String str : words) which allows you to loop directly on the String values instead of needing to use a loop counter.
Here's a one-liner:
public static String spinWords(String sentence) {
return Arrays.stream(sentence.split(" "))
.map(word -> word.length() < 5 ? word : new StringBuilder(word).reverse().toString())
.collect(Collectors.joining(" "));
}
See live demo.
Related
everyone. I have a task- reverse every word in a sentence as long as the word is 5 or more letters long. The program has been working with most words, but after a couple, the words are not included. Does anyone know why this is happening? Here is the code:
public static int wordCount(String str) {
int count = 0;
for(int i = 0; i < str.length(); i++) if(str.charAt(i) == ' ') count++;
return count + 1;
}
This just gets the word count for me, which I use in a for loop later to loop through all the words.
public static String reverseString(String s) {
Stack<Character> stack = new Stack<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
stack.push(s.charAt(i));
}
while (!stack.empty()) {
sb.append(stack.pop());
}
return sb.toString();
}
This reverses a single string. This is not where I reverse certain words- this reverses a string. "Borrowed" from https://stackoverflow.com/a/33458528/16818831.
Lastly, the actual function:
public static String spinWords(String sentence) {
String ans = "";
for(int i = 0; i <= wordCount(sentence); i++) {
if(sentence.substring(0, sentence.indexOf(' ')).length() >= 5) {
ans += reverseString(sentence.substring(0, sentence.indexOf(' '))) + " ";
sentence = sentence.substring(sentence.indexOf(' ') + 1);
} else {
ans += sentence.substring(0, sentence.indexOf(' ')) + " ";
sentence = sentence.substring(sentence.indexOf(' ') + 1);
}
}
return ans;
}
This is where my mistake probably is. I'd like to know why some words are omitted. Just in case, here is my main method:
public static void main(String[] args) {
System.out.println(spinWords("Why, hello there!"));
System.out.println(spinWords("The weather is mighty fine today!"));
}
Let me know why this happens. Thank you!
The main issue would appear to be the for loop condition in spinWords()
The word count of your sentence keeps getting shorter while at the same time, i increases.
For example:
i is 0 when the word count is 5
i is 1 when the word count is 4
i is 2 when the word count is 3
i is 3 when the word count is 2 which
stops the loop.
It can't get through the whole sentence.
As many have mentioned, using the split method would help greatly, for example:
public static String spinWords(String sentence) {
return Arrays.asList(sentence.split(" ")).stream()
.map(word -> word.length() < 5 ? word : new StringBuilder(word).reverse().toString())
.collect(Collectors.joining(" "));
}
I think you should rewrite a lot of your code using String.split(). Instead of manually parsing every letter, you can get an array of every word just by writing String[] arr = sentence.split(" "). You can then use a for loop to go through and reverse each word something like this
for (int i=0; i<arr.length; i++) {
if (arr[i] >= 5) {
arr[i] = reverse(arr[i])
}
}
I know you just asked for a solution to your current code, but this would probably get you a better grade :)
I'm having trouble printing off all vowel combinations of a given input. My input is "SOMETHING" and I would like to print off all vowel combinations such as sxmxthxng where x is aeiou vowels. I believe my problem is that I find a vowel, change it with all the others vowels and move on. I need to continue down the rest of the word and find additional vowels and change those before proceeding.
Other refs
vowelList is an ArrayList containing all lower case vowels.
Code
private static void createVowelCombos(String word) {
Set<String> rmRepeats = new HashSet<>();
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
for (int i = 0; i < word.length(); i++) {
// System.out.println("real word: " + splitWord[i]);
if (splitWord[i].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(i, vowelList.get(j).charAt(0));
System.out.println(sbAddWord.toString());
}
}
}
}
Sample Output with input "SOMETHING"
samething
semething
simething
something
sumething
sumathing
sumething
sumithing
sumothing
sumuthing
sumuthang
sumutheng
sumuthing
sumuthong
sumuthung
For some reason it is giving me all the combinations with 'u' but not the other vowels. I would like to get all the results for the other vowels as well.
as already suggested your problem can be best solved by using recursion (with backtracking). I've modified your code so as to print the required output. Have a look !!
private static void createVowelCombos(String word, int start) {
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
if(start==splitWord.length)
{
System.out.println(word);
return;
}
if (splitWord[start].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(start, vowelList.get(j).charAt(0));
createVowelCombos(sbAddWord.toString(),start+1);
//System.out.println(sbAddWord.toString());
}
}
else
createVowelCombos(sbAddWord.toString(),start+1);
}
Call createVowelCombos("something",0) from the calling method.
I've been really struggling with a programming assignment. Basically, we have to write a program that translates a sentence in English into one in Pig Latin. The first method we need is one to tokenize the string, and we are not allowed to use the Split method usually used in Java. I've been trying to do this for the past 2 days with no luck, here is what I have so far:
public class PigLatin
{
public static void main(String[] args)
{
String s = "Hello there my name is John";
Tokenize(s);
}
public static String[] Tokenize(String english)
{
String[] tokenized = new String[english.length()];
for (int i = 0; i < english.length(); i++)
{
int j= 0;
while (english.charAt(i) != ' ')
{
String m = "";
m = m + english.charAt(i);
if (english.charAt(i) == ' ')
{
j++;
}
else
{
break;
}
}
for (int l = 0; l < tokenized.length; l++) {
System.out.print(tokenized[l] + ", ");
}
}
return tokenized;
}
}
All this does is print an enormously long array of "null"s. If anyone can offer any input at all, I would reallllyyyy appreciate it!
Thank you in advance
Update: We are supposed to assume that there will be no punctuation or extra spaces, so basically whenever there is a space, it's a new word
If I understand your question, and what your Tokenize was intended to do; then I would start by writing a function to split the String
static String[] splitOnWhiteSpace(String str) {
List<String> al = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (char ch : str.toCharArray()) {
if (Character.isWhitespace(ch)) {
if (sb.length() > 0) {
al.add(sb.toString());
sb.setLength(0);
}
} else {
sb.append(ch);
}
}
if (sb.length() > 0) {
al.add(sb.toString());
}
String[] ret = new String[al.size()];
return al.toArray(ret);
}
and then print using Arrays.toString(Object[]) like
public static void main(String[] args) {
String s = "Hello there my name is John";
String[] words = splitOnWhiteSpace(s);
System.out.println(Arrays.toString(words));
}
If you're allowed to use the StringTokenizer Object (which I think is what the assignment is asking, it would look something like this:
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
which will produce the output:
this
is
a
test
Taken from here.
The string is split into tokens and stored in a stack. The while loop loops through the tokens, which is where you can apply the pig latin logic.
Some hints for you to do the "manual splitting" work.
There is a method String#indexOf(int ch, int fromIndex) to help you to find next occurrence of a character
There is a method String#substring(int beginIndex, int endIndex) to extract certain part of a string.
Here is some pseudo-code that show you how to split it (there are more safety handling that you need, I will leave that to you)
List<String> results = ...;
int startIndex = 0;
int endIndex = 0;
while (startIndex < inputString.length) {
endIndex = get next index of space after startIndex
if no space found {
endIndex = inputString.length
}
String result = get substring of inputString from startIndex to endIndex-1
results.add(result)
startIndex = endIndex + 1 // move startIndex to next position after space
}
// here, results contains all splitted words
String english = "hello my fellow friend"
ArrayList tokenized = new ArrayList<String>();
String m = "";
int j = 0; //index for tokenised array list.
for (int i = 0; i < english.length(); i++)
{
//the condition's position do matter here, if you
//change them, english.charAt(i) will give index
//out of bounds exception
while( i < english.length() && english.charAt(i) != ' ')
{
m = m + english.charAt(i);
i++;
}
//add to array list if there is some string
//if its only ' ', array will be empty so we are OK.
if(m.length() > 0 )
{
tokenized.add(m);
j++;
m = "";
}
}
//print the array list
for (int l = 0; l < tokenized.size(); l++) {
System.out.print(tokenized.get(l) + ", ");
}
This prints, "hello,my,fellow,friend,"
I used an array list since at the first sight the length of the array is not clear.
This code is inside the main function:
Scanner input = new Scanner(System.in);
System.out.println("Type a sentence");
String sentence = input.next();
Stack<Character> stk = new Stack<Character>();
int i = 0;
while (i < sentence.length())
{
while (sentence.charAt(i) != ' ' && i < sentence.length() - 1)
{
stk.push(sentence.charAt(i));
i++;
}
stk.empty();
i++;
}
And this is the empty() function:
public void empty()
{
while (this.first != null)
System.out.print(this.pop());
}
It doesn't work properly, as by typing example sentence I am getting this output: lpmaxe. The first letter is missing and the loop stops instead of counting past the space to the next part of the sentence.
I am trying to achieve this:
This is a sentence ---> sihT si a ecnetnes
Per modifications to the original post, where the OP is now indicating that his goal is to reverse the letter order of the words within a sentence, but to leave the words in their initial positions.
The simplest way to do this, I think, is to make use of the String split function, iterate through the words, and reverse their orders.
String[] words = sentence.split(" "); // splits on the space between words
for (int i = 0; i < words.length; i++) {
String word = words[i];
System.out.print(reverseWord(word));
if (i < words.length-1) {
System.out.print(" "); // space after all words but the last
}
}
Where the method reverseWord is defined as:
public String reverseWord(String word) {
for( int i = 0; i < word.length(); i++) {
stk.push(word.charAt(i));
}
return stk.empty();
}
And where the empty method has been changed to:
public String empty() {
String stackWord = "";
while (this.first != null)
stackWord += this.pop();
return stackWord;
}
Original response
The original question indicated that the OP wanted to completely reverse the sentence.
You've got a double-looping construct where you don't really need it.
Consider this logic:
Read each character from the input string and push that character to the stack
When the input string is empty, pop each character from the stack and print it to screen.
So:
for( int i = 0; i < sentence.length(); i++) {
stk.push(sentence.charAt(i));
}
stk.empty();
I assume that what you want your code to do is to reverse each word in turn, not the entire string. So, given the input example sentence you want it to output elpmaxe ecnetnes not ecnetnes elpmaxe.
The reason that you see lpmaxe instead of elpmaxe is because your inner while-loop doesn't process the last character of the string since you have i < sentence.length() - 1 instead of i < sentence.length(). The reason that you only see a single word is because your sentence variable consists only of the first token of the input. This is what the method Scanner.next() does; it reads the next (by default) space-delimited token.
If you want to input a whole sentence, wrap up System.in as follows:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
and call reader.readLine().
Hope this helps.
Assuming you've already got your input in sentence and the Stack object is called stk, here's an idea:
char[] tokens = sentence.toCharArray();
for (char c : tokens) {
if (c == ' ') {
stk.empty();
System.out.print(c);
} else {
stk.add(c);
}
}
Thus, it will scan through one character at a time. If we hit a space character, we'll assume we've hit the end of a word, spit out that word in reverse, print that space character, then continue. Otherwise, we'll add the character to the stack and continue building the current word. (If you want to also allow punctuation like periods, commas, and the like, change if (c == ' ') { to something like if (c == ' ' || c == '.' || c == ',') { and so on.)
As for why you're only getting one word, darrenp already pointed it out. (Personally, I'd use a Scanner instead of a BufferedReader unless speed is an issue, but that's just my opinion.)
import java.util.StringTokenizer;
public class stringWork {
public static void main(String[] args) {
String s1 = "Hello World";
s1 = reverseSentence(s1);
System.out.println(s1);
s1 = reverseWord(s1);
System.out.println(s1);
}
private static String reverseSentence(String s1){
String s2 = "";
for(int i=s1.length()-1;i>=0;i--){
s2 += s1.charAt(i);
}
return s2;
}
private static String reverseWord(String s1){
String s2 = "";
StringTokenizer st = new StringTokenizer(s1);
while (st.hasMoreTokens()) {
s2 += reverseSentence(st.nextToken());
s2 += " ";
}
return s2;
}
}
public class ReverseofeachWordinaSentance {
/**
* #param args
*/
public static void main(String[] args) {
String source = "Welcome to the word reversing program";
for (String str : source.split(" ")) {
System.out.print(new StringBuilder(str).reverse().toString());
System.out.print(" ");
}
System.out.println("");
System.out.println("------------------------------------ ");
String original = "Welcome to the word reversing program";
wordReverse(original);
System.out.println("Orginal Sentence :::: "+original);
System.out.println("Reverse Sentence :::: "+wordReverse(original));
}
public static String wordReverse(String original){
StringTokenizer string = new StringTokenizer(original);
Stack<Character> charStack = new Stack<Character>();
while (string.hasMoreTokens()){
String temp = string.nextToken();
for (int i = 0; i < temp.length(); i ++){
charStack.push(temp.charAt(i));
}
charStack.push(' ');
}
StringBuilder result = new StringBuilder();
while(!charStack.empty()){
result.append(charStack.pop());
}
return result.toString();
}
}
public class reverseStr {
public static void main(String[] args) {
String testsa[] = { "", " ", " ", "a ", " a", " aa bd cs " };
for (String tests : testsa) {
System.out.println(tests + "|" + reverseWords2(tests) + "|");
}
}
public static String reverseWords2(String s) {
String[] sa;
String out = "";
sa = s.split(" ");
for (int i = 0; i < sa.length; i++) {
String word = sa[sa.length - 1 - i];
// exclude "" in splited array
if (!word.equals("")) {
//add space between two words
out += word + " ";
}
}
//exclude the last space and return when string is void
int n = out.length();
if (n > 0) {
return out.substring(0, out.length() - 1);
} else {
return "";
}
}
}
This can pass in leetcode
I need to count the number of spaces in my string but my code gives me a wrong number when i run it, what is wrong?
int count=0;
String arr[]=s.split("\t");
OOPHelper.println("Number of spaces are: "+arr.length);
count++;
s.length() - s.replaceAll(" ", "").length() returns you number of spaces.
There are more ways. For example"
int spaceCount = 0;
for (char c : str.toCharArray()) {
if (c == ' ') {
spaceCount++;
}
}
etc., etc.
In your case you tried to split string using \t - TAB. You will get right result if you use " " instead. Using \s may be confusing since it matches all whitepsaces - regular spaces and TABs.
Here is a different way of looking at it, and it's a simple one-liner:
int spaces = s.replaceAll("[^ ]", "").length();
This works by effectively removing all non-spaces then taking the length of what’s left (the spaces).
You might want to add a null check:
int spaces = s == null ? 0 : s.replaceAll("[^ ]", "").length();
Java 8 update
You can use a stream too:
long spaces = s.chars().filter(c -> c == (int)' ').count();
Fastest way to do this would be:
int count = 0;
for(int i = 0; i < str.length(); i++) {
if(Character.isWhitespace(str.charAt(i))) count++;
}
This would catch all characters that are considered whitespace.
Regex solutions require compiling regex and excecuting it - with a lot of overhead. Getting character array requires allocation. Iterating over byte array would be faster, but only if you are sure that your characters are ASCII.
\t will match tabs, rather than spaces and should also be referred to with a double slash: \\t. You could call s.split( " " ) but that wouldn't count consecutive spaces. By that I mean...
String bar = " ba jfjf jjj j ";
String[] split = bar.split( " " );
System.out.println( split.length ); // Returns 5
So, despite the fact there are seven space characters, there are only five blocks of space. It depends which you're trying to count, I guess.
Commons Lang is your friend for this one.
int count = StringUtils.countMatches( inputString, " " );
If you use Java 8, the following should work:
long count = "0 1 2 3 4.".chars().filter(Character::isWhitespace).count();
This will also work in Java 8 using Eclipse Collections:
int count = Strings.asChars("0 1 2 3 4.").count(Character::isWhitespace);
Note: I am a committer for Eclipse Collections.
Your code will count the number of tabs and not the number of spaces. Also, the number of tabs will be one less than arr.length.
Another way using regular expressions
int length = text.replaceAll("[^ ]", "").length();
The code you provided would print the number of tabs, not the number of spaces. The below function should count the number of whitespace characters in a given string.
int countSpaces(String string) {
int spaces = 0;
for(int i = 0; i < string.length(); i++) {
spaces += (Character.isWhitespace(string.charAt(i))) ? 1 : 0;
}
return spaces;
}
A solution using java.util.regex.Pattern / java.util.regex.Matcher
String test = "foo bar baz ";
Pattern pattern = Pattern.compile(" ");
Matcher matcher = pattern.matcher(test);
int count = 0;
while (matcher.find()) {
count++;
}
System.out.println(count);
please check the following code, it can help
public class CountSpace {
public static void main(String[] args) {
String word = "S N PRASAD RAO";
String data[];int k=0;
data=word.split("");
for(int i=0;i<data.length;i++){
if(data[i].equals(" ")){
k++;
}
}
System.out.println(k);
}
}
The simple and fastest way to count spaces
String fav="foo hello me hi";
for( int i=0; i<fav.length(); i++ ) {
if(fav.charAt(i) == ' ' ) {
counter++;
}
}
I just had to do something similar to this and this is what I used:
String string = stringValue;
String[] stringArray = string.split("\\s+");
int length = stringArray.length;
System.out.println("The number of parts is: " + length);
public static void main(String[] args) {
String str = "Honey dfd tEch Solution";
String[] arr = str.split(" ");
System.out.println(arr.length);
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (!arr[i].trim().isEmpty()) {
System.out.println(arr[i]);
count++;
}
}
System.out.println(count);
}
public static void main(String[] args) {
Scanner input= new Scanner(System.in);`
String data=input.nextLine();
int cnt=0;
System.out.println(data);
for(int i=0;i<data.length()-1;i++)
{if(data.charAt(i)==' ')
{
cnt++;
}
}
System.out.println("Total number of Spaces in a given String are " +cnt);
}
This program will definitely help you.
class SpaceCount
{
public static int spaceCount(String s)
{ int a=0;
char ch[]= new char[s.length()];
for(int i = 0; i < s.length(); i++)
{ ch[i]= s.charAt(i);
if( ch[i]==' ' )
a++;
}
return a;
}
public static void main(String... s)
{
int m = spaceCount("Hello I am a Java Developer");
System.out.println("The number of words in the String are : "+m);
}
}
The most precise and exact plus fastest way to that is :
String Name="Infinity War is a good movie";
int count =0;
for(int i=0;i<Name.length();i++){
if(Character.isWhitespace(Name.charAt(i))){
count+=1;
}
}
System.out.println(count);
import java.util.Scanner;
import java.io.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in).useDelimiter("\n");
String str = sc.next();
int spaceCount=0;
str = str.toLowerCase();
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i)==' '){
spaceCount++;
}
}
System.out.println("Number of spaces: "+ spaceCount);
}
}