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.
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 want to make a program that prints the number of words that START with an uppercase letter. So I made two strings str1 = "The deed is done" and str2 = "My name is Bond, JAMES Bond". For the first string, it printed 1 which is what I wanted. But for the second one it prints 8 instead of 4 because JAMES is capitalized.
public static void main(String[] args){
String str1 = "The deed is done";
String str2 = "My name is Bond, JAMES Bond";
System.out.println(uppercase(str2));
}
public static int uppercase(String str){
int cnt = 0;
for(int i = 0; i < str.length(); i++){
if(Character.isUpperCase(str.charAt(i)))
cnt++;
}
return cnt;
}
That's what I have so far. How would I make it so that the other letters in that word aren't counted?
You should check the first character of each word in the input string, instead of all characters of the input string.
public static int uppercase(String str){
int cnt = 0;
String[] words = str.split(" ");
for(int i = 0; i < words.length; i++){
if(Character.isUpperCase(words[i].charAt(0)))
cnt++;
}
return cnt;
}
A more 'declarative approach' could use a Stream
public static long uppercase2(String str){
return Arrays.stream(str.split(" "))
.map(word -> word.charAt(0))
.filter(Character::isUpperCase)
.count();
}
String str1 = "The deed is done";
String str2 = "My name is Bond, JAMES Bond";
System.out.println(upperCaseCount(str1));
System.out.println(upperCaseCount(str2));
public static int upperCaseCount(String s) {
int count = 0;
// append a space to cater for empty string and
// use regex to split on one or more spaces.
for (String word : (s + " ").split("\\s+")) {
if (Character.isUpperCase(word.charAt(0))) {
count++;
}
}
return count;
}
A nice way to do this is with a regex: \b[A-Z] tests for capital letters occurring after a word boundary, so we can just find all matches and count them.
> import java.util.regex.*;
> Pattern p = Pattern.compile("\\b[A-Z]");
> Matcher m = p.matcher("Hi, this is Stack Overflow.");
> int c = 0;
> while(m.find()) { c++; }
> c
3
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.
I am trying to make a program on word count which I have partially made and it is giving the correct result but the moment I enter space or more than one space in the string, the result of word count show wrong results because I am counting words on the basis of spaces used. I need help if there is a solution in a way that no matter how many spaces are I still get the correct result. I am mentioning the code below.
public class CountWords
{
public static void main (String[] args)
{
System.out.println("Simple Java Word Count Program");
String str1 = "Today is Holdiay Day";
int wordCount = 1;
for (int i = 0; i < str1.length(); i++)
{
if (str1.charAt(i) == ' ')
{
wordCount++;
}
}
System.out.println("Word count is = " + wordCount);
}
}
public static void main (String[] args) {
System.out.println("Simple Java Word Count Program");
String str1 = "Today is Holdiay Day";
String[] wordArray = str1.trim().split("\\s+");
int wordCount = wordArray.length;
System.out.println("Word count is = " + wordCount);
}
The ideas is to split the string into words on any whitespace character occurring any number of times.
The split function of the String class returns an array containing the words as its elements.
Printing the length of the array would yield the number of words in the string.
Two routes for this. One way would be to use regular expressions. You can find out more about regular expressions here. A good regular expression for this would be something like "\w+" Then count the number of matches.
If you don't want to go that route, you could have a boolean flag that remembers if the last character you've seen is a space. If it is, don't count it. So the center of the loop looks like this:
boolean prevCharWasSpace=true;
for (int i = 0; i < str1.length(); i++)
{
if (str1.charAt(i) == ' ') {
prevCharWasSpace=true;
}
else{
if(prevCharWasSpace) wordChar++;
prevCharWasSpace = false;
}
}
Update
Using the split technique is exactly equivalent to what's happening here, but it doesn't really explain why it works. If we go back to our CS theory, we want to construct a Finite State Automa (FSA) that counts words. That FSA may appear as:
If you look at the code, it implements this FSA exactly. The prevCharWasSpace keeps track of which state we're in, and the str1.charAt('i') is decideds which edge (or arrow) is being followed. If you use the split method, a regular expression equivalent of this FSA is constructed internally, and is used to split the string into an array.
Java does have StringTokenizer API and can be used for this purpose as below.
String test = "This is a test app";
int countOfTokens = new StringTokenizer(test).countTokens();
System.out.println(countOfTokens);
OR
in a single line as below
System.out.println(new StringTokenizer("This is a test app").countTokens());
StringTokenizer supports multiple spaces in the input string, counting only the words trimming unnecessary spaces.
System.out.println(new StringTokenizer("This is a test app").countTokens());
Above line also prints 5
You can use String.split (read more here) instead of charAt, you will get good results.
If you want to use charAt for some reason then try trimming the string before you count the words that way you won't have the extra space and an extra word
My implementation, not using StringTokenizer:
Map<String, Long> getWordCounts(List<String> sentences, int maxLength) {
Map<String, Long> commonWordsInEventDescriptions = sentences
.parallelStream()
.map(sentence -> sentence.replace(".", ""))
.map(string -> string.split(" "))
.flatMap(Arrays::stream)
.map(s -> s.toLowerCase())
.filter(word -> word.length() >= 2 && word.length() <= maxLength)
.collect(groupingBy(Function.identity(), counting()));
}
Then, you could call it like this, as an example:
getWordCounts(list, 9).entrySet().stream()
.filter(pair -> pair.getValue() <= 3 && pair.getValue() >= 1)
.findFirst()
.orElseThrow(() ->
new RuntimeException("No matching word found.")).getKey();
Perhaps flipping the method to return Map<Long, String> might be better.
Use split(regex) method. The result is an array of strings that was splited by regex.
String s = "Today is Holdiay Day";
System.out.println("Word count is = " + s.split(" ").length);
You need to read the file line by line and reduce the multiple occurences of the whitespaces appearing in your line to a single occurence and then count for the words. Following is a sample:
public static void main(String... args) throws IOException {
FileInputStream fstream = new FileInputStream("c:\\test.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
int wordcount = 0;
while ((strLine = br.readLine()) != null) {
strLine = strLine.replaceAll("[\t\b]", "");
strLine = strLine.replaceAll(" {2,}", " ");
if (!strLine.isEmpty()){
wordcount = wordcount + strLine.split(" ").length;
}
}
System.out.println(wordcount);
in.close();
}
public class wordCOunt
{
public static void main(String ar[])
{
System.out.println("Simple Java Word Count Program");
String str1 = "Today is Holdiay Day";
int wordCount = 1;
for (int i = 0; i < str1.length(); i++)
{
if (str1.charAt(i) == ' '&& str1.charAt(i+1)!=' ')
{
wordCount++;
}
}
System.out.println("Word count is = " +(str1.length()- wordCount));
}
}
public class wordCount
{
public static void main(String ar[]) throws Exception
{
System.out.println("Simple Java Word Count Program");
int wordCount = 1,count=1;
BufferedReader br = new BufferedReader(new FileReader("C:/file.txt"));
String str2 = "", str1 = "";
while ((str1 = br.readLine()) != null) {
str2 += str1;
}
for (int i = 0; i < str2.length(); i++)
{
if (str2.charAt(i) == ' ' && str2.charAt(i+1)!=' ')
{
wordCount++;
}
}
System.out.println("Word count is = " +(wordCount));
}
}
you should make your code more generic by considering other word separators as well.. such as "," ";" etc.
public class WordCounter{
public int count(String input){
int count =0;
boolean incrementCounter = false;
for (int i=0; i<input.length(); i++){
if (isValidWordCharacter(input.charAt(i))){
incrementCounter = true;
}else if (incrementCounter){
count++;
incrementCounter = false;
}
}
if (incrementCounter) count ++;//if string ends with a valid word
return count;
}
private boolean isValidWordCharacter(char c){
//any logic that will help you identify a valid character in a word
// you could also have a method which identifies word separators instead of this
return (c >= 'A' && c<='Z') || (c >= 'a' && c<='z');
}
}
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multiset;
String str="Simple Java Word Count count Count Program";
Iterable<String> words = Splitter.on(" ").trimResults().split(str);
//google word counter
Multiset<String> wordsMultiset = HashMultiset.create();
for (String string : words) {
wordsMultiset.add(string.toLowerCase());
}
Set<String> result = wordsMultiset.elementSet();
for (String string : result) {
System.out.println(string+" X "+wordsMultiset.count(string));
}
public static int CountWords(String str){
if(str.length() == 0)
return 0;
int count =0;
for(int i=0;i< str.length();i++){
if(str(i) == ' ')
continue;
if(i > 0 && str.charAt(i-1) == ' '){
count++;
}
else if(i==0 && str.charAt(i) != ' '){
count++;
}
}
return count;
}
public class CountWords
{
public static void main (String[] args)
{
System.out.println("Simple Java Word Count Program");
String str1 = "Today is Holdiay Day";
int wordCount = 1;
for (int i = 0; i < str1.length(); i++)
{
if (str1.charAt(i) == ' ' && str1.charAt(i+1)!=' ')
{
wordCount++;
}
}
System.out.println("Word count is = " + wordCount));
}
}
This gives the correct result because if space comes twice or more then it can't increase wordcount. Enjoy.
try this
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class wordcount {
public static void main(String[] args) {
String s = "India is my country. I love India";
List<String> qw = new ArrayList<String>();
Map<String, Integer> mmm = new HashMap<String, Integer>();
for (String sp : s.split(" ")) {
qw.add(sp);
}
for (String num : qw) {
mmm.put(num, Collections.frequency(qw, num));
}
System.out.println(mmm);
}
}
To count total words Or to count total words without repeat word count
public static void main(String[] args) {
// TODO Auto-generated method stub
String test = "I am trying to make make make";
Pattern p = Pattern.compile("\\w+");
Matcher m = p.matcher(test);
HashSet<String> hs = new HashSet<>();
int i=0;
while (m.find()) {
i++;
hs.add(m.group());
}
System.out.println("Total words Count==" + i);
System.out.println("Count without Repetation ==" + hs.size());
}
}
Output :
Total words Count==7
Count without Repeatation ==5
Not sure if there is a drawback, but this worked for me...
Scanner input = new Scanner(System.in);
String userInput = input.nextLine();
String trimmed = userInput.trim();
int count = 1;
for (int i = 0; i < trimmed.length(); i++) {
if ((trimmed.charAt(i) == ' ') && (trimmed.charAt(i-1) != ' ')) {
count++;
}
}
You can use this code.It may help you:
public static void main (String[] args)
{
System.out.println("Simple Java Word Count Program");
String str1 = "Today is Holdiay Day";
int count=0;
String[] wCount=str1.split(" ");
for(int i=0;i<wCount.length;i++){
if(!wCount[i].isEmpty())
{
count++;
}
}
System.out.println(count);
}
String data = "This world is mine";
System.out.print(data.split("\\s+").length);
This could be as simple as using split and count variable.
public class SplitString {
public static void main(String[] args) {
int count=0;
String s1="Hi i love to code";
for(String s:s1.split(" "))
{
count++;
}
System.out.println(count);
}
}
public class TotalWordsInSentence {
public static void main(String[] args) {
String str = "This is sample sentence";
int NoOfWOrds = 1;
for (int i = 0; i<str.length();i++){
if ((str.charAt(i) == ' ') && (i!=0) && (str.charAt(i-1) != ' ')){
NoOfWOrds++;
}
}
System.out.println("Number of Words in Sentence: " + NoOfWOrds);
}
}
In this code, There wont be any problem regarding white-space in it.
just the simple for loop. Hope this helps...
To count specified words only like John, John99, John_John and John's only. Change regex according to yourself and count the specified words only.
public static int wordCount(String content) {
int count = 0;
String regex = "([a-zA-Z_’][0-9]*)+[\\s]*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
while(matcher.find()) {
count++;
System.out.println(matcher.group().trim()); //If want to display the matched words
}
return count;
}
class HelloWorld {
public static void main(String[] args) {
String str = "User is in for an interview";
int counter=0;
String arrStr[] = str.split(" ");
for (int i = 0; i< arrStr.length; i++){
String charStr = arrStr[i];
for(int j=0; j<charStr.length(); j++) {
if(charStr.charAt(j) =='i') {
counter++;
}
}
}
System.out.println("i " + counter);
}
}
public class CountWords {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the string :");
String str = sc.nextLine();
System.out.println("length is string is :"+str.length());
int worldCount = 1;
for(int i=0; i<str.length(); i++){
if(str.charAt(i) == ' '){
worldCount++;
}
}
System.out.println(worldCount);
}
}
The full program working is:
public class main {
public static void main(String[] args) {
logicCounter counter1 = new logicCounter();
counter1.counter("I am trying to make a program on word count which I have partially made and it is giving the correct result but the moment I enter space or more than one space in the string, the result of word count show wrong results because I am counting words on the basis of spaces used. I need help if there is a solution in a way that no matter how many spaces are I still get the correct result. I am mentioning the code below.");
}
}
public class logicCounter {
public void counter (String str) {
String str1 = str;
boolean space= true;
int i;
for ( i = 0; i < str1.length(); i++) {
if (str1.charAt(i) == ' ') {
space=true;
} else {
i++;
}
}
System.out.println("there are " + i + " letters");
}
}