When I run the tester class it can't get past the first letter. It outputs an "!" mark instead of continuing to print the rest of the word reversed. Can't figure why it keeps getting hungup. The recursive method seems to be stuck and unable to continue past the first character. Instead of printing "!olleH" I only get "!". Thanks!
/**
Class reverses text of word
*/
public class Sentence
{
private String text="";
/**
Constructs a sentence
#param word
*/
public Sentence(String textIN)
{
text=textIN;
}
/**
gets text
#return text
*/
public String getText()
{
return text;
}
/**
Reverse word
*/
public String reverse()
{
if (text.length() <= 1)
{
return text;
}
else
{
char val = text.charAt(0);
text=text.substring(1);
return reverse() + val;
}
}
}
/**
A tester class for reversing a sentence.
*/
public class SentenceTester
{
public static void main(String[] args)
{
Sentence greeting = new Sentence("Hello!");
greeting.reverse();
System.out.println(greeting.getText());
System.out.println("Expected: !olleH");
}
}
From a read-through of your code, your reverse method seems to work - it returns a reverse of the original text. However, it does this by altering the value of text, and it never puts the final value into text.
What actually happens is that text gets shorter by one character (removed from the front) until there is only one character left - the !.
So, you could solve the problem in your main method:
public static void main(String[] args)
{
Sentence greeting = new Sentence("Hello!");
String result = greeting.reverse();
System.out.println(result);
System.out.println("Expected: !olleH");
}
I hope you like it that way. Just for information, you could use below -
String reversedString = new StringBuilder("Original String").reverse().toString();
One more thing, your code will not work if you pass null :)
The problem with your code is, you are modifying text in else block.
text = text.substring(1);
So at the end it holds only !
Here is the final program (just changed the return statement):
/**
Class reverses text of word
*/
public class Sentence
{
private String text="";
/**
Constructs a sentence
#param word
*/
public Sentence(String textIN)
{
text=textIN;
}
/**
gets text
#return text
*/
public String getText()
{
return text;
}
/**
Reverse word
*/
public String reverse()
{
if (text.length() <= 1)
{
return text;
}
else
{
char val = text.charAt(0);
text=text.substring(1);
return (text=reverse() + val);
}
}
}
the reason is simple - String is immutable. Every time you want it to change assign it back again.
Related
I'm learning Java for a class and one of the assignments I need to do is implementing String methods into my code. After prompting the user to set text, I used a toLowerCase() method and printed it. On another line, I used a toUpperCase() method and printed it. Both printed correctly but whenever I used the toString() method, it only my text in lowercase.
Here is my main class:
import java.util.Scanner;
public class TalkerTester
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter some text: ");
String words = input.nextLine();
Talker talky = new Talker(words);
String yelling = talky.yell();
String whispers = talky.whisper();
System.out.println(talky);
System.out.println("Yelling: " + yelling);
System.out.println("Whispering: " + whispers);
}
}
Here is my class with all my methods
public class Talker
{
private String text;
// Constructor
public Talker(String startingText)
{
text = startingText;
}
// Returns the text in all uppercase letters
// Find a method in the JavaDocs that
// will allow you to do this with just
// one method call
public String yell()
{
text = text.toUpperCase();
return text;
}
// Returns the text in all lowercase letters
// Find a method in the JavaDocs that
// will allow you to do this with just
// one method call
public String whisper()
{
text = text.toLowerCase();
return text;
}
// Reset the instance variable to the new text
public void setText(String newText)
{
text = newText;
}
// Returns a String representatin of this object
// The returned String should look like
//
// I say, "text"
//
// The quotes should appear in the String
// text should be the value of the instance variable
public String toString()
{
text = text;
return "I say, " + "\"" + text + "\"";
}
}
I apologize for the long paste and my bad English.
It is because you modify the value of text. It will persist even after you return. You should not. Instead, directly return like this:
String yell() {
return text.toUpperCase();
}
Using your methods yell() and whisper, you also edit your variable text. In fact, before the line
System.out.println(talky);
you have used the method whisper which make the variable text into lowercase.
You have to edit your code like this:
public String whisper()
{
return text.toLowerCase();
}
public String yell()
{
return text.toUpperCase();
}
public String toString()
{
return "I say, " + "\"" + text + "\"";
}
Moreover, to be more precise, use the Java keyword this when you use the variable text! For example,
public Talker(String startingText)
{
this.text = startingText;
}
I am creating some java code that takes correctly written .java files as input, and i want to extract the text between braces using a regular expression. I want to use the Pattern and Matcher classes, and not for loops.
I believe its best to create a regex that groups the text in the whole class, and later another regex that will be aplied to the previous output and groups the text in methods.
I got close to getting the class text using the following regex on online regex testers:
\w\sclass.*\{((.*\s*)*)\}
but i'm pretty sure i am doing it wrong by using two groups instead of just one. Furthermore when i use this expression in Java i am actually getting nothing.
Here is an example file that i am using for debugging
package foo.bar;
import java.io.File;
public class Handy {
{
// static block, dont care!
}
/**
* Check if a string is Null and Empty
* #param str
* #return
*/
public static boolean isNullOrEmpty(String str) {
Boolean result = (str == null || str.isEmpty());
return result;
}
/**
* Mimics the String.format method with a smaller name
* #param format
* #param args
* #return
*/
public static String f(String format, Object... args)
{
return String.format(format, args);
}
}
With the example code above, i expect to get:
entire class text
{
// static block, dont care!
}
/**
* Check if a string is Null and Empty
* #param str
* #return
*/
public static boolean isNullOrEmpty(String str) {
Boolean result = (str == null || str.isEmpty());
return result;
}
/**
* Mimics the String.format method with a smaller name
* #param format
* #param args
* #return
*/
public static String f(String format, Object... args)
{
return String.format(format, args);
}
individual method text
Boolean result = (str == null || str.isEmpty());
return result;
return String.format(format, args);
I know how to use the Pattern and Matcher classes already, i just need the right regexes...
After some confusion in the comments section, i would like to share my solution for what i asked, even if it was not very clear.
This is not thoroughly tested code, but it works for my purpose. Some adjustments or improvements are very likely possible. I took some inspiration from the comments i read in this post, and others like this.
I feed each of the following methods the entire plain text found in a .java file, and from there i use Pattern and Matcher to extract what i want.
private static String patternMatcher(String content, String patternText, int groupIndex) {
Pattern pattern = Pattern.compile(patternText);
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
return matcher.group(groupIndex);
} else {
return "";
}
}
public static String getPackageName(String content) {
return patternMatcher(content, ".*package\\s+(.*)\\s*\\;", 1);
}
public static String getClassName(String content) {
return patternMatcher(content, ".*class\\s+(\\w+)[\\w\\s]+\\{", 1);
}
public static String getClassCode(String content) {
return patternMatcher(content, ".*class.*\\{((.*\\s*)*)\\}", 1);
}
public static String getMethodName(String code) {
String uncommentedCode = removeComments(code).trim();
return patternMatcher(uncommentedCode,
"(public|private|static|protected|abstract|native|synchronized) *([\\w<>.?, \\[\\]]*)\\s+(\\w+)\\s*\\([\\w<>\\[\\]._?, \\n]*\\)\\s*([\\w ,\\n]*)\\s*\\{",
3);
}
public static String removeComments(String content) {
return content.replaceAll("\\/\\*[\\s\\S]*?\\*\\/|([^:]|^)\\/\\/.*$", "$1 ").trim();
}
I double checked but i hope i didn't forget any escape character, be carefull with those.
Lots of people recomended that i used an actual code parsing library, like ANTLR, but i assumed it would take much longer for me to learn how to work with it, then it would take to do with with RegEx. Furthermore i wanted to improve my Regex skills, this exercise definitely taught me some things.
Please give me in any tips with my class.
I want to make a return statement that will return the first word
in my wordList.
import java.util.ArrayList ;
public class WordList {
private ArrayList<String> theWordList = new ArrayList<String>();
public void addWord(String s) {
theWordList.add(s);
}
/* Check point 5: complete the method below */
public String getFirst() {
/* Replace the return statement bel
ow with a statement
* that returns
* the first word of theWordList (the word at index 0).
* Hint: use the ArrayList method "get".
* If there is no first word (theWordList has no words in it),
* "
-
" should be returned.
*/
return "junk";
}
You can make it this way
public String getFirst() {
if(this.theWordList!=null && this.theWordList.size() > 0)
return this.theWordList.get(0);
return "-";
}
Note : I have returned - (hyphen) when there is no first word in the list or the word list is null (which is not going to happen anyway since it is instantiated earlier)
return theWordList.get(0);
Be sure theWordList is not empty anyway
Make your get function as :
public ArrayList<String> getFirst() {
return this.theWordList;
}
And write a main () AS :
public static void main(String args[]){
WordList w=new WordList();
w.addWord("subash");
//Blah
//blahhhhh ....
System.out.println(w.getFirst().get(0));
}
I need a little help on how i could put in a helper method. This is the helper method I wrote.
public static String helper(String help) {
help = help.toLowerCase();
help = help.replaceAll("\\s+", "");
}
and this is how i used it in main method.
String help = RecursivePalindrome.helper(x);
If I keep it like this then on the helper method they ask me for a return value but if i put the return help; then the method doesn't execute correctly. If I change the helper method to void then i cant put String help on my main method.
This is what happens when i run the program:
Enter a word to test whether it is a palindrome or not(press quit to end.): RaceCar
'RaceCar' is not a palindrome.
See i put the helperclass to ignore the upper cases but it wont. RaceCar would be a palindrome but the uppercase makes the program say its not.
I think you need this:
public static String helper(String help) {
help = help.toLowerCase();
help = help.replaceAll("\\s+", "");
help = help.replaceAll("\\p{Punct}", "");
return help;
}
Calling helper will return a String with all characters lowercased and every occurrence of whitespace or punctuation characters removed.
Example: helper("Race Car#") will return "racecar"
Your method should return String. Also String in Java is immutable, any modification of string returns new string. Try this:
public static String helper(String help) {
return help.toLowerCase().replaceAll("\\s+", "");
}
Here is a quick palindrom calculator I created that works for RaceCar.....using ako's helper method.
public class Main {
public static void main(String [] args){
System.out.println(palindrom(helper("RaceCar")));
}
public static String helper(String help){
return help.toLowerCase().replaceAll("\\s+", "");
}
public static boolean palindrom(String pal)
{
int end = pal.length()-1;
for(int i = 0; i<=pal.length()/2;i++)
{
if(pal.charAt(i)== pal.charAt(end-i));
else
{
return false;
}
}
return true;
}
}
I was told in my class that I have to write and test my code in the main method, I wrote it, but I dont know how to test it. How I am supposed to test my methods? I am supposed to take user input, and then get the get the first letter, last letter, etc.
import java.util.Scanner;
public class Word
{
public static void main(String[] args)
{
}
public String word;
public void Word()
{
String word = "";
}
public void Word(String word1)
{
String word = word1;
}
public String getWord()
{
return word;
}
public void setWord(String newWord)
{
String word = newWord;
}
public void getFirstLetter()
{
String firstLetter = word.substring(0, 1);
}
public void getLastLetter()
{
String lastLetter = word.substring(word.length() - 1, word.length());
}
public void removeFirstLetter()
{
String noFirstLetter = word.substring(1, word.length());
}
public void removeLastLetter()
{
String noLastLetter = word.substring(0, word.length() - 1);
}
public int findLetter (String parameter)
{
word.indexOf(parameter);
return 1;
}
}
You test your methods by calling them with some defined input and compare the results with your expected output.
Example:
Suppose you have a method like this:
public static int add(int a, int b) {
return a + b;
}
You'd test it like this:
int result = add( 3, 5);
if( result != 8 ) {
//method is wrong
}
So basically you define a "contract" of what input the method gets and what the result should be (in terms of return value or other changed state). Then you check whether you get that result for your input and if so you can assume the method works correctly.
In order to be quite sure (you often can't be perfectly sure) you'd test the method several times with different types of input (as many as reasonable, to test different cases, e.g. short words, long words).
You often also test how your method handles wrong input, e.g. by passing null or empty strings.
You should have a look at tools like junit.
You can create a simple Test class and test your class and its behavior.
imports ...;
public class MyTest{
#Test
public void testMyClass(){
Word w= new Word();
w.setWord("test");
Assert.assertEquals(w.getFirstLetter(), "t");
}
}
With tools like Eclipse you could nicely run such a test.
Just a hint: you're very close you need an instance of Word, than you can call your methods
public static void main(String[] args) {
Word test = new Word();
test.setWord("something");
// here you might read javadoc of the String class on how to compare strings
}
EDIT:
I overlooked this:
public void setWord(String newWord)
{
String word = newWord;
}
The code you've written creates a variable word and newWord is assigned to it and then disappears.
If you (obviously) want to set a member of a class you should use this wich references the instance (you created in main()).
public void setWord(String newWord) {
this.word = newWord;
}
Since I would say this is homework, I will try not to explicitly give the answer. In the main method, you should set your word, then call each method and print the output to verify it is correct.
Agree with Jason. If you wanna test something, simply System.out.println() it. In your methods though, your return type is not a String but a void, so you could change that, and print it out on the main program run.
If not, just put the System.out.println() in your void methods. Shouldn't have much of a problem!