Answer coming wrong for some test cases - java

Given two strings A and B of lowercase letters, return true if and only if we can swap two letters in A so that the result equals B.For test case below answer is coming wrong.
Input:
"aaaaaaabc"
"aaaaaaacb"
class Solution {
public boolean buddyStrings(String A, String B)
{
int count=0,index=0;
int a[] = new int[A.length()];
if( A.length()!=B.length() )
return false;
if( A.equals(B) )
{
for(int i=0; i<A.length() ;i++)
{
if( A.charAt(0)==A.charAt(i) )
count++;
}
return( count==A.length() );
}
for(int i=0; i<A.length(); i++)
{
if(A.charAt(i) ! = B.charAt(i))
a[index++] = i;
}
if( a.length==2 )
{
if(A.charAt(a[0])==B.charAt(a[1]) && A.charAt(a[1])==B.charAt(a[0]))
return true;
else
return false;
}
else
return false;
}
}

You're close. Below is my solution to the problem, namely: return true if and only if we can swap two letters in A so that the result equals B Explanations after the code.
public boolean buddyStrings(String s1, String s2) {
boolean result = false;
if (s1 != null && s2 != null) {
char[] letters1 = s1.toCharArray();
char[] letters2 = s2.toCharArray();
if (letters1.length == letters2.length && letters1.length > 1) {
int[] indices = new int[2];
int index = 0;
for (int i = 0; i < letters1.length; i++) {
if (letters1[i] != letters2[i]) {
if (index < 2) {
indices[index++] = i;
}
else {
index++;
break;
}
}
}
if (index == 2) {
result = letters1[indices[0]] == letters2[indices[1]];
}
}
}
return result;
}
Firstly, as in your code, the lengths of both strings must be equal and the lengths should be more than 1 (one), since you can't swap two letters in a string when the string contains only one letter.
Now we check corresponding letters in each string and we save the indices of corresponding letters that are different. For your test strings, for example, the indices would be 7 and 8. There must be precisely two such indices. Hence I save the indices in an int array of size 2.
After checking all the letters, there must be precisely two letters that are different. All that's left is to check that if we swap the two letters, the two strings will be identical.

This part of your code is the problem.
if( A.equals(B) )
{
for(int i=0; i<A.length() ;i++)
{
if( A.charAt(0)==A.charAt(i) )
count++;
}
return( count==A.length() );
}
Consider a case where A = B = "abcdefga".
According to your code, i takes up values from 0 to 7. The condition is only satisfied once, i.e. when i = 7, so count is equal to 1 when the loop is terminated. In your return statement, count == A.length() returns false because 1 =/= 7.

Related

Java: Find the longest substring without any number and at least one upper case character

