This is what I have so far, I managed to reach here with several hours of work. The problem with my code is that if i give it a string "abcefg" it will verify the first two characters and returns it as true. I want the code to do it for all of my characters. I thought that putting the limit as x.length() would do the thing, but for some reason, it won't work.
public static boolean ConsecutiveCheckerAscending(String x) {
x = x.toLowerCase();
for (int i = 0; i < x.length() - 1; i++) {
if ((int)x.charAt(i) + 1 != ((int)x.charAt(i + 1)))
{
return false;
}
}
return true;
}
public static boolean ConsecutiveCheckerDescending(String x) {
x = x.toLowerCase();
for (int i = 0; i < x.length() - 1; i++) {
if((int)x.charAt(i) - 1 != ((int)x.charAt(i + 1)))
{
return false;
}
}
return true;
}
You have a variety of issues here.
Firstly, you can eventually go out of bounds with the charAt(i + 1) calls (check your loop condition).
Secondly, how can you possibly return true in the body of the for-loop? You haven't checked all of the characters yet!
I think you're making this overly complicated, though. All you need to do in order to check that two contiguous (i.e. next to each other in the string) characters are consecutive is
Math.abs(s.charAt(i) - s.charAt(i + 1)) == 1
You actually don't even need a cast. What we're doing is checking that the "distance" between the two characters is 1.
Just apply that to every contiguous pair of characters in the string, and return false if it isn't satisfied somewhere along the line. If you exit the loop without ever returning false, you can return true.
You cannot know for sure if the string is consecutive until the end of the method, so you cannot return true in the middle. At most you can return false when you find that string is not consecutive.
To give more advice, what do you mean by "consecutive"? Is adgkm consecutive? Looking at the current code it would look like it; all you check is the order of the characters. Is abcdcbcd consecutive? Usually "consecutive" means there are no gaps.
In both if and else statements you having return statement, So the method will return after first check. You have to give return only for the exit condition. don't give for both if and else
Wrote it in a rush, but it'd look something like this.-
public static boolean ConsecutiveChecker(String x) {
boolean consecutive = true;
x = x.toLowerCase();
for (int i = 0; i < x.length() - 1; i ++) {
if ((int) x.charAt(i) + 1 != ((int) x.charAt(i + 1))) {
consecutive = false;
break;
}
}
return consecutive;
}
Related
I am trying to solve a question in which I am given a String array of words and I have to check whether they have all same length or not. For instance if am given the array {"apple","purple","lemon"} then my method should return true, and when I am given the array {"red","blue"}, it should return false.
This is what I did so far but it is not working. I appreciate any help.
public static boolean allEqualLength(String[] myArray){
int i;
for(i=0;i<myArray.length;i++){
if(myArray[i]!=myArray[i+1])
return false;
}
return true,
}
All items having the same length is equivalent to saying all items must have the same length as the first item:
public static boolean allEqualLength(String[] myArray) {
// zero items => "all" items have same length:
if (myArray.length == 0) return true;
final int expectedLength = myArray[0].length();
for(int i = 0; i < myArray.length; ++i) {
if(myArray[i].length() != expectedLength)
return false;
}
return true,
}
But your original solution was not that far off. You just need to make sure not to exceed the array's bounds and to compare the string lengths, not the strings themselves:
public static boolean allEqualLength(String[] myArray) {
for(int i=0; i < myArray.length - 1; i++) { // -1 to not exceed bounds
if(myArray[i].length() != myArray[i+1].length()) // compare length, not memory addresses
return false;
}
return true,
}
I world do something like that:
public static boolean allEqualLength(String[] myArray) {
int strLength = myArray[0].length();
for (String str :
myArray) {
if (str.length() != strLength)
return false;
}
return true;
}
Like that you can avoid any indexing problems in your loop.
You are trying to compare the strings themselves. You should compare the length only.
myArray[i].length() != myArray[i + 1].length()
By the way, this will throw an ArrayIndexOutOfBoundsException, because you are trying to access index myArray[myArray.length]. Change the for loop to
for (int i = 0; i < myArray.length - 1; i++) {
if (myArray[i].length() != myArray[i + 1].length()) {
return false;
}
}
Also make sure you return true if the array length is 0 or 1, because the loop can't handle those.
For example you have array with length 4 , you have the positions 0,1,2,3 so in your code you run with : myArray[i]!=myArray[i+1] so on the last run you check the positions :
3 and 4 and you will get ArrayIndexOutOfBoundsException , you need to change to : length-1 on the loop condition like this :
public static boolean allEqualLength(String[] myArray){
int i;
for(i=0;i<myArray.length -1;i++){
if(myArray[i].length() != myArray[i+1].length())
return false;
}
return true,
}
If you run on myArray.length ,the positions that check :
0--1
1--2
2--3
3--4 // ERROR !!! ArrayIndexOutOfBoundsException !!
If you run on myArray.length-1 ,the positions that check :
0--1
1--2
2--3 -OK !!!
So on this way if you run the array with : myArray.length-1 , you will not get ArrayIndexOutOfBoundsException .
First things first you are not checking element lengths other issue is your for loop would try to access array index out of bounds since you have i+1, last element is already being checked that way, considering that you just need for until myArray.length - 1.
Using your code it would look something like this:
public static boolean allEqualLength(String[] myArray) {
for (int i = 0; i < myArray.length - 1; i++) {
if (myArray[i].length() != myArray[i + 1].length())
return false;
}
return true;
}
If performance is not an issue and you will not use it in 1 million strings or something, in addition to all these answers, here is an one liner:
boolean allStringsEqualLength = Stream.of(array)
.map(String::length).distinct().count() == 1;
The idea is to map each string to its length. So if distinct() stream contains only one value, that means all strings had the same length.
This method is supposed to return true if four different numbers in the array are all equal. But whenever I try to run it with 4 equal numbers, I get an error that says:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Assignment4.containsFourOfaKind(Assignment4.java:93)
at Assignment4.main(Assignment4.java:16)
public static boolean containsFourOfaKind( int hand[] ){
for (int i = 0; i < 5; i++) {
if (hand[i ] == hand[i + 1] &&
hand[i + 1] == hand[i + 2] &&
hand[i + 2] == hand[i + 3]
) {
return true;
}
}
return false;
}
How can I fix this?
Most answers only address the ArrayIndexOutOfBoundsException, but they don't address that your original code wasn't detecting for of a kind. It was trying to detect four-in-a-row. Imagine a hand {3, 0, 3, 3, 3}: even if your code didn't cause the ArrayIndexOutOfBoundsException, it still would say that this wasn't four-of-a-kind, although it clearly is.
You need code that actually counts how many of-a-kind there are and then check if it is four or more out of the total hand. (In a typical playing card deck you couldn't have more than 4 of a kind so you can check with == to 4 as well)
The code below is even agnostic to the number of cards in a hand, although from your code above it looks like your hand size is 5 (which is very typical in poker)
public static boolean containsFourOfaKind(int hand[]) {
for (int i = 0; i < hand.length; i++) {
int countOfKind = 0;
for (int j = 0; j < hand.length; j++) {
if (hand[i] == hand[j]) {
countOfKind++;
}
}
if (countOfKind >= 4) {
return true;
}
}
return false;
}
(Note that this is a native approach. You can optimize this further; for example if you look at this closely you'll see that i doesn't have to go any further than 0 and 1.)
When you run your loop from (i=0; i<5;...) you are checking five values... In your if statement you are looking at hand[i] == hand[i+1] && hand[i+1] == hand[i+2] && hand[i+2] == hand[i+3]. This means that during the iteration when i=4 you are trying to access hand[4] through to hand[7].
I suspect your array, hand, doesn't have that many elements.
public static boolean containsFourOfaKind(int hand[]){
for(int x=0; x < hand.length; x++){
for(int y=0; y < hand.length; y++){
if(y!=x){
if(hand[x]!=hand[y]){
return false;
}
}
}
}
return true;
}
You were going outside the index using the +1 within the loop. The above code checks to see if all of the elements in the array are the same.
While others have addressed the ArrayIndexOutOfBoundsException quite clearly, I'd like to propose another method that uses no indexes:
private boolean isArrayEqual(int[] array) {
Arrays.sort(array); //Sort array to place four of a kind in sequence
int[] setOfFour = Arrays.copyOfRange(array, 0, 4); //Copy first four values
int[] compareArray = new int[4];
Arrays.fill(compareArray, setOfFour[0]); //Make an array containing only first value
if (Arrays.equals(compareArray, setOfFour)) { //Test if first four are equal
return true;
} else { //Test is last four are equal
setOfFour = Arrays.copyOfRange(array, 1, 5); //Copy of last four values
Arrays.fill(compareArray, setOfFour[0]);
return Arrays.equals(compareArray, setOfFour);
}
}
You create a second array which is filled with one of the values from the array in question (any value will do - I picked the first one). Then just see if the arrays are equal. Done.
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
for(int i=0; i < hand.length - 1; i++)
{
if(hand[i] != hand[i + 1])
return false;
}
return true;
}
Going with your approach you could have had a simple check that was non-iterative that would just check to see if all the four cards were equal, however if you're going for an iterative approach then this is probably your best bet. Whenever you receive an arrayindexoutofbounds exception you always know that it has something to do with your arrays, and in your case there is only one spot that deals with arrays so it should be easy to visualize once you know what t he exception means.
A noniterative approach is as follows...
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
if((hand[0] == hand[1]) && (hand[1] == hand[2]) && (hand[2] == hand[3]))
return true;
return false;
}
This can be used however it is not recommended.
An approach that doesn't specifically target a hand, could be to target a larger group; where the array could be much larger than 4. In this case, you could have a loop add onto a map that counts how many times a certain "object" (literal meaning) is in that list:
public static boolean fourOfaKind(Integer[] hand) {
HashMap<Integer,Integer> counts = new HashMap<Integer,Integer>();
for(Integer i : hand) {
if(counts.containsKey(i))
{
int count = counts.get(i);
counts.put(i, ++count);
if(count >= 4)
return true;
}
else
counts.put(i, 1);
}
return false;
}
simple code can be as follows, this will work for N number of element.
public static boolean containsFourOfaKind(int hand[]){
for(int i=1; i < hand.length; i++){
if(hand[i-1] != hand[i]){
return false;
}
}
return true;
}
In Java8 you can do it very easy:
private static boolean isEqualElements(int[] arr) {
return Arrays.stream(arr).allMatch(value -> arr[0] == value);;
}
Im trying to write a method that takes in an ID of the form "xxxx-xxxx" (x being any number 1-9) and checks to see if the ID entered is valid. For example, 1111-1111 would be valid, but 111p-1111 or 11111-1111 would not be. However, after I have written this method, it comes out as true even when the ID is of the form 111p-1111.
public static boolean idCheck(String ID){
char[] idChar = ID.toCharArray();
boolean firstHalf = false;
boolean secHalf = false;
for (int i = 0; i < 5; ++i){//Check first half
if ((idChar[i] > 47 && idChar[i] < 58)){//Checks ascii vals to see if valid ID
firstHalf = true;
}
}
for (int i = 5; i < idChar.length; ++i){//Check second half
if ((idChar[i] > 47 && idChar[i] < 58)){//Checks ascii vals to see if valid ID
secHalf = true;
}
}
//If all values are valid, returns true.
if (firstHalf == true && secHalf == true && idChar[4] == '-' && ID.length() == 9){
return true;
}
return false;
}
Using a regular expression would be much simpler in this case:
\d{4}-\d{4}
In Java:
static boolean idCheck(String id) {
return id.matches("\\d{4}-\\d{4}");
}
If you're unfamiliar with regular expressions, here's an explanation:
\d Match a digit 0-9
{4} Repeat last token 4 times (matches 4 digits)
- Match a hyphen literally
\d Match a digit 0-9
{4} Repeat last token 4 times (matches 4 digits)
Your if statements only look at one number to determine if it sets the boolean to true. So if any of the numbers in each half are valid, the boolean will be set to true.
You are probably better off using regular expressions. regexr.com is a great resource to get started! :)
Something like:
[1-9]{4}-[1-9]{4} (You can also use \d)
You only check if there is at least one character that matches, not if any of the input characters are failing.
To have a quick solution that is easy to understand for any Java developer after you you could use a Regex and check if your input matches:
public static boolean idCheck(String id){
return Pattern.matches("\\d{4}-\\d{4}", id);
}
If you want to keep your way of checking you should start with true booleans and check if they stay true.
boolean firstHalf = true;
boolean secHalf = true;
and therefrom use firstHalf &= true for your updates and use a else{ firstHalf = false; } branch.
To keep your method I would prefer to always back out fast if you know the result:
public static boolean idCheck(String id)
{
//check length
if (id.length() != 9)
return false;
char[] idChar = id.toCharArray();
//check for dash
if (idChar[4] != '-')
return false;
//check first half
for (int i = 0; i < 5; ++i)
{
if (!(idChar[i] > 47 && idChar[i] < 58))
return false;
}
//check second half
for (int i = 5; i <= 10; ++i)
{
if (!(idChar[i] > 47 && idChar[i] < 58))
return false;
}
}
I am trying to write a basic java program to compress a java string from an input; such as aabbccdddd, into a2b2c2d4. The program does what I ask except it doesn't process the last char, I am getting an output of a2b2c2 instead of the a2b2c2d4. What am I doing wrong?
for(x = 0, y = 1; x<input.length()-1; x++)
{
if (input.charAt(x) != input.charAt(x+1) && count == 1)
{
System.out.print(input.charAt(x));
System.out.print(count);
}
else if (input.charAt(x) == input.charAt(x+y))
{
count++;
}
else if (input.charAt(x) != input.charAt(x+1) && count >= 2)
{
System.out.print(input.charAt(x));
System.out.print(count);
count = 1;
}
else
{
System.out.println("fail");
}
}
You print the count when the next character is not same as the current one. There is no next character for the last character. That is why it is not displayed in the output.
Approach 1
You should add following two lines after the loop:
System.out.print(input.charAt(input.length()-1));
System.out.println(count);
Approach 2
If you do not have problem with modifying the original input. You can add a additional character in the end of the input. This additional character must be a character which will never appear in the original string. Say it is #
Do this before beginning of the loop:
input += "#";
for(...)
The loop is incorrect, you have "-1" after input.length(). Try:
for(x = 0, y = 1; x<input.length(); x++) {
// CODE HERE...
}
Your for loop ends before you hit a condition that forces you to print out what's being buffered, ie. count of 4 for the current (last) character. You need to print out the last character and the current count after the loop.
The following should do what you want
public static void main(String[] args) throws Exception {
String input = "aabbccdddd";
int count= 1;
int x, y;
for (x = 0, y = 1; x < input.length() - 1; x++) {
char charAtX = input.charAt(x);
char charAtXPlus1 = input.charAt(x + 1);
if ( charAtX != charAtXPlus1 && count == 1) {
System.out.print(input.charAt(x));
System.out.print(count);
}
else if (charAtX == input.charAt(x + y)) {
count++;
}
else if (charAtX != charAtXPlus1 && count >= 2) {
System.out.print(input.charAt(x));
System.out.print(count);
count = 1;
} else {
System.out.println("fail");
}
}
System.out.print(input.charAt(x));
System.out.println(count);
}
You should learn how to use a proper debugger and use proper debugging techniques. For example, I've assigned the value returned by input.charAt(x) to a variable because we reuse that value in the various if-else conditions and because it's easier to see it in a debug window.
You are not able to get the desired result because of the condition
else if(input.charAt(x)!=input.charAt(x+1)&&count>=2)
that fails as there is not character at x+1 location.
So, you could add another condition to check if it's the last character and then go ahead with your code
while (input.charAt(x) != input.length()-1)
So im working on java codingbat and this is the question:
Given a string, look for a mirror image (backwards) string at both the beginning and end of the given string.
In other words, zero or more characters at the very begining of the given string, and at the very end of the string in reverse order (possibly overlapping).
For example:
the string "abXYZba" has the mirror end "ab". mirrorEnds("abXYZba") → "ab" mirrorEnds("abca") → "a" mirrorEnds("aba") → "aba" .
My code passed all the test except for the other test, which is not specified. I dont know what's wrong with it.
public String mirrorEnds(String string) {
String input = string, mirror = "";
int length = string.length();
for (int n = 0; n < (length+1) / 2; n++) {
if (input.charAt(n) != input.charAt(length - n - 1)) {
break;
}else if(length%2 == 1 && n == (length - 1)/2){
// System.out.println("length/2 = " );
return input;
}
else {
mirror += input.charAt(n);
}
}
return mirror;
}
You were correct in not needing to go though the entire word, but your logic is more complex than it needs to be, making it harder to find and fix the problem. The root cause of the test failure is in the last return statement. It must return string if the loop completes without breaking. You can fix your code by changing break; to return mirror; and changing the last return mirror; to return input;
The test that is failing is one like this:
mirrorEnds("abba") -> "abba"
A much simpler version of your code can be created like this:
public String mirrorEnds(String string) {
int len = string.length();
for (int i=0; i < len/2; ++i)
if (string.charAt(i) != string.charAt(len - 1 - i))
return string.substring(0, i);
return string;
}
mirrorEnds("abba")?
Anyways, I'm sure you could come up with a better question name than "some weird stuff"...
Since you are dividing n by 2 in your loop termination condition, it will end when halfway through the word. This is enough to tell the word is a palindrome, but not enough to build your output correctly. You have a condition handling palindrome with odd numbers of letter, but not even numbers of letters. I believe the failing test will be of the form "abba", where I believe what you have will return "ab", instead of "abba".
If you change you loop to:
for (int n = 0; n < length; n++) {
I believe it should be doing what you want. This also makes the short circuit case unnecessary, so:
for (int n = 0; n < length; n++) {
if (input.charAt(n) != input.charAt(length - n - 1)) {
break;
}
else {
mirror += input.charAt(n);
}
}
The first test I tried was with the string "abba" which fails. It returns ab, and not abba. As femtoRgon mentioned, you're not going through the entire word, which may some times be necessary. femtoRgon's solution works, as well as taking a slightly different approach to iterating through the word as follows:
public String mirrorEnds(String string) {
boolean matches = true;
StringBuilder mirrorEnd = new StringBuilder();
int index = 0;
while (matches && index < string.length()) {
if (string.charAt(index) == string.charAt(string.length() - index - 1))
mirrorEnd.append(string.charAt(index));
else
matches = false;
index++;
}
return mirrorEnd.toString();
}
public String mirrorEnds(String string) {
String comp="";
for(int i=0; i<string.length(); i++){
if(string.charAt(i)==string.charAt(string.length()-(i+1)))
comp= comp+ string.charAt(i);
else break;
}
return comp;
}