I'd like to retrieve whatever is in quotes that someone enters as a string, i'm assuming it's substring that I need but i'm not sure how.
When the user inputs a string mixed with words and numbers all separated by one space:
hey 110 say "I am not very good at Java" but " I can fish pretty well"
Then I want to be able to take the "I am not very good at Java" and the "I can fish pretty well" and print out what's inside the quotes so there can be multiple quotes in the string.
right now I have if( userInput=='"') then I do something with substring but i'm not sure what.
I can't use split, trim, tokenizer, regex or anything that would make this really easy unfortunatley.
it's all in this method where I try to identify if something in the string is a word, number or a quote:
public void set(String userInput)// method set returns void
{
num=0;// reset each variable so new input can be passed
String empty="";
String wordBuilder="";
userInput+=" ";
for(int index=0; index<userInput.length(); index++)// goes through each character in string
{
if(Character.isDigit(userInput.charAt(index)))// checks if character in the string is a digit
{
empty+=userInput.charAt(index);
}
else
{
if (Character.isLetter(userInput.charAt(index)))
{
wordBuilder+=userInput.charAt(index);
}
else
{
if(userInput.charAt(index)=='"')
{
String quote=(userInput.substring(index,);
}
}
//if it is then parse that character into an integer and assign it to num
num=Integer.parseInt(empty);
word=wordBuilder;
empty="";
wordBuilder="";
}
}
}
}
Thanks!
Try the next:
public static void main(String[] args) {
String input = "\"123\" hey 110 say \"I am not very good at Java\" but \" I can fish pretty well\"";
int indexQuote = -1;
boolean number = true;
String data = "";
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (Character.isWhitespace(ch)) {
if (data.length() > 0 && indexQuote == -1) {
if (number) {
System.out.println("It's a number: " + data);
} else {
System.out.println("It's a word: " + data);
}
// reset vars
number = true;
data = "";
} else if (indexQuote != -1) {
data += ch;
}
} else if (ch == '"') {
if (indexQuote == -1) {
number = false;
indexQuote = i;
} else {
System.out.println("It's a quote: " + data);
// reset vars
number = true;
data = "";
indexQuote = -1;
}
} else {
if (!Character.isDigit(ch)) {
number = false;
}
data += ch;
if (data.length() > 0 && i == input.length() - 1) {
if (number) {
System.out.println("It's a number: " + data);
} else {
System.out.println("It's a word: " + data);
}
}
}
}
}
Output:
It's a word: hey
It's a number: 110
It's a word: say
It's a quote: I am not very good at Java
It's a word: but
It's a quote: I can fish pretty well
I'm not sure if this quite what you are looking for, but it will strip down the quoted parts in steps...
String quote = "I say: \"I have something to say, \"It's better to burn out then fade away\"\" outloud...";
if (quote.contains("\"")) {
while (quote.contains("\"")) {
int startIndex = quote.indexOf("\"");
int endIndex = quote.lastIndexOf("\"");
quote = quote.substring(startIndex + 1, endIndex);
System.out.println(quote);
}
}
Which outputs...
I have something to say, "It's better to burn out then fade away"
It's better to burn out then fade away
Updated
I don't know if this is cheating or not...
String quote = "I say: \"I have something to say, \"It's better to burn out then fade away\"\" outloud...\"Just in case you don't believe me\"";
String[] split = quote.split("\"");
for (String value : split) {
System.out.println(value);
}
Which outputs...
I say:
I have something to say,
It's better to burn out then fade away
outloud...
Just in case you don't believe me
Updated
Okay, fake String#split
StringBuilder sb = new StringBuilder(quote.length());
for (int index = 0; index < quote.length(); index++) {
if (quote.charAt(index) == '"') {
System.out.println(sb);
sb.delete(0, sb.length());
} else {
sb.append(quote.charAt(index));
}
}
Updated
Okay, this is basically fake split with options...
String quote = "blah blah 123 \"hello\" 234 \"world\"";
boolean quoteOpen = false;
StringBuilder sb = new StringBuilder(quote.length());
for (int index = 0; index < quote.length(); index++) {
if (quote.charAt(index) == '"') {
if (quoteOpen) {
System.out.println("Quote: [" + sb.toString() + "]");
quoteOpen = false;
sb.delete(0, sb.length());
} else {
System.out.println("Text: [" + sb.toString() + "]");
sb.delete(0, sb.length());
quoteOpen = true;
}
} else {
sb.append(quote.charAt(index));
}
}
if (sb.length() > 0) {
if (quoteOpen) {
System.out.println("Quote: [" + sb.toString() + "]");
} else {
System.out.println("Text: [" + sb.toString() + "]");
}
}
Which generates...
Text: [blah blah 123 ]
Quote: [hello]
Text: [ 234 ]
Quote: [world]
Know, I don't know how you are storing the results. I would be tempted to create some basic classes which were capable of storing the String results and add them to a List so I could maintain the order and maybe use a flag of some kind to determine what type they are...
Iterate over the string and use a temporary int variable to store when the quoted string started. When you see that it ends, you can extract that substring and do what you want with it.
Use StringUtils.subStringBetween
public class MyTestSecond {
public static void main(String...args){
String a = "hey 110 say \"I am not very good at Java\"";
// Method 1
if(a.contains("\""))
System.out.println(a.substring(a.indexOf("\""),a.lastIndexOf("\"")+1));
//Method 2
String[] array = a.split(" ");
for(int i=0;i<array.length;i++){
if(array[i].startsWith("\""))
System.out.println(a.substring(a.indexOf("\""),a.lastIndexOf("\"")+1));
}
}
}
public String getNextQuote(int index, String sentence){
return sentence.substring(sentence.indexOf("\"", index + 1), sentence.indexOf("\"", index + 2));
}
usage: call the method with an index as parameter. This index resembles the index of the last " that you've encountered.
Afterwards, it will return everything between the next two quotes.
Related
Basically I've built up a string and I need to put an if statement on when to use a comma and a space. So basically I need it be after the first element and not on the last element.
This is what my current code is:
And the output it returns is
"thing1thing2thing3"
I want to make the output to be
"thing1, thing2, thing3"
And I need an if statement as part of the requirements on when to place the commas and spaces.
Thanks in advance.
This might be a little advanced for you, but it's very easy when using Java 8 (if things is a Collection:
return Optional.of(things.stream()
.filter(thing -> thing.getCategory() == things.STUFF)
.collect(Collectors.joining(", ")))
.orElse("nothing");
If you're using Java 7, then you can do it manually:
StringBuilder sb = new StringBuilder();
for (Thing thing : things) {
if (things.getCategory() == some.STUFF){
sb.append(thing.getName()).append(", ");
}
}
if (s.isEmpty()) {
return "nothing";
}
return sb.delete(sb.length() - 2, sb.length()).toString();
I'd use a for-loop rather than a for-each loop - only because I see it as eliminating the need for an additional counter variable. This is how I'd approach the problem.
String[] things = {"thing 1", "thing 2", "thing 3", "thing 4"};
for(int i = 0; i < things.length; i++)
{
if(i < things.length - 1)
{
System.out.print(things[i] + ", ");
}
else
{
System.out.print(things[i] + ".");
}
}
There are a few unclear things about the question, so the code below is based on what I have understood so far.
String s = "";
boolean isComma = true; // true = comma, false = space.
for (Thing thing : things)
{
if (things.getCategory() == thing.STUFF)
{
//Check if there already exists an entry within the String.
if (s.length() > 0)
{
//Add comma or space as required based on the isComma boolean.
if (isComma)
{
s += ", ";
}
else
{
s += " ";
}
}
s += thing.getName();
}
}
if (s.equals(""))
{
s += "nothing";
}
return s;
I'm working on getting a method that prints the words of a sentence out backwards. I'm very close to a solution but am hitting a minor snag.
Here is my code:
public static String reverseString(String str) {
if (str.equals(""))
return "";
else {
int i = str.length() - 1;
while (!Character.isWhitespace(str.charAt(i))) {
if (i - 1 < 0)
break;
i--;
}
return str.substring(i,str.length()) + reverseString(str.substring(0,i));
}
}
Now the problem is the that the output from my test:
String test = "This is a test.";
System.out.println(reverseString(test));
Is giving me this back:
test. a isThis
Now, when I try to bump up the index of the substring being returned and add in the spaces manually, it cuts off the "T" in "This". That is, if I decide to instead return as follows:
return str.substring(i+1,str.length()) + " " + reverseString(str.substring(0,i));
then I get back
test. a is his
Does anyone have any advice or pointers on my implementation in general?
You can change the return statement to this:
return str.substring(i, str.length()).trim() + " " + reverseString(str.substring(0, i));
Split the sentence using String.split and then iterate over the resulting array backwards. To split at whitespace do
test.split(" +");
The split method takes a Regular Expression and the above means: split at one or more consecutive whitespaces.
Recursive approach:
public String reverse(final String s) {
final int pos = s.indexOf(' ');
if (pos > -1) {
return reverse(s.substring(pos + 1).trim()) + " " + s.substring(0, pos).trim();
}
return s;
}
In this approach you can selectively create substring based on whitespace. For input This is a test. below method will give return test. a is This. Idea here is if you have a leading space, you will actually convert to trailing space.
public static String reverseString(String str) {
if (str.equals(""))
return "";
else {
int i = str.length() - 1;
while (!Character.isWhitespace(str.charAt(i))) {
if (i - 1 < 0)
break;
i--;
}
String substring;
if(Character.isWhitespace(str.charAt(i)))
{
substring= str.substring(i+1,str.length())+" ";
}
else
{
substring= str.substring(i,str.length());
}
return substring + reverseString(str.substring(0,i));
}
}
Working with your code you would just need to add an additional space in front of whatever string you want to reverse such as with this code
reverseString(" " + str)
when you first execute the method.
this method I tried to write is supposed to take in a string, and then an array of strings to be inserted into the original string at any "_" character, with an a/an before it, depending on what is appropriate. It will be used if the strings to be inserted are variables, and I don't know if it should be a or an. But it doesn't work. For instance, if theString is just "_" and array is {pineapple}, then it prints a pineapple_. If theString is "I am holding _, which is not a fruit, like _" and array is {pineapple, apple}, it prints I am holding _, which is not a fruit, like a pinapple_. I have looked at it, but I am unable to find the problem. I am not too sure how the stringBuilder class works, so the problem may stem from that. Thanks for any help you can give me!
public static void printWithVar(String theString, String[] array){
int arrayPosition = 0;
String insert;
StringBuilder builder = new StringBuilder(theString);
for (int i = 0;i <= theString.length();i++){
// if a "_" is found
if (theString.substring(i).equals("_")){
// if the first letter is a vowel
if (array[arrayPosition].substring(0).equalsIgnoreCase("a") || array[arrayPosition].substring(0).equalsIgnoreCase("e") || array[arrayPosition].substring(0).equalsIgnoreCase("i") || array[arrayPosition].substring(0).equalsIgnoreCase("o") || array[arrayPosition].substring(0).equalsIgnoreCase("u")){
builder.deleteCharAt(i);
insert = "an " + array[arrayPosition];
}
// if just an "a"
else{
builder.deleteCharAt(i);
insert = "a " + array[arrayPosition];
}
builder = new StringBuilder(theString = theString.substring(0, i) + insert + theString.substring(i));
arrayPosition++;
i += insert.length();
// if there are no more strings to insert
if (arrayPosition == array.length){
break;// for loop searching for "_" characters
}
}// end if an "_" is found
}// end loop
System.out.println(builder.toString());
}// end printWithVar
In response to the first comment (by 9000) I changed the code to this, and it now works.
public static void printWithVar(String theString, String[] insertArray){
String[] splitStrings = theString.split("_");
String output = "";
String insert;
// loop until there are no mmore inserts
for (int i = 0;i < insertArray.length;i++){
// if an is appropriate
if (insertArray[i].substring(i).equalsIgnoreCase("a") || insertArray[i].substring(i).equalsIgnoreCase("e") || insertArray[i].substring(i).equalsIgnoreCase("i") || insertArray[i].substring(i).equalsIgnoreCase("o") || insertArray[i].substring(i).equalsIgnoreCase("u")){
insert = "an " + insertArray[i];
}
// if a is appropriate
else{
insert = "a " + insertArray[i];
}
// add everything needed to the output string
output = output + splitStrings[i] + insert;
}// end the loop
// print the resulting string
System.out.println(output);
}// end printWithVar
If you would accept an alternative solution, I would use StringTokenizer:
public static void printWithVar(String theString, String[] array) {
final List<Character> vowels = Arrays.asList(new Character[] { 'a', 'e', 'i', 'o', 'u' });
StringTokenizer tok = new StringTokenizer(theString, "_", true);
StringBuilder result = new StringBuilder();
int i = 0;
while (tok.hasMoreTokens()) {
String token = tok.nextToken();
if (token.equals("_")) {
if (i >= array.length) {
continue;
}
String replacement = array[i];
if (vowels.contains(replacement.toLowerCase().charAt(0))) {
result.append("an " + replacement);
} else {
result.append("a " + replacement);
}
i++;
} else {
result.append(token);
}
}
System.out.println(result.toString());
}
You can use indexOf instead which returns the position of the first occurrence of "_" or -1 if it isn't found. While "_" can be found use .replace(...) method to swap out "_" with the word from the string array array[wordArrayPosition].
public static void printWithVar(String theString, String[] array){
int wordArrayPosition = 0;
String[] vowels = {"a", "e", "i", "o", "u"};
StringBuilder builder = new StringBuilder(theString);
int indexOfSymbol = builder.indexOf("_");
while (indexOfSymbol != -1) {
//Adding a or an to the word
String word = null;
if (Arrays.asList(vowels).contains(array[wordArrayPosition].charAt(0))){
word = "an " + array[wordArrayPosition];
} else {
word = "a " + array[wordArrayPosition];
}
//Checking if the word need to be capitalized
if ((indexOfSymbol == 0) || (builder.charAt(indexOfSymbol - 1) == '.')) {
word = "A" + word.substring(1);
}
builder.replace(indexOfSymbol, indexOfSymbol + 1, word);
wordArrayPosition += 1;
indexOfSymbol = builder.indexOf("_");
}
System.out.println(builder.toString());
}
I'm using the following code to add a guessed consonant to a string of stars if the guessed consonant is part of the original word. Initially I was keeping wordWithGuess between calls to getCurrentResult. But the result of this was that the new content was added to the end, and wordWithGuess kept getting longer (instead of just replacing the most recently guessed letter).
When running the code below, the output is
After guessing r: *****r******
After guessing s: ************
After guessing t: **tt********
After guessing l: ********ll**
After guessing n: ***********n
My goal is for it to be:
After guessing r: *****r******
After guessing s: *****r******
After guessing t: **tt*r******
After guessing l: **tt*r**ll**
After guessing n: **tt*r**ll*n
Sample code follows:
public class Sample {
String targetWord;
String wordWithGuess = "";
public Sample(String targetWord) {
this.targetWord = targetWord;
}
public void guess(String consonant) {
wordWithGuess = "";
for (int i = 0; i < targetWord.length(); i++) {
if (targetWord.substring(i, i + 1).equals(" ")) {
wordWithGuess += " ";
} else if (targetWord.substring(i, i + 1).equals(consonant)) {
wordWithGuess += consonant;
} else {
wordWithGuess += "*";
}
}
}
public String getCurrentResult() {
return wordWithGuess;
}
public static void main(String args[]) {
String targetWord = "bitterbollen";
Sample sample = new Sample(targetWord);
String[] guesses = { "r", "s", "t", "l", "n" };
for (String guess : guesses) {
sample.guess(guess);
System.out.println("After guessing " + guess + ": "
+ sample.getCurrentResult());
}
}
}
you should store all consonants guessed, and change
word.substring(i, i + 1).equals (consonant)
to something like
word.substring(i, i + 1) exists in the consonant guessed. (it is pusedo-code of course)
Some more hints: have a look in Set (or more precisely, HashSet), or String's contains() or indexOf() method.
Some extra opinions to you:
you are calling word.substring(i, i + 1) without storing the returned string, that's a meaningless call.
Instead calling word.substring(i, i + 1) that many times, you can call it once and use the returned string for multiple comparison.
And, as you are comparing one char each time, you should use char to store the character, and using charAt() to get the character at certain position.
The problem is that you need to keep some information between calls to guess(). This means either storing all values of consonant, or finding a way to merge the old value of wordWithGuess with the new consonant.
The first option means something like
import java.util.Set;
import java.util.HashSet;
class Sample {
// ...
Set<String> guesses = new HashSet<String>();
public void guess(String consonant) {
guesses.add(consonant);
wordWithGuess = "";
for (int i = 0; i < targetWord.length(); i++) {
String cursor = targetWord.substring(i, i + 1);
if (cursor.equals(" ")) {
wordWithGuess += " ";
} else if (guesses.contains(cursor)) {
wordWithGuess += cursor;
} else {
wordWithGuess += "*";
}
}
}
// ...
}
This stores the old guesses as a Set. Instead of just checking for the last guess, guess() now includes any letter that has been guessed.
In fact you could even add a constructor to initialize the set with any characters that you want to include by default. This will let you eliminate the check for a space, as it'll be in the initial set of guesses:
import java.util.Set;
import java.util.HashSet;
class Sample {
// ...
Set<String> guesses;
public Sample() {
this.guesses = new HashSet<String>();
guesses.add(" ");
}
public void guess(String consonant) {
guesses.add(consonant);
wordWithGuess = "";
for (int i = 0; i < targetWord.length(); i++) {
String cursor = targetWord.substring(i, i + 1);
if (guesses.contains(cursor)) {
wordWithGuess += cursor;
} else {
wordWithGuess += "*";
}
}
}
// ...
}
The other option would be to update wordWithGuess to include the new guess. In C it's easy to do this, because strings can be modified just like character arrays (for example, wordWithGuess[i] = consonant. Java guards its strings more closely, but there's no reason why one can't use an array of char to the same effect.
public class Sample {
String targetWord;
char[] currentResult;
public Sample(String targetWord) {
this.targetWord = targetWord;
currentResult = new char[targetWord.length()];
for (int i = 0; i < targetWord.length(); i++) {
if(targetWord.charAt(i) == ' ') {
currentResult[i] = ' ';
} else {
currentResult[i] = '*';
}
}
}
public void guess(String consonant) {
for (int i = 0; i < targetWord.length(); i++) {
String cursor = targetWord.substring(i, i + 1);
if (cursor.equals(consonant)) {
currentResult[i] = consonant.charAt(0);
}
}
}
public String getCurrentResult() {
return new String(currentResult);
}
// ...
}
You'll want to store the result of the previous iteration. Have the code oldWordWithGuess = wordWithGuess at the end of the for loop.
Then, in your loop you'll want the following code:
...
if(oldWordWithGuess[i] != `*`) {
wordWithGuess += oldWordWithGuess[i];
} else if (word.substring(i, i + 1).equals (" ")) {
...
That way it will put any previous guesses in.
I've actually found a different solution where I use a char Array and store every letter in a different element of that array. Am I actually allowed to do this? Does this not require too much resources for what it does?
I have this code:
String s = "A very long string containing " +
"many many words and characters. " +
"Newlines will be entered at spaces.";
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
The output of the code is:
A very long string containing
many many words and
characters. Newlines
will be entered at spaces.
The above code is wrapping the string after the next space of every 30 characters, but I need to wrap the string after the previous space of every 30 characters, like for the first line it will be:
A very long string
And the 2nd line will be
containing many
Please give some proper solution.
You can use Apache-common's WordUtils.wrap().
Use lastIndexOf instead of indexOf, e.g.
StringBuilder sb = new StringBuilder(s);
int i = 0;
while (i + 20 < sb.length() && (i = sb.lastIndexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
This will produce the following output:
A very long string
containing many
many words and
characters.
Newlines will be
entered at spaces.
You can try the following:
public static String wrapString(String s, String deliminator, int length) {
String result = "";
int lastdelimPos = 0;
for (String token : s.split(" ", -1)) {
if (result.length() - lastdelimPos + token.length() > length) {
result = result + deliminator + token;
lastdelimPos = result.length() + 1;
}
else {
result += (result.isEmpty() ? "" : " ") + token;
}
}
return result;
}
call as wrapString("asd xyz afz","\n",5)
I know it's an old question, but . . . Based on another answer I found here, but can't remember the posters name. Kuddos to him/her for pointing me in the right direction.
public String truncate(final String content, final int lastIndex) {
String result = "";
String retResult = "";
//Check for empty so we don't throw null pointer exception
if (!TextUtils.isEmpty(content)) {
result = content.substring(0, lastIndex);
if (content.charAt(lastIndex) != ' ') {
//Try the split, but catch OutOfBounds in case string is an
//uninterrupted string with no spaces
try {
result = result.substring(0, result.lastIndexOf(" "));
} catch (StringIndexOutOfBoundsException e) {
//if no spaces, force a break
result = content.substring(0, lastIndex);
}
//See if we need to repeat the process again
if (content.length() - result.length() > lastIndex) {
retResult = truncate(content.substring(result.length(), content.length()), lastIndex);
} else {
return result.concat("\n").concat(content.substring(result.length(), content.length()));
}
}
//Return the result concatenating a newline character on the end
return result.concat("\n").concat(retResult);;
//May need to use this depending on your app
//return result.concat("\r\n").concat(retResult);;
} else {
return content;
}
}
public static void main(String args[]) {
String s1="This is my world. This has to be broken.";
StringBuffer buffer=new StringBuffer();
int length=s1.length();
int thrshld=5; //this valueis threshold , which you can use
int a=length/thrshld;
if (a<=1) {
System.out.println(s1);
}else{
String split[]=s1.split(" ");
for (int j = 0; j < split.length; j++) {
buffer.append(split[j]+" ");
if (buffer.length()>=thrshld) {
int lastindex=buffer.lastIndexOf(" ");
if (lastindex<buffer.length()) {
buffer.subSequence(lastindex, buffer.length()-1);
System.out.println(buffer.toString());
buffer=null;
buffer=new StringBuffer();
}
}
}
}
}
this can be one way to achieve
"\n" makes a wordwrap.
String s = "A very long string containing \n" +
"many many words and characters. \n" +
"Newlines will be entered at spaces.";
this will solve your problem