Came across a programming exercise and was stuck. The problem is:
You need to define a valid password for an email but the only
restrictions are:
The password must contain one uppercase character
The password should not have numeric digit
Now, given a String, find the length of the longest substring which
is a valid password. For e.g Input Str = "a0Ba" , the output should
be 2 as "Ba" is the valid substring.
I used the concept of longest substring without repeating characters which I already did before but was unable to modify it to find the solution to above problem. My code for longest substring without repeating characters is:
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}
How about
final String input = "a0Ba";
final int answer = Arrays.stream(input.split("[0-9]+"))
.filter(s -> s.matches("(.+)?[A-Z](.+)?"))
.sorted((s1, s2) -> s2.length() - s1.length())
.findFirst()
.orElse("")
.length();
out.println(answer);
Arrays.stream(input.split("[0-9]+")) splits the original string into an array of strings. The separator is any sequence of numbers (numbers aren't allowed so they serve as separators). Then, a stream is created so I can apply functional operations and transformations.
.filter(s -> s.matches("(.+)?[A-Z](.+)?")) keeps into the stream only strings that have at least one upper-case letter.
.sorted((s1, s2) -> s2.length() - s1.length()) sorts the stream by length (desc).
.findFirst() tries to get the first string of the stream.
.orElse("") returns an empty string if no string was found.
.length(); gets the length of the string.
I suggest that you split your String to have an array of strings without digit:
yourString.split("[0-9]")
Then iterate over this array (says array a) to get the longest string that contains one Upper case character:
a[i].matches("[a-z]*[A-Z]{1}[a-z]*");
You can use a simple array. The algorithm to use would be a dynamic sliding window. Here is an example of a static sliding window: What is a Sliding Window
The algorithm should be as follows:
Keep track of 2 indexes of the array of char. These 2 indexes will be referred to as front and back here, representing the front and back of the array.
Have an int (I'll name it up here) to keep track of the number of upper case char.
Set all to 0.
Use a while loop that terminates if front > N where N is the number of char given.
If the next char is not a number, add 1 to front. Then check if that char is upper case. If so, add 1 to up.
If up is at least 1, update the maximum length if necessary.
If the next char is a number, continue checking the following char if they are also numbers. Set front to the first index where the char is not a number and back to front-1.
Output the maximum length.
You can use my solution which runs in O(n) time and finds the longest part without any digit and with a capital letter:
String testString = "skjssldfkjsakdfjlskdssfkjslakdfiop7adfaijsldifjasdjfil8klsasdfŞdijpfjapodifjpoaidjfpoaidjpfi9a";
int startIndex = 0;
int longestStartIndex = 0;
int endIndex = 0;
int index = 0;
int longestLength = Integer.MIN_VALUE;
boolean foundUpperCase = false;
while(index <= testString.length()) {
if (index == testString.length() || Character.isDigit(testString.charAt(index))) {
if (foundUpperCase && index > startIndex && index - startIndex > longestLength) {
longestLength = index - startIndex;
endIndex = index;
longestStartIndex = startIndex;
}
startIndex = index + 1;
foundUpperCase = false;
} else if (Character.isUpperCase(testString.charAt(index))) {
foundUpperCase = true;
}
index++;
}
System.out.println(testString.substring(longestStartIndex, endIndex));
You don't need regular expressions. Just use a few integers to act as index pointers into the string:
int i = 0;
int longestStart = 0;
int longestEnd = 0;
while (i < s.length()) {
// Skip past all the digits.
while (i < s.length() && Character.isDigit(s.charAt(i))) {
++i;
}
// i now points to the start of a substring
// or one past the end of the string.
int start = i;
// Keep a flag to record if there is an uppercase character.
boolean hasUppercase = false;
// Increment i until you hit another digit or the end of the string.
while (i < s.length() && !Character.isDigit(s.charAt(i))) {
hasUppercase |= Character.isUpperCase(s.charAt(i));
++i;
}
// Check if this is longer than the longest so far.
if (hasUppercase && i - start > longestEnd - longestStart) {
longestEnd = i;
longestStart = start;
}
}
String longest = s.substring(longestStart, longestEnd);
Ideone demo
Whilst more verbose than regular expressions, this has the advantage of not creating any unnecessary objects: the only object created is the longest string, right at the end.
I am using modification of Kadane algorithm to search the required password length. You may use isNumeric() and isCaps() function or include inline if statements. I have shown below with functions.
public boolean isNumeric(char x){
return (x>='0'&&x<='9');
}
public boolean isCaps(char x){
return (x>='A'&&x<='Z');
}
public int maxValidPassLen(String a)
{
int max_so_far = 0, max_ending_here = 0;
boolean cFlag = false;
int max_len = 0;
for (int i = 0; i < a.length(); i++)
{
max_ending_here = max_ending_here + 1;
if (isCaps(a.charAt(i))){
cFlag = true;
}
if (isNumeric(a.charAt(i))){
max_ending_here = 0;
cFlag = false;
}
else if (max_so_far<max_ending_here){
max_so_far = max_ending_here;
}
if(cFlag&&max_len<max_so_far){
max_len = max_so_far;
}
}
return max_len;
}
Hope this helps.
There are plenty of good answers here but thought it might be of interest to add one that uses Java 8 streams:
IntStream.range(0, s.length()).boxed()
.flatMap(b -> IntStream.range(b + 1, s.length())
.mapToObj(e -> s.substring(b, e)))
.filter(t -> t.codePoints().noneMatch(Character::isDigit))
.filter(t -> t.codePoints().filter(Character::isUpperCase).count() == 1)
.mapToInt(String::length).max();
If you wanted the string (rather than just the length), then the last line can be replaced with:
.max(Comparator.comparingInt(String::length));
Which returns an Optional<String>.
I'd use Streams and Optionals:
public static String getBestPassword(String password) throws Exception {
if (password == null) {
throw new Exception("Invalid password");
}
Optional<String> bestPassword = Stream.of(password.split("[0-9]"))
.filter(TypeErasure::containsCapital)
.sorted((o1, o2) -> o1.length() > o2.length() ? 1 : 0)
.findFirst();
if (bestPassword.isPresent()) {
return bestPassword.get();
} else {
throw new Exception("No valid password");
}
}
/**
* Returns true if word contains capital
*/
private static boolean containsCapital(String word) {
return word.chars().anyMatch(Character::isUpperCase);
}
Be sure to write some unit tests
public String pass(String str){
int length = 0;
boolean uppercase = false;
String s= "";
String d= "";
for(int i=0;i<str.length();i++){
if(Character.isUpperCase(str.charAt(i)) == true){
uppercase = true;
s = s+str.charAt(i);
}else if(Character.isDigit(str.charAt(i)) == true ){
if(uppercase == true && s.length()>length){
d = s;
s = "";
length = s.length();
uppercase = false;
}
}else if(i==str.length()-1&&Character.isDigit(str.charAt(i))==false){
s = s + str.charAt(i);
if(uppercase == true && s.length()>length){
d = s;
s = "";
length = s.length();
uppercase = false;
}
}else{
s = s+str.charAt(i);
}
}
return d;}
Here is a simple solution with Scala
def solution(str: String): Int = {
val strNoDigit = str.replaceAll("[0-9]", "-")
strAlphas = strNoDigit.split("-")
Try(strAlphas.filter(_.trim.find(_.isUpper).isDefined).maxBy(_.size))
.toOption
.map(_.length)
.getOrElse(-1)
}
Another solution using tail recursion in Scala
def solution2(str: String): Int = {
val subSt = new ListBuffer[Char]
def checker(str: String): Unit = {
if (str.nonEmpty) {
val s = str.head
if (!s.isDigit) {
subSt += s
} else {
subSt += '-'
}
checker(str.tail)
}
}
checker(str)
if (subSt.nonEmpty) {
val noDigitStr = subSt.mkString.split("-")
Try(noDigitStr.filter(s => s.nonEmpty && s.find(_.isUpper).isDefined).maxBy(_.size))
.toOption
.map(_.length)
.getOrElse(-1)
} else {
-1
}
}
This is a dynamic programming problem. You can solve this yourself using a matrix. It is easy enough. Just give it a try. Take the characters of the password as the rows and columns of the matrix. Add the diagonals if the current character appended to the last character forms a valid password. Start with the smallest valid password as the initial condition.
String[] s = testString.split("[0-9]");
int length = 0;
int index = -1;
for(int i=0; i< s.length; i++){
if(s[i].matches("[a-z]*.*[A-Z].*[a-z]*")){
if(length <= s[i].length()){
length = s[i].length();
index = i;
}
}
}
if(index >= 0){
System.out.println(s[index]);
}
//easiest way to do it:
String str = "a0Ba12hgKil8oPlk";
String[] str1 = str.split("[0-9]+");
List<Integer> in = new ArrayList<Integer>();
for (int i = 0; i < str1.length; i++) {
if (str1[i].matches("(.+)?[A-Z](.+)?")) {
in.add(str1[i].length());
} else {
System.out.println(-1);
}
}
Collections.sort(in);
System.out.println("string : " + in.get(in.size() - 1));
This is my solution with c#. I tested a range of strings and it gave me the correct value. Used Split. No Regex or Substrings. Let me know if it works; open to improvements and corrections.
public static int validPassword(string str)
{
List<int> strLength = new List<int>();
if (!(str.All(Char.IsDigit)))
{
//string str = "a0Bb";
string[] splitStrs = str.Split(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
//check if each string contains a upper case
foreach (string s in splitStrs)
{
//Console.WriteLine(s);
if (s.Any(char.IsUpper) && s.Any(char.IsLower) || s.Any(char.IsUpper))
{
strLength.Add(s.Length);
}
}
if (strLength.Count == 0)
{
return -1;
}
foreach (int i in strLength)
{
//Console.WriteLine(i);
}
return strLength.Max();
}
else
{
return -1;
}
}
I think this solution takes care of all the possible corner cases. It passed all the test cases in an Online Judge. It is a dynamic sliding window O(n) solution.
public class LongestString {
public static void main(String[] args) {
// String testString = "AabcdDefghIjKL0";
String testString = "a0bb";
int startIndex = 0, endIndex = 0;
int previousUpperCaseIndex = -1;
int maxLen = 0;
for (; endIndex < testString.length(); endIndex++) {
if (Character.isUpperCase(testString.charAt(endIndex))) {
if (previousUpperCaseIndex > -1) {
maxLen = Math.max(maxLen, endIndex - startIndex);
startIndex = previousUpperCaseIndex + 1;
}
previousUpperCaseIndex = endIndex;
} else if (Character.isDigit(testString.charAt(endIndex))) {
if (previousUpperCaseIndex > -1) {
maxLen = Math.max(maxLen, endIndex - startIndex);
}
startIndex = endIndex + 1;
previousUpperCaseIndex = -1;
}
}
if (previousUpperCaseIndex > -1)
maxLen = Math.max(maxLen, endIndex - startIndex);
System.out.println(maxLen);
}}
function ValidatePassword(password){
var doesContainNumber = false;
var hasUpperCase = false;
for(var i=0;i<password.length;i++){
if(!isNaN(password[i]))
doesContainNumber = true;
if(password[i] == password[i].toUpperCase())
hasUpperCase = true;
}
if(!doesContainNumber && hasUpperCase)
return true;
else
return false;
}
function GetLongestPassword(inputString){
var longestPassword = "";
for(var i=0;i<inputString.length-1;i++)
{
for (var j=i+1;j<inputString.length;j++)
{
var substring = inputString.substring(i,j+1);
var isValid = ValidatePassword(substring);
if(isValid){
if(substring.length > longestPassword.length)
{
longestPassword = substring;
}
}
}
}
if(longestPassword == "")
{
return "No Valid Password found";
}
else
{
return longestPassword;
}
}

Greatest number of consecutive vowels

I'm trying to write a function that takes in a String and returns the greatest number of consecutive equivalent vowels in the String.
Here's my attempt:
public static final String VOWELS = "aeiou";
public static int consecutiveVowelsInLine(String line) {
int longestVowels = 0;
int candidateLength = 0;
for (int i = 0; i < line.length() - 1; i++) {
if (isVowel(line.charAt(i))) {
if (line.charAt(i) == line.charAt(i+1)) {
candidateLength++;
}
} else {
candidateLength = 0;
}
longestVowels = Math.max(longestVowels, candidateLength);
}
return longestVowels;
}
public static boolean isVowel(char c) {
VOWELS.contains(c.toLowerCase());
}
The problem is this doesn't handle the case where the String is a single character that's a vowel. So if the String is just "a", my code gives back 0 instead of 1.
As said before, the vowels have to be the same.
Testcases:
a -> 1
b -> 0
ae -> 1
aeae -> 1
aab -> 2
aba -> 1
abee -> 2
I think you aim to do too much in the loop: instead of looking to the character next, concentrate on the current character and maintain a state that stores the previous vowel:
public static int consecutiveVowelsInLine(String line) {
int longestVowels = 0;
int candidateLength = 0;
char vowel = 'b'; //b is not a vowel
for (int i = 0; i < line.length(); i++) {
char ci = line.charAt(i);
if (isVowel(ci)) {
if (ci == vowel) { //the same as the other one
candidateLength++;
} else {
candidateLength = 1;
}
vowel = ci;
} else {
candidateLength = 0;
vowel = 'b';
}
longestVowels = Math.max(longestVowels, candidateLength);
}
return longestVowels;
}
Here vowel stores the current vowel sequences you are working with. In the beginning we use b, simple because that is not a vowe. In case we encounter a vowel, that vowel is stores in vowel and we update the candidateLength accordingly. In case we encounter a non-vowel, we set vowel back to b (or another non-vowel).
Demo:
There were some problems with your isVowel method as well, a running implementation with a few testcases can be found here.
Here's one problem:
if (line.charAt(i) == line.charAt(i+1)) {
candidateLength++;
}
If the string is only one character, you're checking the character against null. Add a check, something like this:
if (line.length() == 1 && isVowel(line.charAt(0)) {
etc.
}
Simply change it like:
public static int consecutiveVowelsInLine( String line ){
int result = findConsecutiveMaxValue( line );
if( result == 0 ){
result = findSingleVowel( line );
}
return result;
}
private static int findSingleVowel( String line ){
for( int i = 0; i < line.length(); i++ ){
if( isVowel( line.charAt( i ) ) ){ return 1; }
}
return 0;
}
private static int findConsecutiveMaxValue( String line ){
int longestVowels = 0;
int candidateLength = 0;
for( int i = 0; i < line.length() - 1; i++ ){
if( isVowel( line.charAt( i ) ) ){
if( line.charAt( i ) == line.charAt( i + 1 ) ){
candidateLength++;
}
}
else{
candidateLength = 0;
}
longestVowels = Math.max( longestVowels, candidateLength );
}
return longestVowels;
}
Change:
if (line.charAt(i) == line.charAt(i+1)) {
candidateLength++;
}
to:
if (candidateLength == 0 || line.charAt(i) == line.charAt(i-1)) {
candidateLength++;
}
Additionally the condition in for() loop looks suspicious - use getLength() instead of getLength()-1.

Algorithm to determine if a string has all unique characters

I have written this algorithm to determine if a string has all unique characters, but its giving me some errors. Can anyone help me with improving the code.
It is giving me the error that I am duplicating the uniquechar1 method but I am passing it to an if statement.
package nospacesinstrings;
import java.util.Scanner;
public class uniquechar {
public static boolean uniquechar1(String s) {
if (s == null || s.length() > 0 ) {
return false;
}
for (int i = 0 ;i < s.length();i++) {
for (int j = s.length() ;j > 0;j--) {
if (i == j)
return false;
else
return true;
}
}
}
public static void main(String[] args) {
String s ;
System.out.println("Enter the string ");
Scanner in = new Scanner(System.in);
s = in.nextLine();
if (uniquechar1(s) == true) {
System.out.println("String has all the unique characters ");
} else {
System.out.println("String does not have all the unique characters ");
}
}
}
Your check at the top looks backwards. I think you meant to put s.length() < 1 instead of s.length() > 0
You also are returning a value before you have finished iterating over your string. You should only return true if you iteration through the complete string without returning false
Also, your double loop will always end up comparing each character to itself so the method will return false. To do it using a for each loop, you need to stop before you get to the currently checked index.
for (int i = 0 ;i < s.length();i++){
for (int j = s.length() ;j > i;j--){
if (i == j )
{return false ;}
}
return true;
you could also avoid traversing twice down the string by collecting characters as you go. Something like this:
Stack<char> stack = new Stack<char>();
for (int i = 0 ;i < s.length();i++){
if (stack.Contains(s[i]))
{return false ;}
stack.Push(s[i]);
}
return true ;
Lastly, if you should research character comparison. Are you looking to fail if any two any character even if they are different cases (i.e. A == a or A != a)?
This algorithm should work. I'm assuming there are no numbers in the string. (Edited to correct code).
public static boolean uniquechar1(String s)
{
if (s == null || s.length() == 0 )
return true;
// make sure no letter in alphabet occurs twice in the string.
boolean[] letters = new boolean[26];
s = s.toUpperCase();
s = s.replaceAll(" ", "");
for (int i = 0; i < s.length(); i++)
{
char ch = s.charAt(i);
ch = (char) (ch - 'A');
if (letters[ch] == true)
return false;
else
letters[ch] = true;
}
return true;
}
Here is a tester method.
public static void main(String[] args)
{
System.out.println( uniquechar1("Hello World!") );
System.out.println( uniquechar1("A A") );
System.out.println( uniquechar1("ABC") );
}
Outputs:
false
false
true

Can't find the reason for my out of bounds exception

So I need to write a method which allows me to find the next number without using anything but String and StringBuffer classes (so no parse or whatsoever).
when I run my code everything seems to work fine except for the last input (String k). It causes an outofbounds error in the while loop. But I don't see how It could do that because since my boolean should be false (I think because it only consists out of nine's) it shouldn't enter te loop in the first place.
public class Palindroom {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="347"
+ ""; System.out.println("s "+increment(s));
String p="199919";System.out.println(" p "+increment(p));
String d="199999";System.out.println( " d "+increment(d));
String k ="999999";System.out.println(" k "+increment(k));
}
static String increment (String s) {
StringBuffer sb = new StringBuffer (s);
char laatst = sb.charAt(sb.length()-1);
int laatste = sb.length()-1;
if(laatst == '9') {
int a = 1;
boolean nine = false;
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) != 9 ) {
nine = true;
} else nine = false;
}
if (nine == true) {
while (sb.charAt(sb.length()- a) == '9'){
sb.setCharAt(sb.length()- a, '0' );
a++;
}
sb.setCharAt(sb.length()-a, ((char)((sb.charAt(sb.length()-a)+1))));
} else if( nine == false) {
System.out.println("negen "+nine);
sb.insert(0, '1');
for (int i = 0; i < sb.length(); i++) {
if(sb.charAt(i)=='9') {
sb.setCharAt(i, '0');
}
}
}
} else {
sb.setCharAt(laatste,(char) (laatst+1) );
}
return sb.toString();
}
}
EDIT: based on the comments :) . Correct your logic for true and false.
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) == '9' ) {
nine = true;
}
else
{
nine = false;
break;
}
}
also you are getting an out of bounds exception because
while (sb.charAt(sb.length()- a) == '9'){
sb.setCharAt(sb.length()- a, '0' );
a++;
}
after the fifth iteration sb.length()- a will be negative when the control comes to check the condition.
you are not getting the same error in other cases because the control never goes to the while loop (as nine == false)
OLD OBSERVATION
in
if(laatst == '9') {
int a = 1;
boolean nine = false;
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) != 9 ) {
nine = true;
} else nine = false;
}
you are doing
if (sb.charAt(i) != 9 ) {
nine = true;
} else nine = false;
instead do, if you want to compare against the character 9,
if (sb.charAt(i) != '9' ) {
nine = true;
} else nine = false;
otherwise you are just comparing the ASCII value of the charAt(i) and so your boolean will only be false, if charAt(i) has ascii value 9
The problem is that when your string consists only of 9s, your while loop causes a to exceed sb.length(). Then, you end up trying to access the character at place -1 of sb.

