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());
}
Related
I am trying to check if a sentence is the same forwards and backwards or a "sentence palindrome." The sentence "You can cage a swallow, can't you, but you can't swallow a cage, can you?" should return (True) as a palindrome. Ignore everything that is not a letter.
My problem: Not sure how to compare words specifically. This currently works for words checking if they are palindromes, but I need to figure out what to change to compare each word.
public static boolean isWordPalindrome(String input) {
Deque<Character> q = new LinkedList<>( );
Deque<Character> q2 = new LinkedList<>( );
Character letter; // One character from the input string
int mismatches = 0; // Number of spots that mismatched
int i; // Index for the input string
int x;
for (i = 0; i < input.length( ); i++)
{
letter = input.charAt(i); // read next character in the string
if (letter.toString().equals(',') || letter.toString().equals('"') || letter.toString().equals('?') || letter.toString().equals('!') || letter.toString().equals('.') || letter.toString().equals(' ')) {
//throwaway.add(letter); //ignore above chars and put in throwaway stack
}
if (Character.isLetter(letter)) // if letter put into q's
{
q.add(letter);
q2.addFirst(letter);
}
} // end of for loop
System.out.println("q: " + q);
System.out.println("q2:" + q2);
while (!q.isEmpty( ))
{
if (!Objects.equals(q.remove(), q2.remove()))
mismatches++;
}
I'd remove all the special characters, split the string by whitespaces and check the list is "symmetrical":
private static boolean isSentancePalindrom(String sentence) {
String[] words = sentence.replaceAll("[^a-zA-Z ]", "").split("\\s+");
for (int i = 0; i < words.length / 2; ++i) {
if (!words[i].equalsIgnoreCase(words[words.length - i - 1])) {
return false;
}
}
return true;
}
I came up with this:
public static boolean checkString(String str) {
str = str.replaceAll("[,\\?\\.!]+", "").toUpperCase();
String[] split = str.split(" ");
String[] reverse = new String[split.length];
System.arraycopy(split, 0, reverse, 0, split.length);
List<String> listOfSring = Arrays.asList(split);
List<String> reversListOfSring = Arrays.asList(reverse);
Collections.reverse(reversListOfSring);
return reversListOfSring.equals(listOfSring);
}
I hope it would help!
I have an assignment for school due at midnight today. I have finished almost all the assignment except for one question. I need to swap "r" and "q" with each other as values. So, if you enter "r" in the compiler you should get "q" if you enter "q" you get "r"(Using JOptionPane). For example, if your name is Quart, the compiler should print Ruaqt. I tried using the replace.All method, but once I can only swap "r" or "q" not both. I know I need a temporary variable, but do not know anything else...
We had to replace vowels with the letter after them so I did this:
String firstName = JOptionPane
.showInputDialog("What is your first name?");
String lastName = JOptionPane
.showInputDialog("What is your last name?");
String fullname = firstname + lastname;
String lowername = fullName.toLowerCase();
String encryptedname = lowername.replaceAll("a", "b")
.replaceAll("e", "f").replaceAll("i", "j").replaceAll("o", "p")
.replaceAll("u", "v");
Thanks
Dunno why the 2 answers using StringBuilder are both making the thing more complicated than needed.
Here is the way you can use StringBuilder to do that single character swap:
public static String swapChar(String string, char c1, char c2) {
StringBuilder sb = new StringBuilder(string);
for (int i = 0; i < sb.length(); ++i) {
if (sb.charAt(i) == c1) {
sb.setCharAt(i, c2);
} else if (sb.charAt(i) == c2) {
sb.setCharAt(i, c1);
}
}
return sb.toString();
}
Update :
Just found that what you are looking for is actually doing a bunch of replace of character at the same time. That can be cleanly done by providing a Map as parameter:
public static String replaceChars(String string, Map<Character,Character> cmap) {
StringBuilder sb = new StringBuilder(string);
for (int i = 0; i < sb.length(); ++i) {
if (cmap.containsKey(sb.charAt(i)) {
sb.setCharAt(i, cmap.get(sb.charAt(i));
}
}
return sb.toString();
}
to use it:
// or make a util method to make these even easier to create
Map<Character,Character> cmap = new HashMap<Character,Character>();
cmap.put('r','q');
cmap.put('q','r');
cmap.put('a','b');
cmap.put('e','f');
cmap.put('i','j');
cmap.put('o','p');
cmap.put('u','v');
and simply do a replace:
String result = replaceChars(inputString, cmap);
or even simpler, by making use of Apache Commons Lang:
String result = StringUtils.replaceChars(inputString, "rqaeiou", "qrbfjpv");
You can try this.
private static final char Q_STR = 'q';
private static final char R_STR = 'r';
public static String replaceString(String original, int position, char strToReplace) {
StringBuilder strBuilder = new StringBuilder(original);
if (strToReplace == Q_STR) {
strBuilder.setCharAt(position, R_STR);
} else if (strToReplace == R_STR){
strBuilder.setCharAt(position, Q_STR);
}
return strBuilder.toString();
}
public static void main(String[] args) {
String firstname = "Quart";
String lastname = " QuartLastName";
String fullname = firstname + lastname;
String lowername = fullname.toLowerCase();
//get all chars in String
char[] array = lowername.toCharArray();
//list to keep original position of Q char
List<Integer> allQPosition = new ArrayList<Integer>();
//list to keep original position of R char
List<Integer> allRPosition = new ArrayList<Integer>();
for (int i = 0; i < array.length; i++) {
if(array[i] == 'q') {
allQPosition.add(i);
} else if(array[i] == 'r') {
allRPosition.add(i);
}
}
//replace q
for (Integer integer : allQPosition) {
lowername = replaceString(lowername, integer, Q_STR);
}
//replace r
for (Integer integer : allRPosition) {
lowername = replaceString(lowername, integer, R_STR);
}
//replace others
String encryptedname = lowername.replace("a", "b")
.replace("e", "f")
.replace("i", "j")
.replace("o", "p")
.replace("u", "v");
System.out.println("Result: " + encryptedname);
}
My solution is:
Keep all position of 'q' and 'r' from original String.
Replace each of them
Replace the rest of other chars
Hope this help
public static void main(String[] args) {
String origin = "r and q";
System.out.println(newReplacement(origin, 'r', 'q'));
}
private static String newReplacement(String origin, char firstChar, char secondChar) {
StringBuffer stringBuffer = new StringBuffer(origin);
for(int i = 0; i < origin.length(); i++) {
if(origin.charAt(i) == firstChar) {
stringBuffer.replace(i, i+1, secondChar + "");
continue;
}
if(origin.charAt(i) == secondChar) {
stringBuffer.replace(i, i+1, firstChar + "");
}
}
return stringBuffer.toString();
}
Rewrite replace method with simple one.
I am trying to get the first letter of every word in a String:
String recInf = recursos.getString(nombre);
char[] tipoAbreviado = recInf.toCharArray();
tipoAbreviado[0] = Character.toUpperCase(tipoAbreviado[0]);
for (int i = 0; i < recInf.length() - 2; i++) {
// Es 'palabra'
if (tipoAbreviado[i] == ' ' || tipoAbreviado[i] == '.' || tipoAbreviado[i] == ',') {
// Reemplazamos
tipoAbreviado[i + 1] = Character.toUpperCase(tipoAbreviado[i + 1]);
}
nombre = tipoAbreviado.toString();
}
Finally the value of nombre is [C#3b1938ea, not the first letter of every word in recInf
You can use Arrays.toSting(your_array) to print your Array.
Take a look what toString() in Arrays do
public static String toString(long[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
But when you use tipoAbreviado.toString(); it will call toString() method in Object class.
What toString() method in Object class do?
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
That's why you are getting your current out put.
Instead of using toString on an Array which prints the memory address representation, you should create a String from char[] using new String(char[])
nombre = new String(tipoAbreviado);
You can use string's .split() with the correct regex and then just pick the first char:
String[] words = "Your String & !+ and some extraodrinary others".split("[^a-zA-Z]+");
for (String word: words ){
System.out.println(word.charAt(0));
}
You can try to fetch them with a Regular Expression.
When I use the RegEx (\w)\w+ on the string Hallo Welt, ich bin ein String, I get an array with H, W, i, b, e, S. Note: You have to run the expression as global expression (more than once).
Assuming the String object you want to process is recInf i would recommend to do it as follows:
String recInf = new String(text.replaceAll("[^\\p{L}\\p{Nd} ]+"," ")
.replaceAll("[\\s]+", " "));
String[] words = recInf.split(" ");
String[] firstLetters = new String[words.length];
for(int i=0; i<words.length;i++){
firstLetters[i]=words[i].getCharAt(0);
}
You could try this
nombre = (new StringBuilder(tipoAbreviado)).toString();
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 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