Custom compare string method throwing indexarrayoutofbounds - java

I have a custom compare method:
public int compareStrings(String one, String two) {
int compareAmount = 0;
if (one.length() == two.length()) {
compareAmount++;
} else {
compareAmount--;
}
int x = 0;
for (char i : one.toCharArray()) {
if (!(x > two.length())) {
if (two.charAt(x) == i) {
compareAmount++;
}
x++;
}
}
return compareAmount;
}
If string one is "Ok" and String two is "Lets give it a go" it throws java.lang.StringIndexOutOfBoundsException: String index out of range: 2. I cannot see were I've gone wrong!

You are going all the way to two.length() instead of stopping at two.length() - 1. This doesn't work since arrays are indexed from 0..length()-1.
Just change your if condition inside the loop to fix the problem:
if (!(x >= two.length())) {

If the length of the String two is 11, the last index is 10. You're just checking if x is NOT greater than the length of two. But it might be equal which is out of bounds. Just change it to >=

Dude, first of all, don't reimplement this kind of algorithms.
Use the compareTo(String) method defined in the String class.
You can also learn from the JDKs source code and see how they implement this method http://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/8c2c5d63a17e/src/share/classes/java/lang/String.java#l1096
If you need a custom comparator for a specific class, you must implement the Comparator interface.
If you are starting to learn java and want to get good at it. At least make a full read of the official Java tutorial by oracle

Related

How do i find how many times a substring is used in a string?

public Object countOccurrences(String string)
{
int e = 0;
int i = 0;
while ( i < sentence.length())
{
if(sentence.contains(string))
{
e++;
i++;
return e;
}
else
{
break;
}
}
return e;
}
What is wrong with my code that won't allow me to pass the test? is there anyway I can use the substring method inside a loop to do this?
#Test
public void testCountOccurrences()
{
assertEquals(1, sc1.countOccurrences("ence"));
assertEquals(2, sc1.countOccurrences("en"));
assertEquals(1, sc2.countOccurrences("that"));
assertEquals(0, sc2.countOccurrences("This"));
}
What is wrong with my code that won't allow me to pass the test?
Before doing anything else, you should consider how you could have worked out what was wrong for your code to start with. Did you debug through it? At what point did it behave differently to how you expected it to? If you haven't learned how to use a debugger yet, now is a great time to start.
As for the next step, look at this code:
if(sentence.contains(string))
{
e++;
i++;
return e;
}
That condition doesn't depend on i or e, just on sentence and string. So as long as sentence is of length at least 1, you'll either return 1 or 0. Your code can never return more than 1.
That's what's wrong with your code at the moment - as for how to fix it, I'd start looking at String.indexOf(String, int). In other words, you want to find the first occurrence, then find the next occurrence, then the next occurrence, until you can't find any more. (Use the return value to work out where to start looking on the next iteration, as well as checking that there was a match.)
A couple of situations to be careful of:
How many times does "abbbc" contain "bb"?
How many times does "abbbc" contain ""?
I'd also urge a couple of other changes:
Your method has a return type of Object - why? Surely it's always going to return an integer, so a return type of int would be more appropriate
This is a great candidate for parameterized testing. Look into how you can effectively separate your single test into multiple test cases which can pass or fail independently, but without the source overhead of lots of test methods... (Hint: each test case should have the sentence, the text you're looking for, and the expected number of matches.)
public Object countOccurrences(String string) {
int e = 0;
int i = 0;
while (i <= (sentence.length() - string.length() + 1)) {
if (sentence.substr(i, string.length() - 1).equals(string)) {
e++;
}
i++;
}
return e;
}
I didn't got to try it myself but it should work.

Java - Complex Recursive Backtracking

For Java practice I started working on a method countBinary that accepts an integer n as a parameter that prints all binary numbers that have n digits in ascending order, printing each value on a separate line. Assuming n is non-negative and greater than 0, some example outputs would look like this.
I am getting pretty much nowhere with this. I am able to write a program that finds all possible letter combinations of a String and similar things, but I have been unable to make almost any progress with this specific problem using binary and integers.
Apparently the best way to go about this issue is by defining a helper method that accepts different parameters than the original method and by building up a set of characters as a String for eventual printing.
Important Note: I am NOT supposed to use for loops at all for this exercise.
Edit - Important Note: I need to have trailing 0's so that all outputs are the same length.
So far this is what I have:
public void countBinary(int n)
{
String s = "01";
countBinary(s, "", n);
}
private static void countBinary(String s, String chosen, int length)
{
if (s.length() == 0)
{
System.out.println(chosen);
}
else
{
char c = s.charAt(0);
s = s.substring(1);
chosen += c;
countBinary(s, chosen, length);
if (chosen.length() == length)
{
chosen = chosen.substring(0, chosen.length() - 1);
}
countBinary(s, chosen, length);
s = c + s;
}
}
When I run my code my output looks like this.
Can anyone explain to me why my method is not running the way I expect it to, and if possible show me a solution to my issue so that I might get the correct output? Thank you!
There are more efficient ways to do it, but this will give you a start:
public class BinaryPrinter {
static void printAllBinary(String s, int n) {
if (n == 0) System.out.println(s);
else {
printAllBinary(s + '0', n - 1);
printAllBinary(s + '1', n - 1);
}
}
public static void main(String [] args) {
printAllBinary("", 4);
}
}
I'll let you work out the more efficient way.

Throw Expected After This Token Error

When I run my code, it gives me an error that says, "Syntax error on token "{", throw expected after this token." The error is on line 7's code.
class WhileLoopTest {
public static void main(String[] args){
apple = 0;
while (apple = 0) {
(int)(Math.random( )*(60) + 5);
return;
}
}
}
on the line while (apple = 0) you are setting the variable instead of declaring it. The while loop expects that you pass it a boolean. You are probably trying to use the comparison equals ==. The full line should read while (apple == 0).
First , you need to define a type for your variable apple because Java is statically type
apple = 0;
Read more About Statically typed vs Dynamically typed
change to
int apple = 0;
Second, (int)(Math.random( )*(60) + 5); is not statement so you need to either print the value or return it
Third, while (apple = 0) { is wrong because compiler looking for Boolean expression
while(Boolean_expression)
{
//Statements
}
change to while (apple == 0 ) {
You need to add an extra equals sign to the condition within the while statement (at the moment you are assigning the value of 0 to apple, instead of texting if it is equal), so it looks like this
while(apple == 0){
Pleas note that the while loop has no function at all, since you are returning within the loop. This will stop your program execution as you are returning from the main method. The computation of a random number doesn't serve a purpose here as you aren't assigning a variable to it or printing it.
Also, you are not defining a type for the apple variable. Try making it of type int.
int apple = 0;
I suggest that you look up some tutorials on java as you seem to misunderstand several concepts within the language.

Recursive method to determine if a string is a hex number - Java

This is a homework question that I am having a bit of trouble with.
Write a recursive method that determines if a String is a hex number.
Write javadocs for your method.
A String is a hex number if each and every character is either
0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9
or a or A or b or B or c or C or d or D or e or E or f or f.
At the moment all I can see to test this is if the character at 0 of the string is one of these values he gave me then that part of it is a hex.
Any hints or suggestions to help me out?
This is what I have so far: `
public boolean isHex(String string){
if (string.charAt(0)==//what goes here?){
//call isHex again on s.substring(1)
}else return false;
}
`
If you're looking for a good hex digit method:
boolean isHexDigit(char c) {
return Character.isDigit(c) || (Character.toUpperCase(c) >= 'A' && Character.toUpperCase(c) <= 'F');
}
Hints or suggestions, as requested:
All recursive methods call themselves with a different input (well, hopefully a different input!)
All recursive methods have a stop condition.
Your method signature should look something like this
boolean isHexString(String s) {
// base case here - an if condition
// logic and recursion - a return value
}
Also, don't forget that hex strings can start with "0x". This might be (more) difficult to do, so I would get the regular function working first. If you tackle it later, try to keep in mind that 0xABCD0x123 shouldn't pass. :-)
About substring: Straight from the String class source:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
offset is a member variable of type int
value is a member variable of type char[]
and the constructor it calls is
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
It's clearly an O(1) method, calling an O(1) constructor. It can do this because String is immutable. You can't change the value of a String, only create a new one. (Let's leave out things like reflection and sun.misc.unsafe since they are extraneous solutions!) Since it can't be changed, you also don't have to worry about some other Thread messing with it, so it's perfectly fine to pass around like the village bicycle.
Since this is homework, I only give some hints instead of code:
Write a method that always tests the first character of a String if it fulfills the requirements. If not, return false, if yes, call the method again with the same String, but the first character missing. If it is only 1 character left and it is also a hex character then return true.
Pseudocode:
public boolean isHex(String testString) {
If String has 0 characters -> return true;
Else
If first character is a hex character -> call isHex with the remaining characters
Else if the first character is not a hex character -> return false;
}
When solving problems recursively, you generally want to solve a small part (the 'base case'), and then recurse on the rest.
You've figured out the base case - checking if a single character is hex or not.
Now you need to 'recurse on the rest'.
Here's some pseudocode (Python-ish) for reversing a string - hopefully you will see how similar methods can be applied to your problem (indeed, all recursive problems)
def ReverseString(str):
# base case (simple)
if len(str) <= 1:
return str
# recurse on the rest...
return last_char(str) + ReverseString(all_but_last_char(str))
Sounds like you should recursively iterate the characters in string and return the boolean AND of whether or not the current character is in [0-9A-Fa-f] with the recursive call...
You have already received lots of useful answers. In case you want to train your recursive skills (and Java skills in general) a bit more I can recommend you to visit Coding Bat. You will find a lot of exercises together with automated tests.

Javabat substring counting

public boolean catDog(String str)
{
int count = 0;
for (int i = 0; i < str.length(); i++)
{
String sub = str.substring(i, i+1);
if (sub.equals("cat") && sub.equals("dog"))
count++;
}
return count == 0;
}
There's my code for catDog, have been working on it for a while and just cannot find out what's wrong. Help would be much appreciated!*/
EDIT- I want to Return true if the string "cat" and "dog" appear the same number of times in the given string.
One problem is that this will never be true:
if (sub.equals("cat") && sub.equals("dog"))
&& means and. || means or.
However, another problem is that your code looks like your are flailing around randomly trying to get it to work. Everyone does this to some extent in their first programming class, but it's a bad habit. Try to come up with a clear mental picture of how to solve the problem before you write any code, then write the code, then verify that the code actually does what you think it should do and that your initial solution was correct.
EDIT: What I said goes double now that you've clarified what your function is supposed to do. Your approach to solving the problem is not correct, so you need to rethink how to solve the problem, not futz with the implementation.
Here's a critique since I don't believe in giving code for homework. But you have at least tried which is better than most of the clowns posting homework here.
you need two variables, one for storing cat occurrences, one for dog, or a way of telling the difference.
your substring isn't getting enough characters.
a string can never be both cat and dog, you need to check them independently and update the right count.
your return statement should return true if catcount is equal to dogcount, although your version would work if you stored the differences between cats and dogs.
Other than those, I'd be using string searches rather than checking every position but that may be your next assignment. The method you've chosen is perfectly adequate for CS101-type homework.
It should be reasonably easy to get yours working if you address the points I gave above. One thing you may want to try is inserting debugging statements at important places in your code such as:
System.out.println(
"i = " + Integer.toString (i) +
", sub = ["+sub+"]" +
", count = " + Integer.toString(count));
immediately before the closing brace of the for loop. This is invaluable in figuring out what your code is doing wrong.
Here's my ROT13 version if you run into too much trouble and want something to compare it to, but please don't use it without getting yours working first. That doesn't help you in the long run. And, it's almost certain that your educators are tracking StackOverflow to detect plagiarism anyway, so it wouldn't even help you in the short term.
Not that I really care, the more dumb coders in the employment pool, the better it is for me :-)
choyvp obbyrna pngQbt(Fgevat fge) {
vag qvssrerapr = 0;
sbe (vag v = 0; v < fge.yratgu() - 2; v++) {
Fgevat fho = fge.fhofgevat(v, v+3);
vs (fho.rdhnyf("png")) {
qvssrerapr++;
} ryfr {
vs (fho.rdhnyf("qbt")) {
qvssrerapr--;
}
}
}
erghea qvssrerapr == 0;
}
Another thing to note here is that substring in Java's built-in String class is exclusive on the upper bound.
That is, for String str = "abcdefg", str.substring( 0, 2 ) retrieves "ab" rather than "abc." To match 3 characters, you need to get the substring from i to i+3.
My code for do this:
public boolean catDog(String str) {
if ((new StringTokenizer(str, "cat")).countTokens() ==
(new StringTokenizer(str, "dog")).countTokens()) {
return true;
}
return false;
}
Hope this will help you
EDIT: Sorry this code will not work since you can have 2 tokens side by side in your string. Best if you use countMatches from StringUtils Apache commons library.
String sub = str.substring(i, i+1);
The above line is only getting a 2-character substring so instead of getting "cat" you'll get "ca" and it will never match. Fix this by changing 'i+1' to 'i+2'.
Edit: Now that you've clarified your question in the comments: You should have two counter variables, one to count the 'dog's and one to count the 'cat's. Then at the end return true if count_cats == count_dogs.

Categories

Resources