Count Character Consecutively in Java

I'm trying to write a method that returns the number of times char c first appears consecutively in s, even if it's a single occurrence of the character. Even spaces break the consecutive count. So the string "I'm bad at programming." should only return 1, if char c was 'a'.
The code below compiles but doesn't print the correct answers. Just something to show my general logic when it comes to approaching this problem.
public class WordCount
{
public int countRun( String s, char c )
{
int counter = 0;
for( int i = 0; i < s.length(); i++)
/*There should be other conditions here that checks for first
appearance consecutively. I've tried my fair share, but no
luck on getting correct results.*/
{
if( s.charAt(i) == c )
{
counter += 1;
}
}
return counter;
}
public static void main( String args[] )
{
WordCount x = new WordCount();
System.out.println( x.countRun( "Add dog", 'd' ) ); //should return 2
System.out.println( x.countRun( "Add dog", 'D' ) ); //should return 0
System.out.println( x.countRun( "Hope you're happy", 'p' )); //should return 1
System.out.println( x.countRun( "CCCCCcccC", 'C' )); //should return 5
}
}
I just need a few pointers (logic-wise or code). Maybe there's a method for Strings that I've never seen before that could make my program much simpler. I have very limited knowledge in programming and in Java.
EDIT: For anyone wondering if this is part of some homework assignment or whatnot, this was a question from a very old midterm. I got it wrong but for some reason but never bothered to ask for the correct answer at the time. I looked at it today and wanted to see if I knew the answer. Looks like I don't.
You could do it in one line:
int result = s.replaceFirst(".*?(" + c + "+).*", "$1").length();
This code uses regex to essentially extract the part of s that is the first contiguous occurrences of c, then gets the length of that.
This will also work for no occurrences, yielding zero.
See live demo.
Add a flag, and break out of the loop when you have found one matching character, then find "anything else". Maybe not the most compact or elegant, but true to the original code. Tested, and produces 2,0,1,5 as expected.
public int countRun( String s, char c )
{
int counter = 0;
boolean foundOne = false;
for( int i = 0; i < s.length(); i++)
{
if( s.charAt(i) == c )
{
counter += 1;
foundOne = true;
}
else {
if(foundOne) break;
}
}
return counter;
}
It occurs to me that counter>0 is an equivalent condition to foundOne==true; that would allow you to simplify the code to:
public int countRun( String s, char c )
{
int counter = 0;
for( int i = 0; i < s.length(); i++)
{
if( s.charAt(i) == c ) counter++;
else if(counter>0) break;
}
return counter;
}
The logic is a tiny bit harder to follow this way, as the variable name foundOne is self-documenting. But per other posts, "small is beautiful" too...
Using assci array counter
public static int countRun(String s, char c) {
int[] counts = new int[256];
int count = 0;
char currChar;
for (int i = 0; i < s.length(); i++) {
currChar = s.charAt(i);
if (currChar == c) {// match
counts[c]++;
} else if (Character.isSpaceChar(currChar)) {
counts[c] = 0;// reset counter for c
} else {// no match
if (counts[c] > 0) {// return accumulated counts if you have
count = counts[c];
return count;
}
}
}
return count;
}
public class A3B2C1 {
public static void main(String[] args) {
String s = "AAABBC";
s = s + '#';//dummy char to consider the last char 'C' in the string
//without using charAt()
int count = 1;
String n="";
int i=0;
StringBuffer bf = new StringBuffer();
char c[] = s.toCharArray();
for(i=0;i< c.length-1;i++)
{
if(c[i] == c[i+1])
{
count++;
}
else
{
n = c[i] +""+count;
bf.append(n);
count=1;
}
}
System.out.println("Output: "+bf);//prints-->> Output: A3B2C1
}
}

Categories