count uppercase chars in string recursively - java

I have to solve an exercise, counting all the uppercase chars in a String - recursively - Anyhow I thought I might have found a solution - but it won't work…
Probably you might help me? Thanks!
public static int CountCapitals(String s) {
int counter = 0;
// if (Character.isUpperCase(s.charAt(0)))counter+=1;
if (s.length() == 0)
return counter;
if (s.length() == 1 && s.charAt(0) < 65 && s.charAt(0) > 90)
return 0;
if (s.charAt(0) < 'A' && s.charAt(0) > 'Z') {
return CountCapitals(s.substring(1));
}
if (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z')
counter++;
return CountCapitals(s.substring(1));
}

The problem with your code is the use of counter: each level of invocation has its own counter, initially set to zero. The ++ operator at the bottom has no effect.
You need to compute the result of this invocation based on the result of the previous invocation. Your base case (i.e. s.length() == 0) is fine; the rest of your code needs to change so that it returns whatever CountCapitals(s.substring(1)) when the first letter is non-capital; when the first letter is capital, your function should return 1 + CountCapitals(s.substring(1)).

You need to consider the case when the length of string is 1 and the only character is uppercase (in this case, you should return 1).
Also you need to pass in the counter as a parameter rather than expecting it to "carry over" into other function calls.

This recursion should do just what you want:
public static int countCapitals(String s) {
if (s.length() == 0) return 0;
int cap = Character.isUpperCase(s.charAt(0)) ? 1 : 0;
return countCapitals(s.substring(1)) + cap;
}
If this wasn't a home assignment, you could try an iterative approach which is about 5-10 times faster:
public static int countCapitals(String s) {
int count = 0;
for (int idx = 0; idx < s.length(); idx++) {
if (Character.isUpperCase(s.charAt(idx))) {
count++;
}
}
return count;
}

You don't really need to use a counter variable to keep track of the number of capitals. Instead, you can just the recursive calls, themselves, to keep track of the total:
public static int CountCapitals(String s)
{
if (s.length() == 1)
return (Character.isUpperCase(s.charAt(0)) ? 1 : 0);
else
return CountCapitals(s.substring(1)) +
(Character.isUpperCase(s.charAt(0)) ? 1 : 0);
}
If this is for an assignment and you have to use ASCII values, then fine, but if not, you really should just Character.isUpperCase(char c). In case you're not familiar with the conditional operator, it's defined as follows:
if(someExpression == true)
{
//output 1
}
else
{
//output 0
}
is represented succinctly as:
(someExpression == true) ? 1 : 0
NB:
In your example, counter is set to 0 at the beginning of each method call, so that's why it's not working. If you really want to use a counter, pass it as a parameter to the method instead, and update the parameter with each method call. When you get to the end of the String, simply return the parameter.

You try this
public class HelloWorld{
public static int isUpperCase(String str){
if(str.length()==0) return 0;
boolean check =Character.isUpperCase(str.charAt(0));
if(check){
return isUpperCase(str.substring(1))+1;
}
return isUpperCase(str.substring(1));
}
public static void main(String []args){
String n= "FSAsdsadASdcCa";
System.out.println(isUpperCase("FSAsdsadASdcCa"));
}
}

Related

First Unique Character In a String-Leetcode

I have tried out 387.First Unique Character In A string
Given a string s, find the first non-repeating character in it and
return its index. If it does not exist, return -1.
EXAMPLE : 1
Input: s = "leetcode"
Output: 0
EXAMPLE :2
Input: s = "loveleetcode"
Output: 2
I have been trying this problem. I thought we will pick one by one all the characters and check if a repeating character exists break from the loop. And if not then return that index.I have thought over a solution which I believe is not the most efficient way but I want to know the how can I solve this problem with the approach given below:
public int firstUniqChar(String s) {
for(int i=0;i<s.length();i++){
for(int j=i+1;j<s.length();j++){
if(s.charAt(i)==s.charAt(j)){
break;
}
}
}
return -1;
}
I'm confused how to return the index.I'm unable to find the logic after:
for(int j=i+1;j<s.length();j++){
if(s.charAt(i)==s.charAt(j)){
break;
}
}
If anyone can help me find out the logic here.
Try this.
public static int firstUniqChar(String s) {
L: for (int i = 0, length = s.length(); i < length; i++) {
for (int j = 0; j < length; j++)
if (i != j && s.charAt(i) == s.charAt(j))
continue L;
return i;
}
return -1;
}
public static void main(String[] args) {
System.out.println(firstUniqChar("leetcode"));
System.out.println(firstUniqChar("loveleetcode"));
System.out.println(firstUniqChar("aabb"));
}
output:
0
2
-1
you can use a flag variable.
public int firstUniqChar(String s) {
int flag=0;
for(int i=0;i<s.length();i++){
flag=0;
for(int j=0;j<s.length();j++){
if(s.charAt(i)==s.charAt(j) && i!=j){
flag=1;
break;
}
}
if(flag==0){
return i;
}
}
return -1;
}
There are 26 possible lowercase English letters, so you could use two 26 element arrays.
One array, letterCount, keeps counts of each letter. Start at 0 and add 1 every time the corresponding letter appears in the text string. The second array, position, holds the position of the first occurrence of that letter, or -1 if the letter never appears. You will need to initialise that array to -1 for all elements.
Process the string in order, recording initial positions, once only for each letter, and incrementing the count for each letter in the string.
After the string has been processed, look through the letterCount array. If there are no letters with a 1 count then return -1. If exactly one letter has a 1 count, then return the position of that letter from the position array. If more than one letter has a 1 count, then pick the one with the lowest value for its position.
Using two loops is a highly inefficient way of solving this problem. The string can be up to 100,000 characters long and you are processing it multiple times. Far better to process it only once, keeping track of what you have found so far.
Fix you code
You need to add a variable that tells you if you have breaked the loop or not
static int firstUniqChar(String s) {
boolean duplicate;
for (int i = 0; i < s.length(); i++) {
duplicate = false;
for (int j = i + 1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
duplicate = true;
break;
}
}
if (!duplicate) {
return i;
}
}
return -1;
}
Improve
There is a smarter way, that is finding the last index occurence of the current char, if it's equal to the current index : that char is unique and you return its index
static int firstUniqChar(String s) {
for (int i = 0; i < s.length(); i++) {
if (s.lastIndexOf(s.charAt(i)) == i) {
return i;
}
}
return -1;
}
If you do not bother about time complexity using IdenxOF operations, then one can try this solution.
indexOf() – also runs in linear time. It iterates through the internal array and checking each element one by one. So the time
complexity for this operation always requires O(n) time.
int firstUniqCharOneLoop(String str) {
for (int i = 0; i < str.length(); i++) {
if (str.indexOf(str.charAt(i))== str.lastIndexOf(str.charAt(i)) ) {
return i;
}
}
return -1;
}
The lowest complexity I managed to achieve:
public class UniqueSymbolFinder {
static int findFirstUniqueChar(String s) {
Set<Character> set = new HashSet<>(s.length());
List<CharWithIndex> candidates = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
CharWithIndex charWithIndex = new CharWithIndex(ch, i);
if (set.add(ch)) {
candidates.add(charWithIndex);
} else {
candidates.remove(charWithIndex);
}
}
return candidates.size() == 0 ? -1 : candidates.get(0).index;
}
/**
* Class for storing the index.
* Used to avoid of using an indexOf or other iterations.
*/
private static class CharWithIndex {
int index;
char ch;
private CharWithIndex(char ch, int index) {
this.ch = ch;
this.index = index;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CharWithIndex that = (CharWithIndex) o;
return ch == that.ch;
}
#Override
public int hashCode() {
return Objects.hash(ch);
}
}
}
I believe the memory usage can still be optimized.
100% Correct JAVA Solution
Since the question is about returning the index of the first non-repeating character in a string, we need some data structure to save the index of each character in the string for us.
I choose here the HashMap of Java. Basically, what you can do with it, you can save a pair of values (or pair of other data structures).
So, in my solution, I am saving a Character Integer pair. The first is considered as a key (here it is each character in the string), and the second is its index value.
The problem here is that we only want to keep the minimum index of non-repeating characters and that's why if you take a look below, you will find the maxIndexForRepeatedValues is set to be 10 power 5 as the input constraint says 1 <= s.length <= 10 power 5.
However, I am using that value to neglect repeated characters that would be found in the HashMap and at the end, we retrieve the minimum index which is the index of course for the first character from the map, or if there were only repeated characters, we return -1.
To make the code shorter, I used ternary-operator but you can write it with if-else if you want!
class Solution {
public int firstUniqChar(String s) {
int maxIndexForRepeatedValues = 100000;
Map<Character, Integer> map = new HashMap<>();
for (int i = 0 ; i < s.length() ; i++) {
char key = s.charAt(i);
int resIndex = map.containsKey(key) ? maxIndexForRepeatedValues : i;
map.put(key, resIndex);
}
int minIndex = Collections.min(map.values());
return minIndex == maxIndexForRepeatedValues ? -1 : minIndex;
}
}

