Hello I am currently working on a program that reverses sentences using stacks. However, I need to implement a function that detects periods and then repeats the loop over again. For example, I could write "Hello my name is blank. nice to meet you." and it would print "you. meet to nice blank. is name my Hello" when I actually just need it to reverse each sentence individually, if that makes sense. So "blank is name my Hello. you meet to nice." is my desired output. Any advice would help greatly, thank you!
import java.util.Stack;
import java.util.Scanner;
public class NolascoStackReverse {
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
Stack<String> reverse = new Stack<String>();
System.out.println("Enter a sentence to be reversed: ");
String str = in.nextLine();
String[] wordsArray = str.split(" ");
for (String word : wordsArray) {
reverse.push(word);
}
System.out.println("Here is the reversed order: ");
while (reverse.empty() == false) {
System.out.print(reverse.pop() + " ");
}
}
}
Below code splits your string with space char. You need to split it with period first and split each sentence with space.
String[] wordsArray = str.split(" ");
If you dont care for period, then you can use multiple delimiters for split function :Use String.split() with multiple delimiters
If you need period in reversed sentence, you can use below code:
String[] sentenceArray = str.split(("\\."));
for (String sentence : sentenceArray){
String[] wordsArray = sentence.split((" "));
for (String word : wordsArray) {
reverse.push(word);
}
reverse.push(".");
}
There is already an API available in Java for processing text. You can use BreakIterator like this:
public class Test {
public static void main(String[] args) throws Exception {
Stack<String> reverse = new Stack<String>();
String result="";
Locale enUS = new Locale("en","US");
String str = "My name is R.R.Martin. Nice to meet you.";
System.out.println("Text: " + str);
System.out.print("Here is the reversed order: ");
List<String> sentences = getPieces(str, BreakIterator.getSentenceInstance(enUS));
for(String s : sentences) {
s = s.substring(0,s.length()-1);
List<String> words = getPieces(s, BreakIterator.getWordInstance(enUS));
reverse.clear();
for (String w : words) {
reverse.push(w.strip());
}
while (reverse.empty() == false) {
result += reverse.pop() + " ";
}
result = result.strip();
result += result.length()>0? ". ":"";
}
System.out.println(result);
}
public static List<String> getPieces(String text, BreakIterator bi) {
int boundary,start;
String piece = "";
List<String> list = new ArrayList<>();
bi.setText(text);
boundary = bi.first();
start = 0;
while (boundary != BreakIterator.DONE) {
if(boundary>0)
piece = text.substring(start,boundary);
start = boundary;
boundary = bi.next();
if(!piece.strip().isBlank())
list.add(piece.strip());
}
return list;
}
}
Output:
Text: My name is R.R.Martin. Nice to meet you.
Here is the reversed order: R.R.Martin is name My. you meet to Nice.
Advantage of this approach is that it is locale sensitive i.e. you can use the code with other languages.
Related
I am new to Java and looking for code optimization techniques. This code is giving the expected output using two for loops and I want to reduce/eliminate the loops (if possible).
public static void main(String[] args) {
String dummy = "Hello how are you";
String[] strArr = dummy.split(" ");
for(int i=0; i < strArr.length;i++){
String word = strArr[i];
for(int j=word.length(); j > 0; j--){
System.out.print(word.charAt(j - 1));
}
System.out.print(" ");
}
}
Output: olleH woh era uoy
Please advice.
Since the complexity of printing the output would remain the same, all you can do is to "hide" the loops into existing methods that do what you want, not eliminate them, because the amount of work the system needs to perform remains the same in terms of the number of characters that need to be processed.
You can hide the nested loop by using string reversal technique described in this Q&A. The outer loop can be pushed into String.join:
String[] data = {"quick", "brown", "fox"};
System.out.println(
String.join(
" "
, Arrays.stream(data)
.map(s -> new StringBuilder(s).reverse().toString())
.toArray(String[]::new)
)
);
Demo.
As I stated in my comment the complexity is already O(n) and you cannot get better because you need to read the input string. Anyway, there is a way to "unnest" the two for loops: reverse the whole string, split on spaces, and reverse the resulting array.
Example:
"Hello how are you"
"uoy era woh olleH"
"uoy" "era" "woh" "olleH"
"olleH" "woh" "era" "uoy"
Code:
public static void main(String[] args) {
String dummy = "Hello how are you";
int n = dummy.length();
StringBuilder sb = new StringBuilder(n);
while (--n >= 0) sb.append(dummy.charAt(n));
String[] tokens = sb.toString().split(" ");
n = tokens.length;
while (--n >= 0) System.out.print(tokens[n] + " ");
}
Instead, if you are after cools java 8 Stream tricks, read dasblinkenlight's answer.
This is another simple solution using StringTokenizer.
It takes only O(n).
public static void main(String[] args) {
System.out.println(reverseStringWordByWord("Hello How are you"));
}
public static String reverseStringWordByWord(String input) {
StringBuilder result = new StringBuilder();
StringTokenizer sToken = new StringTokenizer(input, " ");
while (sToken.hasMoreTokens()) {
StringBuilder thisToken = new StringBuilder(sToken.nextToken());
result.append(thisToken.reverse() + " ");
}
return result.toString();
}
I have been stuck on this problem for a few days. I want to be able to check and count if each word from uniqueBagOfWords appears in a sentence for example,
UniqueBagOfWords = [i, like, to, play, tennis, think, football, needs, big, changes]
output would be-
Sentence - i like to play tennis = 1,1,1,1,0,0,0,0,0
sentence - i like football like = 1,2,0,0,0,0,1,0,0,0
public static void main(String[] args) {
List<String> sentences = new ArrayList<String>();
sentences.add("i like to play tennis");
sentences.add("i think football needs big changes");
sentences.add("i like football like");
List<String[]> bagOfWords = new ArrayList<String[]>();
for(String str : sentences){
bagOfWords.add(str.split(" "));
}
Set<String> uniqueBagOfWords = new LinkedHashSet<String>();
for(String[] s : bagOfWords){
for(String ss : s)
for(String st : ss.split(" "))
if(!uniqueBagOfWords.contains(st))
uniqueBagOfWords.add(st);
}
I have tried this, I know its not right but can't work out where to go from here. Any help would be great!
for(String s : sentences){
for(String ss : s.split(" ")){
int count= 0;
for(int loop=0; loop <uniqueBagOfWords.size(); loop++){
if(uniqueBagOfWords.contains(ss)){
count +=1;
}
}
System.out.println(ss +" "+ count);
I think an array is the wrong data structure. A better choice would be simply a map of the counts of each word that is in the bag, which is a one-liner:
Map<String, Integer> hits = Arrays.stream(sentence.split(" "))
.filter(uniqueBagOfWords::contains)
.collect(groupingBy(identity()), counting());
This will produce something like:
{i=1, like=2, football=1}
Which seems a whole lot more straightforward. If you absolutely must have a (sparse) array, you can create that as a separate step.
Here I just made a string array for the bag of words and I put all the sentences into an arraylist. Then I made a comparison to check if the letter at a particular position in the sentence matches the position at the bagOfWords array.
public static void main(String[] args) {
String[] bagOfWords = {"i", "like", "to", "play", "tennis", "think", "football", "needs", "big", "changes"};
List<String> sentences = new ArrayList<String>();
sentences.add("i like to play tennis");
sentences.add("i think football needs big changes");
sentences.add("i like football");
for(String s1 : sentences){
String[] sentenceSplit = splitWords(s1);
for(int i=0;i<sentenceSplit.length;i++){
if(sentenceSplit[i].equals(bagOfWords[i])){
System.out.print("1 ");
}
else{
System.out.print("0 ");
}
}
System.out.println("");
}
}
private static String[] splitWords(String sentence){
String[] afterSplit = sentence.split(" ");
return afterSplit;
}
Try looping through your hashSet, rather than each word in the sentence. Also, I would use a StringBuilder or something similar for the output. Take a look at the loop below:
for (String s : sentences) {
StringBuilder numberOfOccurences = new StringBuilder();
for (String word : uniqueBagOfWords) {
if (s.contains(word)) {
numberOfOccurences.append("1,");
} else {
numberOfOccurences.append("0,");
}
}
System.out.println(s + " = " + numberOfOccurences);
}
Output:
i like to play tennis = 1,1,1,1,1,0,0,0,0,0,
i think football needs big changes = 1,0,0,0,0,1,1,1,1,1,
i like football = 1,1,0,0,0,0,1,0,0,0,
This question already has answers here:
Reverse each individual word of "Hello World" string with Java
(27 answers)
Closed 9 years ago.
So im trying to reverse the words in a sentence like: "Hi dog cat", would become "iH god tac". I was wondering if i can use what im doing to achieve that. I can get the sentence itself to reverse, but i cant get individual words to do so. Is there a way to do this with Strings or do i have to mess with Character(which is confusing too)? Any help is appreciated
private static String PrintStack(String sentence)
{
String reverse = "";
String stringReversed = "";
String Last;
String First;
Stack<String> stack= new Stack<String>();
String words[] = sentence.split(" ");
Last = words[words.length-1];
for(int j = 0; j < words.length; j++)
{
String newWord = words[0+j];
stack.push(newWord);
System.out.println(stack);
}
while(!stack.isEmpty())
{
stringReversed += stack.pop();
}
System.out.println("Reverse is: " + stringReversed);
return reverse;
}
}
FYI in Java it's conventional to name methods and variables with lowercase first letters, e.g., "printStack().
Your algorithm doesn't reverse the words themselves. I'd do it like this:
private static String reverseWords(String sentence) {
String words[] = sentence.split(" ");
ArrayList<String> reversed = new ArrayList<String>();
for (String word : words) {
reversed.add(new StringBuilder(word).reverse().toString());
}
StringBuilder reversedSentence = new StringBuilder();
for (String word : reversed) {
reversedSentence.append(word);
reversedSentence.append(" ");
}
return reversedSentence.toString().trim();
}
Hope this helps,
--Mark
In my program i want to take an input from a user, and separate the words with the letter "e" in them and concatenate them without any spaces or different lines. For instance, if my input was "Rob is a nice person" I want it to print "niceperson". This is what i have so far:
Scanner kybd = new Scanner(System.in);
String s = kybd.nextLine();
String[] arr = s.split(" ");
for ( String ss : arr) {
String []ary = {ss};
for(int i = 0; i < ss.length(); i++){
if(ary[i].equalsIgnoreCase("e")){
System.out.print(ary);
}
}
}
Thanks for any tips or help!
Use the contains method, it works like this:
Scanner kybd = new Scanner(System.in);
StringBuilder result = new StringBuilder();
String s = kybd.nextLine();
String[] arr = s.split(" ");
for ( String ss : arr) {
if(ss.contains("e")) {
result.append(ss);
}
}
You can do it in this way
String str = "Rob is a nice person";
String[] arr = str.split(" "); // split by space
StringBuilder sb = new StringBuilder();
for (String i : arr) {
if (i.contains("e")) { // if word contains e
sb.append(i);// append that word
}
}
System.out.println(sb);
Out put:
niceperson
how about some method like string.Replace("e ", "e");
I assume you are using String static method, as I can see you are using Split
try this
s = s.replaceAll("(\\b[\\w&&[^e]]+\\b)|\\s", "");
How can I divide a sentence like "He and his brother playing football." into few part like "He and", "and his", "his brother", "brother playing" and "playing football" . Is it possible to do that by using Java?
Assuming the "words" are always separated by a single space. Use String.split()
String[] words = "He and his brother playing football.".split("\\s+");
for (int i = 0, l = words.length; i + 1 < l; i++)
System.out.println(words[i] + " " + words[i + 1]);
You can do it using BreakIterator class and its static method getSentenceInstance().
It Returns a new BreakIterator instance for sentence breaks for the default locale.
You can also use getWordInstance(), getLineInstance().. to break words, line...etc
eg:
BreakIterator boundary = BreakIterator.getSentenceInstance();
boundary.setText("Your_Sentence");
int start = boundary.first();
int end = boundary.next();
Iterate over it... to get the Sentences....
For more detail look at this link:
http://docs.oracle.com/javase/6/docs/api/java/text/BreakIterator.html
Edited Answer: This is a working code
String sent = "My name is vivek. I work in TaxSmart";
BreakIterator bi = BreakIterator.getSentenceInstance();
bi.setText(sent);
int index = 0;
while (bi.next() != BreakIterator.DONE) {
String sentence = sent.substring(index, bi.current());
System.out.println("Sentence: " + sentence);
index = bi.current();
}
String str="He and his brother playing football";
String [] strArray=str.split(" ");
for(int i=0;i<strArray.length-1 ;i++)
{
System.out.println(strArray[i]+" "+strArray[i+1]);
}
Use a StringTokenizer to separate by spaces or other characters.
import java.util.StringTokenizer;
public class Test {
private static String[] tokenize(String str) {
StringTokenizer tokenizer = new StringTokenizer(str);
String[] arr = new String[tokenizer.countTokens()];
int i = 0;
while (tokenizer.hasMoreTokens()) {
arr[i++] = tokenizer.nextToken();
}
return arr;
}
public static void main(String[] args) {
String[] strs = tokenize("Sandy sells seashells by the sea shore.");
for (String s : strs)
System.out.println(s);
}
}
Should print out:
Sandy
sells
seashells
by
the
sea
shore.
May or may not be what you're after.