Hi I have issue with changing my input to uppercase using recursion. This is my homework and the instruction said I'm not allowed to use toUpperCase() and/or isUpperCase() method.
I have tried using loop and it worked.
import java.util.Arrays;
public class hw5 {
static void convertCase(String str) {
int[] asciiArray = new int[str.length()];
char[] charArray = new char[asciiArray.length];
int ascii = 0;
for(int i = 0; i < str.length(); i++) {
char character = str.charAt(i);
ascii = (int) character;
//change the value if lower case
if(ascii >= 97 && ascii <= 122) {
asciiArray[i] = ascii-32;
charArray[i] = (char) asciiArray[i];
}
//don't change the value if the value is already uppercase or 0-9 (I think this is the base case)
else if((ascii >= 65 && ascii <= 90) || (ascii >= 48 && ascii <= 57)) {
asciiArray[i] = ascii;
charArray[i] = (char) asciiArray[i];
}
System.out.print(charArray[i]);
}
}
public static void main(String[] args) {
convertCase("uPPerCAse123");
}
}
Output:
UPPERCASE123
How to write those using recursion?
One way that we could introduce recursion into your current logic would be to replace the iterative for loop with recursive calls:
public static void convertCase(String str) {
convertCase(str, 0, str.length()-1);
}
private static void convertCase(String input, int start, int end) {
if (input == null || start > end) {
return;
}
char character = input.charAt(start);
int ascii = (int) character;
if (ascii >= 97 && ascii <= 122) {
character = (char)(ascii-32);
}
System.out.print(character);
convertCase(input, start+1, end);
}
public static void main(String args[]) throws Exception {
convertCase("all lowercase HERE");
}
This prints:
ALL LOWERCASE HERE
Each recursive call prints one letter of the string, using a start input pointer. Then, it makes a recursive call, incrementing that start pointer by one, to recursively work its way down the input string.
public String stringToUpperCase(String str){
if (str.length==1) return charToUpperCase((char)str[0]);
return charToUpperCase((char)str[0]) + stringToUpperCase(str.substring(1,str.length-1));
public Char charToUpperCase(Char char){
int ascii = (int)char;
if (ascii >= 97 && ascii <= 122) {
ascii -= 32;
}
return (Char)ascii;
}
public static void(String... args){
System.out.println(stringToUpperCase("asdf");
}
In this version stringToUpperCase() explicitly calls itself, which is the key of recursion.
public class Main {
public static void main(String [] args){
String word ="sathira";
convertUpper(word,word.length());
}
static void convertUpper(String word,int length){
if (word==null||length ==0)
return;
char character = word.charAt(length-1);
int ascii = (int) character;
if (ascii >= 97 && ascii <= 122) {
character = (char)(ascii-32);
}
convertUpper(word,length-1);
System.out.print(character);
}
}
Here my version of to upper case for one character (only ASCII, not tested):
char static toUpper(char ch) {
if (ch >= 'a' && ch <= 'z') {
ch += 'A' - 'a';
}
return ch;
}
or, converted to conditional operator:
ch = (ch >= 'a' && ch <= 'z') ? (char) (ch + 'A' - 'a') : ch;
these can easily be inserted in any of the other recursive solutions already presented in the other answers (not sure which one I prefer, it's strange to have that done in a recursive way)
Here is a recursive implementation in Java. It is based on head recursion -
public class Main {
public static void main(String []args){
String changed = toUpperCaseRec("sTr12uv3X");
System.out.println(changed);
}
static String toUpperCaseRec(String str) {
if(str == null || str.length() == 0) {
return "";
}
String rem = toUpperCaseRec(str.substring(1));
Character cc = convertToUppercase(str.charAt(0));
return cc+rem;
}
static Character convertToUppercase(Character chr) {
if(chr >= 97 && chr <= 122) {
return (char)(chr - 32);
} else {
return chr;
}
}
}
Related
The method takes 2 parameters (String,char) and returns the string with the char replaced by '+' if index is even and '#' if index is odd.
The String I use is "Mary Bella Abracadabra" and the expected output is "M+ry Bell+ +br#c#d#br+". Instead I get "M#ry Bell# #br#c#d#br#".
I can't find the error in my code. It seems that all indexes where char ch is found are odd.
public String emphasize (String phrase, char ch){
String phraseEmph = "";
char c1 = '#';
char c2 = '+';
for (int i=0; i < phrase.length(); i++){
char c = phrase.charAt(i);
char cc = Character.toLowerCase(c);
if ((cc == ch) && ((i % 2) == 0)){
phraseEmph = phrase.replace(c,c2);
phrase = phraseEmph;
}
else if ((cc == ch) && ((i % 2)!= 0)){
phraseEmph = phrase.replace(c,c1);
phrase = phraseEmph;
}
phrase = phrase;
}
return phrase;
}
public void testEmphasize(){
String phrase = "Mary Bella Abracadabra";
char ch = 'a';
String Emphasized = emphasize(phrase,ch);
System.out.println("Emphasized : " + Emphasized);
}
When you call replace it doesn't just replace the current 'a', it replaces all of them. You'll need to find a different way to replace characters so that you only change one at a time.
(I've purposefully avoided suggesting a fix. It'll be more educational if you come up with it yourself.)
Note Array start with 0 in java. String is immutable and don't provide many mutable methods. It's best to make use of StringBuilder as shown below both for easiness and memory efficiency.
public static String emphasize(String phrase, char ch) {
StringBuilder phraseEmph = new StringBuilder(phrase);
char c1 = '#';
char c2 = '+';
for (int i = 0; i < phrase.length(); i++) {
char c = phrase.charAt(i);
char cc = Character.toLowerCase(c);
if ((cc == ch) && ((i % 2) == 0)) {
phraseEmph.setCharAt(i, c2);
} else if ((cc == ch) && ((i % 2) != 0)) {
phraseEmph.setCharAt(i, c1);
}
}
return phraseEmph.toString();
}
Use StringBuilder instead of String for concatenation to a string inside a loop because it is much faster and consumes less memory.
Convert both the characters in the same case (e.g. lowercase) before comparing. This way, you can pass the character to the function in any case.
You should not use String#replace for this case as it replaces all occurrences of replacement character/string in the string being replaced.
Demo:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(emphasize("Mary Bella Abracadabra", 'a'));
System.out.println(emphasize("Mary Bella Abracadabra", 'A'));
}
public static String emphasize(String phrase, char ch) {
char c1 = '#';
char c2 = '+';
StringBuilder sb = new StringBuilder();
// Convert the char parameter to lower case
char chLower = Character.toLowerCase(ch);
for (int i = 0; i < phrase.length(); i++) {
char c = phrase.charAt(i);
if (Character.toLowerCase(c) == chLower) {
if (i % 2 == 0) {
sb.append(c1);
} else {
sb.append(c2);
}
} else {
sb.append(c);
}
}
return sb.toString();
}
}
Output:
M+ry Bell+ +br#c#d#br+
M+ry Bell+ +br#c#d#br+
Here are some suggestions.
use a StringBuilder to make the character replacements. Intialize to the original string. You can then use setCharAt to make the change.
Use indexOf in conjunction with toLowerCase. Then you don't need to verify if you found the character, just use the index returned and return the final string if -1.
then just check for even or or indices like you are doing but assign to a holding char variable.
Then use that to replace the character. Like this pseudocode
char repl;
if (even) {
repl = '#';
} else {
repl = '+';
}
make replacement
don't do a check for both even or odd. Just check for one condition, Otherwise it must be the other condition (not need to check again).
Aside from my recommendations, here is another way of doing it.
The main difference is that it uses the even/odd result to index into the array to replace the character.
public static String emphasize(String phrase, char ch) {
StringBuilder sb = new StringBuilder(phrase);
char[] chars = { '#', '+' };
int idx = -1;
while ((idx = phrase.toLowerCase().indexOf(ch, idx + 1)) >= 0) {
sb.setCharAt(idx, chars[idx % 2]);
phrase = sb.toString();
}
return phrase;
}
Full tested simplified code :
public class Main {
public static void main(String[] args) {
String phrase = "Maryaa Bella Abracadabra";
char ch = 'a';
System.out.println("Original : " + phrase);
String Emphasized = emphasize(phrase,ch);
System.out.println("Emphasized : " + Emphasized);
}
public static String emphasize (String phrase, char ch){
StringBuilder temp = new StringBuilder(phrase);
char c1 = '#';
char c2 = '+';
for (int i = 0; i < phrase.length(); i++){
char c = phrase.charAt(i);
char cc = Character.toLowerCase(c);
if(cc == ch) {
if(i%2 == 0){
temp.setCharAt(i, c1);
} else {
temp.setCharAt(i, c2);
}
}
}
return temp.toString();
}
}
Output :
Original : Maryaa Bella Abracadabra
Emphasized : M+ry#+ Bell+ +br#c#d#br+
Your code is very inefficient, my suggestion :
class emphasize {
private String phrase;
private char ch;
public emphasize(String phrase, char ch) {
this.phrase = phrase;
this.ch = ch;
}
public String execute() {
char chars[] = phrase.toCharArray();
for (int i = 0 ; i < chars.length ; i++) {
/* As char is primitive type I can use == */
if (chars[i]==Character.toLowerCase(ch) || chars[i]==Character.toUpperCase(ch)) chars[i] = i%2==0 ? '+' : '#';
}
return String.valueOf(chars);
}
}
public class Main {
public static void main(String[] args) {
String phrase = "Mary Bella Abracadabra";
char ch = 'a';
emphasize obj = new emphasize(phrase, ch);
System.out.println(obj.execute());
}
}
Output :
For example: String "abc" should return "nop".
I did a System.out.println and it is printing the correct result, however, the JUnit Test case is giving me a red bar. The method move13 just takes the character and moves it 13 spaces left or right.
The method encode is where I am having trouble with.
package code;
public class Encoder {
public char move13(char letter) {
if (letter >= 'a' && letter <= 'm') {
return (char)(letter + 13);
}
if (letter >= 'A' && letter <= 'M') {
return (char)(letter + 13);
}
if (letter >= 'n' && letter <= 'z') {
return (char)(letter - 13);
}
if (letter >= 'N' && letter <= 'Z') {
return (char)(letter - 13);
}
return letter;
}
public String encode(String text) {
String valueOfchar = "";
for (int i = 0; i < text.length(); i++) {
char character = text.charAt(i);
character = move13(character);
valueOfchar = String.valueOf(character);
System.out.println(valueOfchar);
}
return valueOfchar;
}
}
Here you go, hope it helps
public static char move13(char letter) {
if (letter >= 'a' && letter <= 'm')
return (char) (letter + 13);
if (letter >= 'A' && letter <= 'M')
return (char) (letter + 13);
if (letter >= 'n' && letter <= 'z')
return (char) (letter - 13);
if (letter >= 'N' && letter <= 'Z')
return (char) (letter - 13);
return letter;
}
public static String encode(String text) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char character = text.charAt(i);
character = move13(character);
sb.append(character);
//System.out.println(valueOfchar);
}
return sb.toString();
}
The char are concatenated in a StringBuilder (sb.append(char)). After each letter processed in move13(), you return the concatenated chars (sb.toString()).
We don't see the unit test code, but at a guess, your method encode() will only ever return a single char, not the whole String.
public String encode(String text) {
String valueOfchar = "";
for (int i = 0; i < text.length(); i++) {
....
valueOfchar = String.valueOf(character); // A single char
....
}
return valueOfchar;
Try:
valueOfchar = valueOfchar.concat(String.valueOf(character));
So I have made some code for my AP Computer Science class but my teacher is asking me to not use char or token in my code. I have this one code in particular that I need an alternative (non char) version for.
// returns the first nonzero digit of a string, 0 if no such digit found
public static int firstDigitOf(String token) {
for (char ch : token.toCharArray()) {
if (ch >= '1' && ch <= '9') {
return ch - '0';
}
}
return 0;
}
So yes please help me. This isn't homework its a part of a LARGE project so entire lines of code would be appreciated in particular.
or (char ch : token.toCharArray()) {
This is what I have the most trouble with, I just dont know another way to write this.
you can use this
String token = "helo100s23h04dsd sdksjdksa";
token = token.replaceAll("[^1-9]", "");
// in this case token value will be -> 1234, and the first none zero digit is 1
if (token.length() <= 0) {
// if there is no numbers in token larger than 0
return 0;
} else {
return Character.getNumericValue(token.charAt(0));
}
This will work if the input string is all digits:
public static int firstDigitOf(String digits) {
if (digits.length() == 0)
return 0;
int firstDigit = Integer.parseInt(digits.substring(0, 1));
if (firstDigit > 0)
return firstDigit;
return firstDigitOf(digits.substring(1));
}
Iterative version:
public static int firstDigitOf(String digits) {
int firstDigit = 0;
while (digits.length() != 0) {
firstDigit = Integer.parseInt(digits.substring(0, 1));
if (firstDigit > 0)
break;
digits = digits.substring(1);
}
return firstDigit;
}
If the string might have non-digits, you need to do this:
public static int firstDigitOf(String token) {
if (token.length() == 0)
return 0;
try {
int firstDigit = Integer.parseInt(token.substring(0, 1));
if (firstDigit > 0 && firstDigit < 10)
return firstDigit;
} catch (NumberFormatException e) {
}
return firstDigitOf(token.substring(1));
}
I came up with the following:
public Integer firstDigitOf(String s) {
s=s.replaceAll("[^1-9]","");
return (s.isEmpty())?0:Integer.parseInt(s.substring(0,1));
}
Just replace every non-numerical content and give either 0 or first digit.
In the spirit of overkill, here's a regular expression version. Note that there is no use direct use of char - it is all done with String.
private static Pattern nonZeroDigit = Pattern.compile("[123456789]");
public static int firstDigitOf(String token) {
Matcher digitMatcher = nonZeroDigit.matcher(token);
if (digitMatcher.find()) {
return Integer.parseInt(digitMatcher.group());
} else {
return 0;
}
}
I'm trying to create a short program that would convert all letters that are uppercase to lowercase (from the command line input).
The following compiles but does not give me the result I am expecting. What would be the reason for this??
Eg) java toLowerCase BANaNa -> to give an output of banana
public class toLowerCase{
public static void main(String[] args){
toLowerCase(args[0]);
}
public static void toLowerCase(String a){
for (int i = 0; i< a.length(); i++){
char aChar = a.charAt(i);
if (65 <= aChar && aChar<=90){
aChar = (char)( (aChar + 32) );
}
System.out.print(a);
}
}
}
You are printing the String a, without modifying it. You can print char directly in the loop as follows:
public class toLowerCase
{
public static void main(String[] args)
{
toLowerCase(args[0]);
}
public static void toLowerCase(String a)
{
for (int i = 0; i< a.length(); i++)
{
char aChar = a.charAt(i);
if (65 <= aChar && aChar<=90)
{
aChar = (char)( (aChar + 32) );
}
System.out.print(aChar);
}
}
}
Looks like homework to me, Just a hint. You are printing string a whereas you are modifying the char type aChar, its not modifying the original string a. (Remember strings are immutable).
A cleaner way of writing this code is
public static void printLowerCase(String a){
for(char ch: a.toCharArray()) {
if(ch >= 'A' && ch <= 'Z')
ch += 'a' - 'A';
System.out.print(ch);
}
}
Note: this will not work for upper case characters in any other range. (There are 1,000s of them)
Looks like you're close. :)
For starters...
char aChar = a.charAt(i);
"a" is an array of Strings, so I believe you would want to iterate over each element
char aChar = a[i].charAt(0);
and it also seems like you want to return the value of the modified variable, not of "a" which was the originally passed in variable.
System.out.print(aChar);
not
System.out.print(a);
Hope that helps you.
public static void toLowerCase(String a){
String newStr = "";
for (int i = 0; i< a.length(); i++){
char aChar = a.charAt(i);
if (65 <= aChar && aChar<=90){
aChar = (char)( (aChar + 32) );
}
newStr = newStr + aChar;
}
System.out.println(newStr);
}
You should print newStr outside for loop. You were trying to print it inside the loop
/**
* Method will convert the Lowercase to uppercase
* if input is null, null will be returned
* #param input
* #return
*/
public static String toUpperCase(String input){
if(input == null){
return input;
}
StringBuilder builder = new StringBuilder();
for(int i=0;i<input.length();i++){
char stringChar = input.charAt(i);
if(92 <= stringChar && stringChar <=122){
stringChar = (char)( (stringChar - 32) );
builder.append(stringChar);
}
else if (65 <= stringChar && stringChar<=90)
{
builder.append(stringChar);
}
}
if(builder.length() ==0){
builder.append(input);
}
return builder.toString();
}
public class Changecase
{
static int i;
static void changecase(String s)
{
for(i=0;i<s.length();i++)
{
int ch=s.charAt(i);
if(ch>64&&ch<91)
{
ch=ch+32;
System.out.print( (char) ch);
}
else if(ch>96&&ch<123)
{
ch=ch-32;
System.out.print( (char) ch);
}
if(ch==32)
System.out.print(" ");
}
}
public static void main (String args[])
{
System.out.println("Original String is : ");
System.out.println("Alive is awesome ");
Changecase.changecase("Alive is awesome ");
}
}
public class MyClass
{
private String txt;
private char lower;
public MyClass(String txt)
{
this.txt = txt;
}
public void print()
{
for(int i=0;i<txt.length();i++)
{
if('A' <= txt.charAt(i) && txt.charAt(i) <= 'Z')
{
lower = (char)(txt.charAt(i) + 32);
System.out.print(lower);
}
else
{
lower = txt.charAt(i);
System.out.print(lower);
}
}
}
public static void main(String[] args)
{
MyClass mc = new MyClass("BaNaNa");
mc.print();
}
}
Sorry pretty late to the scene but this should solve it. An else condition because when it is not zero it totally discards the alphabet.
If somebody needs clear code without MagicNumbers and as less as possible conversions here is my solution:
final char[] charArray = new char[string.length()];
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
charArray[i] = Character.isLowerCase(c) ? Character.toUpperCase(c) : Character.toLowerCase(c);
}
String.valueOf(charArray);
import java.util.Scanner;
public class LowerToUpperC {
public static void main(String[] args) {
char ch;
int temp;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a Character in Lowercase : ");
ch = scan.next().charAt(0);
temp = (int) ch;
temp = temp - 32;
ch = (char) temp;
System.out.print("Equivalent Character in Uppercase = " +ch);
}
}
I am trying to search a string for the last index of a capital letter. I don't mind using regular expressions, but I'm not too familiar with them.
int searchPattern = searchString.lastIndexOf(" ");
String resultingString = searchString.substring(searchPattern + 1);
As you can see, with my current code I'm looking for the last space that is included in a string. I need to change this to search for last capital letter.
You can write a method as follows:
public int lastIndexOfUCL(String str) {
for(int i=str.length()-1; i>=0; i--) {
if(Character.isUpperCase(str.charAt(i))) {
return i;
}
}
return -1;
}
Pattern pat = Pattern.compile("[A-Z][^A-Z]*$");
Matcher match = pat.matcher(inputString);
int lastCapitalIndex = -1;
if(match.find())
{
lastCapitalIndex = match.start();
}
lastCapitalIndex will contain the index of the last capital letter in the inputString or -1 if no capitals exist.
EDIT NOTE: Solution formerly contained a loop, now it will work with one call to find() and no looping thanks to an improved regex. Tested new pattern as well, and it worked.
In Android (Java) you can use this:
String s = MyDocumentFileIsHere;
String textWithSpace = s.replaceAll("(.)([A-Z])", "$1 $2");
holder.titleTxt.setText(textWithSpace);
The result of String will be "My Document File Is Here"
You can compare each character of the string with the uppercase characters range in the ASCII table (decimal 65 ('A') to 90 ('Z')).
You can increase the readability of your code and benefit from some other features of modern Java here. Please use the Stream approach for solving this problem.
/**
* Finds the last uppercase letter in a String.
*/
public class FindLastCapitalLetter {
public static void main(String[] args) {
String str = "saveChangesInTheEditor";
int lastUppercaseLetter = findLastUppercaseLetter(str);
if (lastUppercaseLetter != -1) {
System.out.println("The last uppercase letter is "
+ Character.toString((char) lastUppercaseLetter));
} else {
System.out.println("No uppercase letter was found in the String.");
}
}
private static int findLastUppercaseLetter(String str) {
return new StringBuilder(str).reverse().toString().chars()
.filter(c -> Character.isUpperCase(c)).findFirst().orElse(-1);
}
}
Sample output:
The last uppercase letter is E
Also, this code gives you the index of the last capital letter in the String.
import java.util.stream.IntStream;
/**
* Finds the index of the last uppercase letter in a String.
*/
public class FindIndexOfLastUppercaseLetter {
public static void main(String[] args) {
String str = "saveChangesInTheEditor";
int lastUppercaseLetterIndex = findLastUppercaseLetter(str);
if (lastUppercaseLetterIndex != -1) {
System.out.println("The last uppercase letter index is " + lastUppercaseLetterIndex
+ " which is " + str.charAt(lastUppercaseLetterIndex));
} else {
System.out.println("No uppercase letter was found in the String.");
}
}
private static int findLastUppercaseLetter(String str) {
int[] stringChars = str.chars().toArray();
int stringCharsLenght = stringChars.length;
return IntStream.range(0, stringCharsLenght)
.map(i -> stringCharsLenght - i - 1)
.filter(i -> Character.isUpperCase(stringChars[i]))
.findFirst().orElse(-1);
}
}
Sample output:
The last uppercase letter index is 16 which is E
LeetCode - Detect capitals
class Solution {
public boolean detectCapitalUse(String word) {
int len = word.length();
if (word.charAt(0) >= 'A' && word.charAt(0) <= 'Z') {
if (word.charAt(len-1) >= 'A' && word.charAt(len-1) <= 'Z') {
for (int i = 1 ; i < len-1 ; i++) {
if ( word.charAt(i) < 'A' || word.charAt(i) > 'Z')
return false;
}
} else {
for (int i = 1 ; i <= len-1 ; i++) {
if ( word.charAt(i) < 'a' || word.charAt(i) > 'z')
return false;
}
}
} else {
for (int i = 0 ; i <= len-1 ; i++) {
if ( word.charAt(i) < 'a' || word.charAt(i) > 'z')
return false;
}
}
return true;
}
}