I'm trying to implement a method that finds the highest index of common digit between two ints like so:
a = 2224 , b = 4222 the result would be index = 2, which means the index is in reverse. I managed to find the first common digit, but I'm having trouble finding the last common digit. This the method to find the first common digit:
private static int getLowestIndexWithSameDigit(int a, int b) {
if (a < 0 || b < 0)
throw new IllegalArgumentException("Ambos os argumentos devem ser positivos: " + a + " " + b);
else {
if (a % 10 == b % 10) {
return indice;
} else if (a / 10 != 0 && b / 10 != 0) {
indice++;
return getLowestIndexWithSameDigit(a / 10, b / 10);
} else {
return -1;
}
}
}
And the method to initialize index as 0 everytime getLowestIndexWithSameDigit is used:
private static void test_getLowestIndexWithSameDigit(int a, int b) {
try {
System.out.print("getLowestIndexWithSameDigit (" + a + ", " + b + ") = ");
indice = 0;
int res = getLowestIndexWithSameDigit(a, b);
System.out.println(res);
} catch (IllegalArgumentException e) {
System.out.println("Erro: " + e.getMessage());
}
}
I was trying to adapt this method in some way, but I don't think it's adaptable to find the last common digit. Any help is appreciated.
It might be simpler to convert the ints to Strings:
//you can overload method to support other primitives
private static int getHighestIndexWithSameDigit(int a, int b) {
String aS = String.valueOf(a);
String bS = String.valueOf(b);
return getHighestIndexWithSameDigit(aS, bS);
}
//helper method to set strat index
private static int getHighestIndexWithSameDigit(String aS, String bS) {
return getHighestIndexWithSameDigit(aS, bS, 1);
}
//recursively check first letter. First index is 1 - indicates first char from left
private static int getHighestIndexWithSameDigit(String aS, String bS, int index) {
int aLength = aS.length(), bLength = bS.length();
if((aLength == 0) || (bLength == 0)) { return -1;}
if(aS.charAt(0) == bS.charAt(0)) { return index; }
//remove first letters, update index
return getHighestIndexWithSameDigit(aS.substring(1, aLength),
bS.substring(1, bLength), ++index);
}
Test by System.out.println(getHighestIndexWithSameDigit(2224 , 4222) );
Edit:
The code posted assumed that the first index is 1 (1 base), where index of value 1 indicates the first digit from left.
If you meant to use 0 base index, counting from right two of the method should change slightly :
//helper method to set start index.
private static int getHighestIndexWithSameDigit(String aS, String bS) {
return getHighestIndexWithSameDigit(aS, bS, aS.length()-1);
}
//recursively check first letter. Index 0 - indicates last char
private static int getHighestIndexWithSameDigit(String aS, String bS, int index) {
System.out.println(aS +" "+ bS);
int aLength = aS.length(), bLength = bS.length();
if((aLength == 0) || (bLength == 0)) { return -1;}
if(aS.charAt(0) == bS.charAt(0)) { return index; }
return getHighestIndexWithSameDigit(aS.substring(1, aLength),
bS.substring(1, bLength), --index);
}
Getting the lowest or the highest should only be a matter of when you stop the loop, no?
The slightly rewritten version of your code below did the trick for me at least.
private static int getDatIndex(int a, int b, boolean getDatLow) {
int indice = -1;
int index = 0;
while (a/10 != 0 && b/10 != 0) {
if (a % 10 == b % 10) {
indice = index;
// If you want the lowest common digit index: stop the loop.
if (getDatLow) {
break;
}
}
a = a/10;
b = b/10;
index++;
}
return indice;
}
Related
I had a test exam in java, that almost no one have succeeded in this question and I can't figure out the solution.
The question was like this:
Find the sum of an integer last and first number. For example 1234-->5, 137-->8, 4-->8. You are only allowed to use recursion and no helper function"
I tried various things. Here is my last attempt:
public static int sumOfFirstandLastdigits(int number)
{
int lastdigit=sumOfFirstandLastdigits(number/10);
if(number/10==0)
{
return number%10;
}
return lastdigit+sumOfFirstandLastdigits(number%10);
}
Assuming the input is supposed to be non-negative:
//If n < 0, return first digit of -n
//Otherwise, return sum of first and last digits of n
int sumLastAndFirstDigit(int n) {
if (n < -9)
return sumLastAndFirstDigit(-(-n/10));
if (n <= 0)
return -n;
if (n < 10)
return n+n;
return n%10 + sumLastAndFirstDigit(-(n/10));
}
You can do this by overloading the method and passing the last digit as a second parameter to keep track of it through the recursion without changing the value (AKA Default Parameter):
public static void main(String[] args) {
System.out.println(sumDigits(3891901));
System.out.println(sumDigits(1234));
System.out.println(sumDigits(5678));
}
private static int sumDigits(int i) {
return sumDigits(i, i % 10);
}
private static int sumDigits(int i, int j) {
if (i / 10 == 0) {
return i % 10 + j;
}
return sumDigits(i / 10, j);
}
Output:
4
5
13
This thread on default parameters might help learn more as well.
Found a solution using String, not sure it's the best :
public int sumLastAndFirstDigit(Integer firstDigit, int number) {
String numberAsString = String.valueOf(number);
//Set the first digit
if(firstDigit == null) {
firstDigit = Integer.valueOf(numberAsString.substring(0,1));
//If there is only one digit in number for the first loop, then return 2 x firstDigit
if(numberAsString.length() == 1) {
return 2 * firstDigit;
}
}
//Remove the first digit to create the new number
String newNumberAsString = numberAsString.substring(1);
Integer newNumber = Integer.valueOf(newNumberAsString);
if(newNumberAsString.length() == 1) {
//When it's the last digit, sum first and last
return firstDigit + newNumber;
}
return sumLastAndFirstDigit(firstDigit, newNumber);
}
Then do :
sumLastAndFirstDigit(null,1234);
sumLastAndFirstDigit(null,137);
sumLastAndFirstDigit(null,4);
Use the sign as a flag to recognize the initial call. Only works with positive numbers, of course.
public static int sum(int value){
if(value > 0)
// initial call
return value % 10 + sum(-value);
else
// recursive call
return -value < 10 ? -value : sum(value / 10);
}
This are the 2 different solutions my professor suggested, although he said no helper (the first one is without an helper).
public static int sumFirstAndLast2(int num) {
if (num < 10 )
return num+num;
return sumFirstAndLast2(num/10) - num%100/10 + num%10;
}
public static int sumFirstAndLast(int num) {
if ( num < 10 )
return num+num;
return sumFirstAndLastHelper(num,true);
}
private static int sumFirstAndLastHelper(int num, boolean isLast) {
if ( isLast )
return num%10 + sumFirstAndLastHelper(num/10,false);
if ( num < 10 )
return num;
return sumFirstAndLastHelper(num/10,false);
}
My assignment is to create a recursive method makeDecimal that when passed a number (that is represented by a String) and its base, converts the number to base 10. You will need to use the method Integer.parseInt(str). (Hint: use substrings.) This method takes a String and returns the integer form of it.
For example, Integer.parseInt("21"); will return the int 21.
Here are some examples of how makeDecimal works:
makeDecimal("11", 2) will return 3.
makeDecimal("100", 4) will return 16.
Here was my attempt at it:
public static double makeDecimal(String number, int base){
int len = number.length();
double f = 0;
if(len <= 0)
return 0;
else{
makeDecimal(number,base);
double temp = Integer.parseInt(number.substring(len - 1, len + 1));
f = f + temp * Math.pow(3, len-1);
}
len--;
return f;
}
However, I get an "overflow error", and I don't know if it even is written correctly.
You are recursing with exactly the same arguments that were passed in. As a result, the call will itself recurse the same way, until the stack overflows. That's not how recursion is supposed to work. Instead, you need to figure out how to do one piece of the problem in the current call and then recurse to do a smaller problem.
In your code, it's not even clear what logic you are using. (What's the point of computing 3len-1?) Try this instead:
If the input string has length 0, the answer is 0 (that part you got right)
Otherwise, take the last digit and parse it in the current base. Then the answer is that value plus base times the value of everything up to but not including the last digit of the input. (Hint: this is a good place to use recursion.)
You should be able to translate that description into the appropriate method calls and use of substring().
Oh, one other thing: there's no reason to be using double values here. Just stick with int variables throughout. You won't be needing Math.pow().
Here is simplest solution using recursion, substring and Integer.parseInt:
public int makeDecimal(String value, int base) {
// exit from recursion
if (value.length() < 1)
return 0;
//parsing last character of string
int charValue = Integer.parseInt(value.substring(value.length() - 1), base);
//calling recursion for string without last character
return makeDecimal(value.substring(0, value.length() - 1), base) * base + charValue;
}
Here's my solution after writing the prototype in Python (if you are interested, I can also include the Python source code):
import java.util.HashMap;
import java.util.Map;
public class MakeDecimal {
public static final Map<Character, Integer> alphabet = buildAlphabetTable();
public static void main(String[] args) {
// System.out.println(alphabet);
System.out.println(makeDecimal("af10bb1", 16));
}
// pos refers to the position of the character in the string.
// For example, if you have the following binary string 100
// then 1 at the left is at position 2,
// the 0 in the middle is at position 1,
// and the right most 0 is at position 0
// (you start counting from the right side).
// In general, you would convert that string in the following way:
// 2^2 * 1 + 2^1 * 0 + 2^0 * 0 = 4
// If the base was n, then you would have
// first * n^{pos + "length of string - 1"} + ... + penultimate * n^{pos + 1} + last * n^{pos}
// Note that pos starts from 0.
private static int makeDecimal(String s, int base, int pos) {
if (s.length() == 0) {
return 0;
} else {
int last = (int) Math.pow(base, pos) * alphabet.get(s.charAt(s.length() - 1));
return makeDecimal(s.substring(0, s.length() - 1), base, pos + 1) + last;
}
}
public static int makeDecimal(String s, int base) {
if (s.length() == 0) {
return 0;
}
if (base < 2 || base > 36) {
throw new IllegalArgumentException("not base >= 2 and base <= 36");
}
return makeDecimal(s.toLowerCase(), base, 0);
}
// Creates a table that maps characters to their decimal value
// the characters can be also '0' or '2' (or any other character number)
// or they can be a character of the English alphabet
private static Map<Character, Integer> buildAlphabetTable() {
Map<Character, Integer> a = new HashMap<>(36);
int i = 0;
for (char c = '0'; c <= '9'; c++, i++) {
a.put(c, i);
}
for (char c = 'a'; c <= 'z'; c++, i++) {
a.put(c, i);
}
return a;
}
}
My solution is based on the following post, which you should definitely read to refresh your ideas on how to convert between bases.
http://www.purplemath.com/modules/numbbase.htm
It does not accept bases that are smaller than 2 or greater than 36. It handles also when you pass English characters in upper case.
Edit: At first I've misted that recursion is obligated for this solution so my original answer without it could me four below.
Here is solution with recursion and without substring and Math.pow:
public double makeDecimal(String value, int base) {
makeDecimal(value, base, value.length() - 1);
}
public double makeDecimal(String value, int base, int index) {
double result = 0;
if (index < 0)
return result;
double charValue = 0;
char currentChar = values.get(Character.toUpperCase(value.charAt(index));
if (currentChar >= 0 && currentChar <= '9') {
charValue = currentChar - '0';
} else if (currentChar >= 'A' && currentChar <= 'Z') {
charValue = currentChar - 'A';
} else {
throw new InvalidValueException("Unsupported character '" + currentChar + "'.");
}
if (charValue >= base) {
throw new InvalidValueException("Wrong character '" + currentChar + "' for base '" base + "'.");
}
return makeDecimal(value, base, index - 1)) * base + charValue;
}
Original Answer: Something like this should work for any base starting from 2 till 36:
private Map<Character, Integer> getCharValues(int base)
{
Map<Character, Integer> values = new HashMap<Character, Integer>();
for (int i = 0; i < base; i++){
if (i < 10) {
values.put('0' + i, i);
} else if (i < 36) {
values.put('A' + i - 10, i);
} else {
throw new InvalidValueException("Base '" + base + "' not supported");
}
}
return values;
}
public double makeDecimal(String value, int base)
{
Map<Character, Integer> charValues = getCharValues(base);
double result = 0;
for (int i = 0; i < value.length(); i++){
result = result * base + charValues.get(Character.toUpperCase(Character.toUpperCase(value.charAt(i))));
}
return result;
}
If you need base more then 36 you can extend char set in method getCharValues. Also it will be a good idea do not create HasMap every time but just store it for maximum base and throw exception if char value exceed given base.
public class A4work
{
private static int fibonacci(int n) {
if (n <= 1) {
return n;
}
{
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
private static boolean isAfibonacci(int a) {
int x = 0; //sequence number
int c = 0; //number in fib sequence
while (a <= c) {
c = fibonacci(x);
x++;
}
if (a == c) {
return true;
} else {
return false;
}
}
public static void main(String[] args) //called a method signiture
{
System.out.println("The 5th Square pyramidal number is " + isAfibonacci(3));
}
}
I think I have the code right, but it keeps on returning false. I'm using it to decide if a number is in the fib sequence or not.
Thanks for the help
When you use System.out.println("The 5th Square pyramidal number is "+ isAfibonacci(3) );, a in your isAfibonacci(); method becomes 3. Now look at your code knowing that.
while(3 <= 0) //replaced a with 3 here and c with 0 for visualization
{
...
}
A non-negative, non-zero integer will never be less than or equal to 0, therefore, will always result in false.
If your input a is 5, for example, you will have:
int c = 0; //number in fib sequence
while (a <= c) { ... }
The while loop will never run since 5 <= 0 is false. So a == c will always be false for any a greater than zero.
I think you want to stop iterating when c is greater than or equal to a, so the correct condition would be
while (c < a) { ... }
For a programming assigment:
Create a recursive method in java that for example for n = 5 returns
1
.2
..3
...4
....5
...4
..3
.2
1
(let the point be spaces or tabs)this has been quite a headache im just started this course so im in beginner level and so far i have this
public String Esc(int n){
if (n <= 1)
return ""+n;
else
return n + "\n" + Esc(n - 1) + "\n" + n;
}
that returns
5
4
3
2
1
2
3
4
5
so im not even close and im still missing the spaces problem
thanks for helping
What you need is to do what you were doing, except backward. The way I found to do it was to basically have a counter going UP to the number n instead of going DOWN from n to 1.
Like this:
public static String esc(int n) {
return esc(1, n); // start at 1, go to n
}
// i counts from 1 to n and then stops at n
public static String esc(int i, int n) {
if (i == n) {
return getDots(i - 1) + i; // base case
}
else {
return getDots(i - 1) + i + "\n" + esc(i + 1, n) + "\n" + getDots(i - 1) + i;
}
}
// this method just generates n number of dots for the spacing
public static String getDots(int n) {
String dots = "";
for (int i = 0; i < n; i++) {
dots += ".";
}
return dots;
}
public static void main(String[] args) {
System.out.println(esc(5)); // call the function
}
So you can see that I recursively call the function using esc(i + 1, n) instead of n - 1. I'm counting i up by 1 each time until I reach n.
As for the use of the getDots method: The dots in front of each of the number happens to be that number subtract 1. So whenever the number is displayed (which is i), just display i - 1 dots in front of it.
Output:
1
.2
..3
...4
....5
...4
..3
.2
1
Shortest and easiest:
Demo: Press Start
Code ( first call set m to zero - see in the demo):
public static String Esc(int n, int m){
m = m + 1;
String s = "";
for ( int i= 0; i< (m-1); i++ ) s += '.';
if (n == m) return s + m;
return s + m + "\n" + Esc(n,m) + "\n" + s + m;
}
And even shorter:
public static String Esc(int n, int m) {
String s = "";
for (int i= 0; i< (m); i++) s += '.';
return n == m+1 ? s+(m+1) : s+(m+1)+"\n"+ Esc(n,m+1) +"\n"+s+(m+1);
}
And Even Shorter and without a for loop!! Demo: Press Start
public static String Esc(int n, int m) {
String s = new String(new char[m]).replace("\0", ".");
return n == m+1 ? s+(m+1) : s+(m+1)+"\n"+ Esc(n,m+1) +"\n"+s+(m+1);
}
Usage:
Esc(5, 0);
The trick is to use an accumulator.
class Test {
public static String esc(int n, String accum) {
if(n == 1) {
return accum;
}
int nMinusOne = n -1;
return esc(nMinusOne, nMinusOne + "\n" + accum + "\n" + nMinusOne);
}
public static String esc(int n) {
return esc(n, "" + n);
}
public static void main(String args[]) {
System.out.println(esc(5));
}
}
Here is one way to do it.
You pass in your value n twice. The reason is that you use n1 to print from 1 to n, and you then use n2 to print from n to 1. You also pass in a boolean flag that you make true once you switch the printing order.
Further more, you use n2 to reverse the value of n1 when printing such that:
n1 = 5, print 1
n1 = 4, print 2
// ....
This is done by the formula n2 + 1 - n1 as demonstrated bellow.
Since you said in the comments that you cannot use loops, I made the printing of dots into another recursive function.
Here is the result:
public static void printDots(int val, int condition) {
if(val < condition - 1) {
System.out.print(".");
printDots(val + 1, condition);
}
}
public static void Esc(int n1, int n2, boolean reverse) {
int val = (n2 + 1 - n1); // this gives 1 for n, 2 for n-1, 3 for n-2 etc.
if (n1 > 1 && !reverse) { // print from 1 to n
printDots(0, val); // print dots
System.out.println(val);
Esc(n1 - 1, n2, reverse);
} else if (n1 <= n2) { // print from n to 1
reverse = true;
printDots(0, val); // print dots
System.out.println(val);
Esc(n1 + 1, n2, reverse);
}
}
public static void main(String args[]) {
Esc(5, 5, false);
}
If you want to use the exact method signature you stated in your question, you can wrap the method I gave you above inside your method:
void Esc(int n) {
Esc(5, 5, false);
}
And then call Esc(5) from your main(). You can name the methods the same because java supports method overloading
Here is a running example
Output:
1
.2
..3
...4
....5
...4
..3
.2
1
public class Assignment {
private static int top;
public static void main(String[] args) {
top = 5;
recurse("", 1);
}
public static void recurse(String dots, int value) {
System.out.println(dots + value);
if (value == top) return;
recurse(dots + '.', value + 1);
System.out.println(dots + value);
}
}
It executes like this:
recurse("", 1) {
1 print 1
recurse(".", 2) {
.2 print .2
recurse("..", 3) {
..3 print ..3
recurse("...", 4) {
...4 print ...4
recurse("....", 5) {
....5 print ....5
return
}
...4 print ...4
}
..3 print ..3
}
.2 print .2
}
1 print 1
}
Now run it in the debugger to learn how it actually works.
Given a string, does "xyz" appear in the middle of the string? To
define middle, we'll say that the number of chars to the left and
right of the "xyz" must differ by at most one. This problem is harder
than it looks.
My solution works without the second last line except for one condition: if str="xyx"
Is it possible to modify the for loop to take this into account...I'm struggling with understanding why it doesn't.
My solution does work I'm just trying to get a better understanding of what I'm doing. I know I could add it into the first if statement but I want to know why it doesn't work without it.
public boolean xyzMiddle(String str) {
for (int i=0;i<str.length()-3;i++) {
if (str.substring(i,i+3).equals("xyz")) {
String front =str.substring(0,i);
String end = str.substring(i+3);
int a =Math.abs(front.length() -end.length());
if (a<=1) return true;
}
}
if (str.equals("xyz")) return true;
return false;
I think i remember this question - it's this question from Codingbat, I believe. Excellent web site, learned a lot from that site back when I started programming. There's absolutely no reason to use a loop, though.
public boolean xyzMiddle(String str) {
boolean result = false;
int i = str.length()/2 -1;
if (str.length() >= 3 && (str.substring(i, i+3).equals("xyz") || (str.length()%2 == 0 && str.substring(i-1, i+2).equals("xyz")) )) {
result = true;
}
return result;
}
So, let's walk through this and why it works. Firstly, str.length() >= 3, because if the string isn't at least as long as "xyz", there's no way it can contain "xyz".
There are two main cases to this problem, we need to think of. The string can have an even or an uneven length. In the uneven case, it's easy:
The Uneven case
AAAxyzAAA // length = 9
012345678 // the indexes
^ // that's the middle, which can be calculated by length/2
// (since this is an integer divison, we disregard whatever comes after the decimal point)
So to get the start of the xyz-substring, we simply subtract one from this number - which is exactly what i is doing:
AAAxyzAAA // length = 9
012345678 // the indexes
i // i = length/2-1 = 3
So if str.substring(i, i+3) is xyz, we can return true!
The Even Case
Now, this can be a bit more tricky, since there is no true "middle" of the string. In fact, two indexes could be called the middle, so we have two sub-cases:
AAAAAAAA // length = 8
01234567 // the indexes
^^ // Which one is the true middle character?
In fact, the middle would be between index 3 and 4. However, we are performing integer divisions, length/2 is always the largest (rightmost) of the two possible "middles". And since we calculate i using the middle, the same as in the uneven case applies - str.substring(i, i+3) could be considered the middle part of the string.
AAAxyzAA
01234567
^^^ // str.substring(i, i+3)
i
But suppose our string was AAxyzAAA - that could also be considered the middle part of the string. So we need to move our substring check "to the left" - so we subtract 1 from it.
AAxyzAAA
01234567
^^^ // str.substring(i-1, i+2)
i // i is still at "the old" location
So is it even or not?
To check whether the string is even or uneven, we use the modulo operator, %. The easiest way to think of what it does is "what would be left over after i divided with this number?". So 3 % 2 would be 1. In our case, we want to make sure that the number is divisible by 2 with nothing left over - because that means it was an even number. Therefore, we need to check whether str.length() % 2 == 0 before we make our "move-to-the-left" check. If not, we could risk going out of bounds on the string. If the string was 3 characters long, and we moved one to the left... we would check the substring starting at index -1, and that doesn't make a lot of sense.
Put it all together, and there you go!
I'd say something as simple as:
public void test() {
test("Hello", "ll");
test("Hello", "He");
test("Hello", "el");
test("Hello", "lo");
test("Hello", "Hell");
test("Hello", "ello");
test("Hello", "Hello");
test("Hell", "He");
test("Hell", "el");
test("Hell", "ll");
}
private void test(String s, String p) {
System.out.println(p + (inMiddle(s, p) ? " in " : " not in ") + s);
}
// Is the pattern in the middle of the string.
public static boolean inMiddle(String s, String p) {
int d = s.length() - p.length();
return at(s, p, d / 2) || ((d & 1) == 1 && at(s, p, (d / 2) + 1));
}
private static boolean at(String s, String p, int i) {
return i >= 0 && i < s.length() && s.substring(i).startsWith(p);
}
Results look correct to me:
ll in Hello
He not in Hello
el in Hello
lo not in Hello
Hell in Hello
ello in Hello
Hello in Hello
He not in Hell
el in Hell
ll not in Hell
I have confirmed that this matches Tobias' solution exactly when p = "xyz".
public boolean xyzMiddle(String str) {
int len = str.length();
if (len < 3){ return false; }
int even = (len+1)%2;
int mid = len/2;
return str.substring(mid-1-even, mid+2).contains("xyz");
}
The simplest I could come up with:
public boolean xyzMiddle(String str) {
str = " " + str + " ";
int even = (str.length()+1)%2;
int mid = (str.length())/2;
str = str.substring(mid-1-even, mid+2);
return str.contains("xyz");
}
public boolean xyzMiddle(String str) {
int len = str.length();
if(len < 3) {return false;}
if(len==3 && str.equals("xyz")) {return true;}
int index = middleIndex(str);
String left = str.substring(0,index) ;
String right= str.substring(index+3) ;
//Return based on the difference by at most 1
return (Math.abs(left.length()-right.length()) <=1);
}
public int middleIndex(String str) {
int middleLen = (str.length())/2;
int index= 0;
//Find an index that could be in the middle of the string with
// "xyz"
for(int i=middleLen-2; i < middleLen; i++ ) {
if(str.substring(i, i+3).equals("xyz") ) {
index= i;
}
}
return index;
}
public boolean xyzMiddle(String str) {
if (str.length() >= 3)
{
// if odd
if (str.length() % 2 == 1)
{
//axyzb
//01234
//length = 5; 5 is odd.
//length / 2 = 2;
//2 minus 1 = 1
//1 is where xyz starts
//aaxyzbb
//0123456
//length = 7; 7 is odd.
//length / 2 = 3;
//3 minus 1 = 2
//2 is where xyz starts.
//....
//This pattern works with all odd numbers.
if (str.substring((str.length() / 2) - 1, ((str.length() / 2) - 1) + 3).equals("xyz"))
{
return true;
}
else
{
return false;
}
}
//if even
else
{
//for evens that occur with a larger amount before "xyz" than after
//axyz
//0123
//length = 4; 4 is even;
//4 - 1 = 3;
//3 / 2 = 1
//1 is where xyz starts.
//aaxyzb
//012345
//length = 6; 6 is even;
//6 - 1 = 5;
//5 / 2 = 2
//2 is where xyz starts.
//...
//This pattern works for all even numbers where there is a larger amount of characters before the xyz.
if (str.substring((str.length() - 1) / 2, ((str.length() - 1) / 2) + 3).equals("xyz"))
{
return true;
}
//For the cases where there are more characters after "xyz" than before.
//xyzb
//0123
//length = 4; 4 is even;
//4 - 1 = 3;
//3 / 2 = 1
//1 - 1 = 0;
//xyz starts at 0;
//axyzbb
//012345
//length = 6; 6 is even;
//6 - 1 = 5;
//5 / 2 = 3;
//2 - 1 = 1;
//xyz starts at 1;
//...
//The pattern continues onwards for all cases where there are more characters after xyz than before.
else if (str.substring((((str.length() - 1) / 2) - 1), (((str.length() - 1) / 2) -1) + 3).equals("xyz"))
{
return true;
}
//If there is no instance of xyz in these areas.
else
{
return false;
}
}
}
// If our string is less than 3 in length.
else
{
return false;
}
}
public boolean xyzMiddle(String str) {
return str.length()>2 && str.length()%2==1 && str.substring((str.length()-1)/2-1,(str.length()/2+1)+1).contains("xyz") || str.length()>2 && str.length()%2==0 && (str.substring(str.length()/2-2,str.length()/2+1).contains("xyz") || str.substring(str.length()/2-1,str.length()/2+2).contains("xyz"));
}
public boolean xyzMiddle(String str) {
int index = str.indexOf("x");
if(index < 0)
return false;
while(index >=0 && (index+3 <= str.length()) ){
if(str.substring(index,index+3).equals("xyz") && Math.abs(str.substring(0,index).length() - str.substring(index+3).length()) <=1)
return true;
index = str.indexOf("x",index+1);
}
return false;
}