How to reverse an integer?

I have a code to reverse an integer, but it does not work, can't seem to find the bug.
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
} else if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}
Sometimes it is easier and/or better to rewrite instead of debugging.
Write or think of your algorithm in pseudocode where each high level step is then broken down into more pseudocode. Your conditions seem strange and therefore hard to debug.
It is best not to embed a print directly into the heart of a loop. Rather, build a string and return it. Let the caller print a string.
System.out.println (reverseInt (12345));
public static String reverseInt (anInt) {
Initialize a StringBuffer with an empty string.
while (anInt > 0) {
Get last digit by modulo 10 and put in StringBuffer.
Prepend digit in StringBuffer.
Chop off last digit by doing integer divide.
}
return StringBuffer's .toString ();
}
An alternate algorithm would call reverseInt recursively to build an ever growing string.
if and else if both works together in a sequence from top to down
if(true) { execute } else if() { done execute even if condition is true } else { done execute}
if(false) else if(check condition) { if true execute other wise go to next condition}
So on..
in your case, this is going to be solution
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
}
if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}

Implement String.length method by hand

I have to implement the .length method from String class "by hand" and I have no idea and hope you can help somehow.
No other methods or functions are allowed, than:
String.charAt()
String.substring()
String.isEmpty()
Bit-operations &,|, &&,||, <<, >>,>>>, !=, ==
Arithmetic operations
for and while Loop
recursion
if else statement
self created methods (int,String,char,boolean etc.)
self-created Arrays. (no Methods of them)
static void manual_length2(String length) {
//example String length = "Hello" = 5 letters.
int counter = 0;
int i = 0;
char g = ' ';
while(i <= 4 ) { /*4 is the number i already know */
g = length.charAt(i);
counter += 1;
length.substring(1);
++i;
}
System.out.println(counter);
Console: 5
This was my approach, but I'm stuck in the while statement's condition to terminate.
With the example "Hello" i already know that this word has 5 letters, but it needs to fit for all inputs. So i don't know how to express to border-value of the while statement.
Another approach is by recursion, but also, i ask myself how can i express the limit of the recursion.
How can i express:
.... lengthMethod1(String length, int ???) {
if(n == 0) {
return length.charAt(0);
}
else {
return ???? lengthMethod1(length, n - 1);
}
You can loop until the String is empty while removing the first character on each iteration.
static int manual_length(String str) {
int len = 0;
while(!str.isEmpty()){
++len;
str = str.substring(1);
}
return len;
}
This can be converted to a tail-recursive method as well.
static int manual_length(String str) {
return str.isEmpty() ? 0 : 1 + manual_length(str.substring(1));
}
Another approach is by recursion, but also, i ask myself how can i
express the limit of the recursion. How can i express:
Yes, you can do recursively like this:
static int manual_length(String str, int len) {
return str.isEmpty() ? len : manual_length(str.substring(1), len + 1);
}
You use an accumulator variable (i.e., len), that you increment, while removing a char from the string (i.e., str.substring(1)). When you reach the end (i.e., str.isEmpty()) you return the accumulator.

Parity - Recursion java

I have the Parity checker problem: A binary string is a string that contains only '0' and '1'characters. The parity of a binary
string is defined as follows. If the number of times that the character '1' appears in this string
is even, the parity it 0; if it’s odd, the parity is 1. For example, the parity of "101" is 0, the
parity of "10110" is 1, and the parity of "001001101" is 0. Write a function, using the signature
public static int parity(String binaryStr)
//no changes are allowed & only use recursive solution, no loops allowed
I managed to write it iteratively however my recursion is out of outOfboundries:
public static int parity(String binaryStr) {
int counter = 0;
for (int i = 0; i < binaryStr.length () ; i++) {
if (binaryStr.charAt (i) == 49) {
counter++;
}
}
if ( counter % 2 == 0 ) {
return 0;
}
else {
return 1;
}
}
recursive:
private static int index = 0;
private static int ans = 0;
private static int parity(String binaryStr) {
if ( index == binaryStr.length ()-1 ) {
if ( ans % 2 == 0 ) {
return 0;
}
else {
return 1;
}
}
else if ( binaryStr.charAt (index) == '1' ) {
ans++;
return parity (binaryStr.substring (index++));
}
return parity (binaryStr.substring (index++));
}
please help me correct it
The major issue with your code is passing binaryStr.substring (index++) to the recursive call, which passes the original String instead of a substring. Hence you get infinite recursion. You can use ++index.
Instead of using static variables, I suggest the following:
private static int parity(String binaryStr) {
if (binaryStr.length() == 0) {
return 0;
} else {
return ((binaryStr.charAt(0) == '0') ? 0 : 1) ^ parity(binaryStr.substring(1));
}
}
Explanation:
If the two operands of bit-wise XOR (^) are equal, it returns 0. If one operands is 0 and the other is 1, it returns 1.
That's exactly the logic you need:
If the first character is '1' and the rest of the String has parity 1 (i.e. odd number of '1's), the whole String's parity is 0.
If the first character is '1' and the result of the String has parity 0 (i.e. even number of '1's, the wholeString`'s parity is 1.
If the first character is '0', the parity of the whole String is the same as the parity of the rest of the String.

some weird stff im running into on java

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;
}

Categories

Resources