The problem with your code is this check:
if (ch == 'O') {
if (!((inp.charAt(i + 1)) == 'X' || (inp.charAt(i - 1)) == 'X')) {
count++
}
}
Here you check for only a case where there is O not surrounded by X. But this check doesn’t work for cases like *OOXOO*. You’ll get 2 but the result is 0. So the solution is to do it in loop or using regexp. Examples are shown below.
Also you did that:
inp = "." + inp + ".";
which I think is not needed. I’m guessing you did that because you were getting ArrayIndexOutOfBoundsException
while looping for i = 0
. The solution you proposed works, but you could also add check in the loop for (i>0)
or start from 1 and check behind + front (see examples below).
If you don’t require a loop with array then you can use a simple regex:
testString = testString.replaceAll("[O]+X","X").replaceAll("X[O]+", "X");
The whole test-program:
public class Main {
public static void main(final String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter Test String: ");
String testString = br.readLine();
testString = "." + testString + ".";
testString = testString.replaceAll("[O]+X","X").replaceAll("X[O]+", "X");
int count = testString.length() - testString.replace("O", "").length();
System.out.println("Result string: " + testString);
System.out.println("Total 'O' left: " + count);
}
}
Test1:
Enter Test String: *OOX*XOX*OO*XO*O*X*OX*XO*O*
Result string: .*X*XX*OO*X*O*X*X*X*O*.
Total 'O' left: 4
Test2:
Enter Test String: *OOXOO*OO
Result string: .*X*OO.
Total 'O' left: 2
Test3:
Enter Test String: *O*OXOO*OO
Result string: .*O*X*OO.
Total 'O' left: 3
EDIT
Below there are 3 types of solutions to your problem:
public class Main {
private BufferedReader userInput;
private String testString;
public static void main(final String args[])
{
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in)); //get the reader.
Main test = new Main(userInput); //create an object of a test class that will use this reader
test.getTestString(); //ask user for the input
test.removeOsWithRegex(); //first method - regex
test.removeOsByReplacingWithX(); //second method - in loop change all O's to X's
test.removeOsByInLoopDeletion(); //third method - delete all O's step by step in a loop.
}
public Main(final BufferedReader userInput)
{
this.userInput = userInput; //constructor
}
//getting the test string.
private void getTestString()
{
System.out.print("Enter Test String: ");
try
{
testString = userInput.readLine();
testString = "." + testString + ".";
}
catch (IOException e)
{
throw new IllegalStateException("Something wrong happened: " + e.getMessage() + ". Shutting down.");
}
}
//removing with regex
private void removeOsWithRegex()
{
System.out.println("Removing 'O' with regexp from: " + testString);
//change all parts of testString where there are Os followed by X to X.
//do the same with parts of testString where there is X followed by one or more O.
String resultString = testString.replaceAll("[O]+X","X").replaceAll("X[O]+", "X");
//the number of Os is the length of the string minus length of the string without Os.
int count = resultString.length() - resultString.replace("O", "").length();
System.out.println("Result string: " + resultString);
System.out.println("Total 'O' left: " + count);
}
//2nd method
public void removeOsByReplacingWithX()
{
System.out.println("Removing 'O' by replacing them with X: " + testString);
byte[] byteArray = testString.getBytes();
boolean changesMade;
//create loop
do
{
changesMade = false;
for (int i = 1; i < byteArray.length - 1; i++)
{
//if X was found change adjacent Os to X
if (byteArray[i] == 'X')
{
if (byteArray[i-1] == 'O')
{
byteArray[i-1] = 'X';
changesMade = true;
}
if (byteArray[i+1] == 'O')
{
byteArray[i+1] = 'X';
changesMade = true;
}
}
}
} while(changesMade); //do this as long as there is something to change.
String resultString = new String(byteArray);
int count = resultString.length() - resultString.replace("O", "").length();
System.out.println("Result string: " + resultString);
System.out.println("Total 'O' left: " + count);
}
//3rd method
public void removeOsByInLoopDeletion()
{
System.out.println("Removing 'O' by deleting them in loop: " + testString);
byte[] byteArray = testString.getBytes();
boolean changesMade;
//create a loop
do
{
changesMade = false;
for (int i = 1; i < byteArray.length - 1; i++)
{
//if there is X
if (byteArray[i] == 'X')
{
//if next is O then shorten the array by cutting the O
if (byteArray[i+1] == 'O')
{
byteArray = shortenByteArray(byteArray, i+1); //i+1 is the position of O
changesMade = true;
break;
}
}
//on the other hand if O was wound
if (byteArray[i] == 'O')
{
//if X is next, shorten it by cutting O from current position
if (byteArray[i+1] == 'X')
{
byteArray = shortenByteArray(byteArray, i); //i is current position.
changesMade = true;
break;
}
}
}
} while(changesMade);
String resultString = new String(byteArray);
int count = resultString.length() - resultString.replace("O", "").length();
System.out.println("Result string: " + resultString);
System.out.println("Total 'O' left: " + count);
}
//cutting one element from byte array
private byte[] shortenByteArray(final byte[] byteArray, final Integer startIndex)
{
byte[] newByteArray = new byte[byteArray.length-1];
for (int i = 0; i < newByteArray.length; i++)
{
//rewrite all before the item to cut
if (i < startIndex)
{
newByteArray[i] = byteArray[i];
}
else
{
//ommit the element to cut and move all others by 1.
newByteArray[i] = byteArray[i+1];
}
}
return newByteArray;
}
}
The results are the same for all three cases for all 3 tests I’ve supplied earlier.
3
solved Count the O’s from a Given String, say=”*XOO*O”