Convert uppercase string to lowercase using charAt - java

I was wondering what is exactly wrong with the following code. I'm getting error on the line after the if statement. This code takes a string with both uppercase and lowercase letters but returns the string after converting the uppercase letters to lowercase.
public class Main {
public static void main(String[] args) {
toLowerCase("HeLloWoRlD!");
}
private static String toLowerCase(String str) {
for (int i = 0; i < str.length(); i++) {
if (Character.isUpperCase(str.charAt(i))) {
str.charAt(i) = Character.toLowerCase(str.charAt(i));
}
}
return str;
}
}

str.charAt(i) cannot be the left hand side of an assignment operator. It's a value returned by a method call, you can't assign to it.
Besides, Strings are immutable. You cannot modify the characters of str.
You'll have to create a new String for your method to return.
For example:
private static String toLowerCase(String str) {
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < str.length(); i++) {
if (Character.isUpperCase(str.charAt(i))) {
sb.append (Character.toLowerCase(str.charAt(i)));
} else {
sb.append (str.charAt(i));
}
}
return sb.toString();
}

Change you code to the following :
private static String toLowerCase(String str) {
StringBuffer lower = new StringBuffer();
for (int i = 0; i < str.length(); i++) {
if (Character.isUpperCase(str.charAt(i))) {
lower.append(Character.toLowerCase(str.charAt(i)));
} else {
lower.append(str.charAt(i));
}
}
return lower.toString();
}
public static void main(String[] args) throws IOException {
System.out.println(toLowerCase("HeLloWoRlD!"));
}
A string is immutable so you can't change the existing one on the fly. Instead you can create a StringBuffer and append the values accordingly as you iterate over the original str.

String is immutable so you cannot change (reassign) the characters inside the string.
Here is the simplest solution, just using the built in method in String class:
private static String toLowerCase(String str) {
return str == null ? null : str.toLowerCase(); //consider str.toLowerCase(Locale.ROOT) if you are using non english language with special characters
}

You are making use of the String.charAt(i) which returns character Value at that position. It is not the reference location that you can assign a value to.
Please check the below documentation.
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#charAt-int-
You need to convert to a character Array the string if you want to modify it using the charAt feature
private static String toLowerCase(String str) {
char[] newStr = str.toCharArray();
for (int i = 0; i < str.length(); i++) {
if (Character.isUpperCase(str.charAt(i))) {
newStr[i] = Character.toLowerCase(str.charAt(i));
}
}
return new String(newStr);
}

The method charAt(i) is used for getting character by index(position) in the string. However, You used it for setting, what is not right.
So, in your case, method toLowerCase() should return new String object, for example.
private static String toLowerCase(String str) {
String returning_Str = "";
for (int i = 0; i < str.length(); i++) {
char test_char = str.charAt(i);
if (Character.isUpperCase(test_char)) {
test_char = Character.toLowerCase(test_char);
}
returning_Str += test_char;
}
return returning_Str;
}

You cannot change the content of a String. You have to create a new object instead:
public class Main {
public static void main(String[] args) {
toLowerCase("HeLloWoRlD!");
}
private static String toLowerCase(String str) {
for (int i = 0; i < str.length(); i++) {
if (Character.isUpperCase(str.charAt(i))) {
str = new String(str.replace(str.charAt(i),Character.toLowerCase(str.charAt(i))));
}
}
return str;
}
}

First take a variable the assign value on it.
This code will work as expected
public class Main {
public static void main(String[] args) {
System.out.println(toLowerCase("HeLloWoRlD!"));
}
private static StringBuffer toLowerCase(String str) {
StringBuffer buf=new StringBuffer();
for (int i = 0; i < str.length(); i++) {
char c=str.charAt(i);
if (Character.isUpperCase(str.charAt(i))) {
c = Character.toLowerCase(str.charAt(i));
buf.append(c);
}else{
buf.append(c);
}
}
return buf;
}
}

private static String toLowerCase(String str){
return str.chars().map(Character::toLowerCase).collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
or
private static String toLowerCase(String str){
return str.toLowerCase();
}

Related

I need help converting strings into camelCase with multiple "_" using loop

My code doesnt convert ex. dog_cat_dog into dogCatDog. The out put of my code is dogCat_dog. Trying to make a loop that doesn't stop at the first "_":
public String underscoreToCamel(String textToConvert) {
int index_= textToConvert.indexOf("_",0);
String camelCase="";
String upperCase = "";
String lowerCase="";
for (int i=0; i < textToConvert.length(); i++){
if(i==index_){
upperCase= (textToConvert.charAt(index_+1)+upperCase).toUpperCase();
upperCase= upperCase+ textToConvert.substring(index_+2);
}
else{
lowerCase=textToConvert.substring(0,index_);
}
camelCase=lowerCase+upperCase;
}
return camelCase;
}
I would do the following: make the method static, it does not use any class state. Then instantiate a StringBuilder with the passed in value, because that is mutable. Then iterate the StringBuilder. If the current character is underscore, delete the current character, then replace the now current character with its upper case equivalent. Like,
public static String underscoreToCamel(String s) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) == '_') {
sb.deleteCharAt(i);
char ch = Character.toUpperCase(sb.charAt(i));
sb.setCharAt(i, ch);
}
}
return sb.toString();
}
I tested like
public static void main(String[] args) {
System.out.println(underscoreToCamel("dog_cat_dog"));
}
Which outputs (as requested)
dogCatDog
You can split on '_' then rebuild.
public static String underscoreToCamel(String textToConvert) {
String [] words = textToConvert.split("_");
StringBuilder sb = new StringBuilder(words[0]);
for (int i = 1; i < words.length; i++) {
sb.append(Character.toUpperCase(words[i].charAt(0)));
sb.append(words[i].substring(1));
}
return sb.toString();
}
I think an easy way to solve this is to first consider the base cases, then tackle the other cases
public static String underscoreToCamel(String textToConvert){
//Initialize the return value
String toReturn = "";
if (textToConvert == null){
//Base Case 1: null value, so just return an empty string
return "";
} else if (textToConvert.indexOf("_") == -1) {
//Base Case 2: string without underscore, so just return that string
return textToConvert;
} else {
//Primary Case:
//Find index of underscore
int underscore = textToConvert.indexOf("_");
//Append everything before the underscore to the return string
toReturn += textToConvert.substring(0, underscore);
//Append the uppercase of the first letter after the underscore
toReturn += textToConvert.substring(underscore+1, underscore+2).toUpperCase();
//Append the rest of the textToConvert, passing it recursively to this function
toReturn += underscoreToCamel(textToConvert.substring(underscore+2));
}
//Final return value
return toReturn;
}

Reverse String Method type mismatch error java

I am trying to use a method to reverse the characters in a string and I keep getting a type mismatch error. Any thoughts?
public static String userReverse (String userEntry3) {
String reverse = "";
for (int i = (userEntry3.length() -1); i >= 0 ; i--) {
reverse = System.out.println(userEntry3.charAt(i));
}
return reverse;
}
System.out.println is a void method. It returns nothing. So it cannot assigned back to a String variable
Your code is wrong.
If you want to reverse a string, you can use this:
public static String userReverse (String userEntry3) {
return new StringBuilder(userEntry3).reverse().toString()
}
Get rid of System.out.println and add a += to concatenate the new char
public static String userReverse (String userEntry3) {
String reverse = "";
for (int i = (userEntry3.length() -1); i >= 0 ; i--) {
reverse += userEntry3.charAt(i);
}
return reverse;
}
EDIT: As Tim said in the comments, StringBuilder can be used too (and is better practice than concatenating strings in a loop):
public static String userReverse (String userEntry3) {
StringBuilder reverse = new StringBuilder();
for (int i = (userEntry3.length() -1); i >= 0 ; i--) {
reverse.append(userEntry3.charAt(i));
}
return reverse.toString();
}
A more optimized way to reverse a string includes two pointer approach:
Use one pointer to start from the beginning and the other to start from the end. By the time they meet each other your string is already reversed
public static String userReverse (String userEntry3) {
int i = 0;
int j = userEntry3.length()-1;
StringBuilder myName = new StringBuilder(userEntry3);
for(; i < j ; i++,j--){
char temp = userEntry3.charAt(i);
myName.setCharAt(i,userEntry3.charAt(j));
myName.setCharAt(j,temp);
}
return myName.toString();
}
System.out.println() is a void method and it not return anything. you should try it this way,
public static String userReverse (String userEntry3) {
String reverse = "";
for (int i = (userEntry3.length() -1); i >= 0 ; i--) {
reverse += userEntry3.charAt(i).toString();
}
return reverse;
}

Using StringBuilder getting null as output

I am doing one coding question in which I try to decrypt the input string. The procedure for the decryption is:
from 0 to 9 it represent alphabets from a to i.
then 10# represent j, 11# represent k and so.
import java.util.HashMap;
public class Julia {
public static void main(String[] args) {
String s="10#21#12#91";
Julia obj=new Julia();
String result=obj.decrypt(s);
System.out.println(result);
}
public String decrypt(String msg)
{
HashMap<String,Character> hs=new HashMap<>();
hs.put("1",'a');
hs.put("2",'b');
hs.put("3",'c');
hs.put("4",'d');
hs.put("5",'e');
hs.put("6",'f');
hs.put("7",'g');
hs.put("8",'h');
hs.put("9",'i');
hs.put("10",'j');
hs.put("11",'k');
hs.put("12",'l');
hs.put("13",'m');
hs.put("14",'n');
hs.put("15",'o');
hs.put("16",'p');
hs.put("17",'q');
hs.put("18",'r');
hs.put("19",'s');
hs.put("20",'t');
hs.put("21",'u');
hs.put("22",'v');
hs.put("23",'w');
hs.put("24",'x');
hs.put("25",'y');
hs.put("26",'x');
StringBuilder n=new StringBuilder();
for(int i=msg.length()-1;i>=0;i--)
{
if(msg.charAt(i)=='#' && i>=2)
{
StringBuilder s=new StringBuilder().append(msg.charAt(i-2)).append(msg.charAt(i-1));
System.out.println(s);
n.append(hs.get(s));
System.out.println(n);
i=i-2;
}
else
{
n.append(hs.get(msg.charAt(i)));
}
}
return n.toString();
}
}
That is code I wrote. But the output I am getting is nullnullnullnullnull.
I think the issue is with StringBuilder. Can anyone help me with that and explain the concept? If someone has better solution please guide.
You should not use data (a map) when you could have used a simple formula.
My suggestion:
import java.util.ArrayList;
import java.util.List;
public final class Julia {
public static void main(final String[] args) {
final String s = "10#21#12#91";
final String result = decrypt(s);
System.out.println(result);
}
private static String decrypt(final String s) {
final List<Integer> crypt = new ArrayList<>();
final String[] groups = s.split("#");
for (int i = 0; i < groups.length; i++) {
final String group = groups[i];
int j = 0;
// Special case for last group
if ((i == (groups.length - 1)) && !s.endsWith("#")) {
j = group.length();
}
if (group.length() > 2) {
j = group.length() - 2;
}
for (int k = 0; k < j; k++) {
crypt.add(Integer.valueOf(group.substring(k, k + 1)));
}
if (j < group.length()) {
crypt.add(Integer.valueOf(group.substring(j, group.length())));
}
}
final StringBuilder n = new StringBuilder(crypt.size());
for (final Integer c : crypt) {
final char d = (char) (('a' + c) - 1);
n.append(d);
}
return n.toString();
}
}
Please note that there are two mistakes in the question: The letter a is 1, not zero, and the value for 26 is z, not x. The latter error is typical when you use data where a formula would do.
Since you are learning, I would note that the decrypt methods - both my suggestion and yours - should be static since they do not use any fields, so the instantiation is not necessary.
This is Pattern Matching problem which can be solved by Regex.
Your code has some bugs and those are already pointed out by others. I don't see any solution which looks better than a simple regex solution.
Below regex code will output 'julia' for input '10#21#12#91'.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Julia {
public static void main(String[] args) {
String s="10#21#12#91";
Julia obj=new Julia();
String result=obj.decrypt(s);
System.out.println(result);
}
public String decrypt(String msg)
{
Pattern regex = Pattern.compile("((\\d\\d#)|(\\d))");
Matcher regexMatcher = regex.matcher(msg);
StringBuffer result = new StringBuffer();
while (regexMatcher.find())
regexMatcher.appendReplacement(result, getCharForNumber(Integer.parseInt(regexMatcher.group(1).replace("#",""))));
return result.toString();
}
private String getCharForNumber(int i) {
return i > 0 && i < 27 ? String.valueOf((char)(i + 96)) : null;
}
}
I hope it helps.
hs.get(s) will always return null, since s is not a String.
Try hs.get(s.toString())
hs.get(msg.charAt(i)) will also always return null, since you are passing a char to get instead of String.
There may also be logic problems in your code, but it's hard to tell.
Optimized version of your code
public class Main {
public static void main(String[] args) {
String cipher = "10#21#12#91";
System.out.print(decrypt(cipher));
//output : julia
}
static String decrypt(String cipher) {
//split with # to obtain array of code in string array
String[] cipher_char_codes = cipher.split("#");
//create empty message
StringBuilder message = new StringBuilder();
//loop for each code
for (String code : cipher_char_codes) {
//get index of character
int index = Integer.parseInt(code);
if (index > 26) {
char[] pair = code.toCharArray();
for (int i = 0; i < pair.length; i++) {
int x = Integer.parseInt("" + code.charAt(i));
message.append((char) ('a' + ((x - 1) % 26)));
}
} else {
//map index into 1 to 26
//find ascii code and cast into char
message.append((char) ('a' + ((index - 1) % 26)));
}
}
return message.toString();
}
}
Regex is indeed the way to go, and the code proposed by Pirate_Jack can be improved. It calls the expensive regex two superfluous times (replace is a regex operation).
Following is a yet improved version:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class Julia3 {
public static void main(final String[] args) {
final String s = "10#21#12#91";
final String result = decrypt(s);
System.out.println(result);
}
public static String decrypt(final String msg) {
final Pattern regex = Pattern.compile("((\\d\\d)(#)|(\\d))");
final Matcher regexMatcher = regex.matcher(msg);
final StringBuffer result = new StringBuffer();
String c;
while (regexMatcher.find()) {
if (regexMatcher.group(2) == null) {
c = regexMatcher.group(1);
} else {
c = regexMatcher.group(2);
}
result.append((char) ((Integer.parseInt(c) + 'a') - 1));
}
return result.toString();
}
}
This is not right :
hs.get(s)
s is a StringBuilder. It should be hs.get(Char)
Edit: an optional different solution:
public class Julia {
public static void main(String[] args) {
String s="10#21#12#91";
List<String> numbers = splitToNumbers(s);
Julia obj=new Julia();
String result=obj.decrypt(numbers);
System.out.println(result);
}
/**
*#param s
*#return
*/
private static List<String> splitToNumbers(String s) {
//add check s is not null
char[] chars = s.toCharArray();
char delimiter = '#';
List<String> numberAsStrings = new ArrayList<String>();
int charIndex = 0;
while (charIndex < (chars.length -3)) {
char theirdChar = chars[charIndex+2];
if(theirdChar == delimiter) {
numberAsStrings.add(""+chars[charIndex]+chars[charIndex+1]);
charIndex +=3;
}else {
numberAsStrings.add(""+chars[charIndex]);
charIndex ++;
}
}
//add what's left
while (charIndex < chars.length) {
numberAsStrings.add(""+chars[charIndex]);
charIndex++;
}
return numberAsStrings;
}
public String decrypt(List<String> numbersAsStings){
StringBuilder sb=new StringBuilder();
for (String number : numbersAsStings) {
int num = Integer.valueOf(number);
sb.append(intToChar(num-1));
}
return sb.toString();
}
private char intToChar(int num) {
if((num<0) || (num>25) ) {
return '?' ;
}
return (char)('a' + num);
}
}

Replace all instances of a character in a String

I'm trying to create a method that replace all instances of a certain character in a word with a new character. This is what I have so far:
public class practice {
public static void main(String[] args) {
String test3 = updatePartialword("----", "test", 't');
System.out.println(test3); }
public static String updatePartialword(String partial, String secret, char c) {
String newPartial = "";
int len = secret.length();
for (int i=0; i<=secret.length()-1; i++){
char x = secret.charAt(i);
if (c==x) {
String first = partial.substring(0,i);
String second = partial.substring(i+1,len);
newPartial = first+x+second;
}
}
return newPartial;
}
}
I want it to return t--t, but it will only print the last t. Any help would be greatly appreciated!
Java already has a built in method in String for this. You can use the the replace() method to replace all occurrences of the given character in the String with the another character
String str = "Hello";
str.replace('l', '-'); //Returns He--o
str.replace('H', '-'); //Returns -ello
I suspect you are looking for something like
public static void main(String[] args) {
String test3 = updatePartialword("----", "test", 't');
System.out.println(test3);
}
public static String updatePartialword(String partial, String secret, char c) {
char[] tmp = partial.toCharArray();
for (int i = 0; i < secret.length(); i++) {
char x = secret.charAt(i);
if (c == x) {
tmp[i] = c;
}
}
return new String(tmp);
}
In your code you overwrite the String each time you found the character. Instead of overwriting, you should expand the string each time.
public class practice {
public static void main(String[] args) {
String test3 = updatePartialword("----", "test", 't');
System.out.println(test3);
}
public static String updatePartialword(String partial, String secret, char c) {
StringBuilder sb = new Stringbuilder();
sb.append(""); // to prevent the Stringbuilder from calculating with the chars
for (int i = 0; i < partial.lenght; i++)
if (secret.charAt(i) == c)
sb.append(c);
else
sb.append('-');
return sb.toString();
}
}

Convert String to its Unicode code point

Assuming I have a string foo = "This is an apple"
The Unicode code point equivalent will be
" \\x74\\x68\\x69\\x73.......... \\x61\\x70\\x70\\x6c\\x65 "
T h i s ............. a p p l e
How do I convert from String foo
to
String " \\x74\\x68\\x69\\x73.......... \\x61\\x70\\x70\\x6c\\x65 "
try this..
public static String generateUnicode(String input) {
StringBuilder b = new StringBuilder(input.length());
for (char c : input.toCharArray()) {
b.append(String.format("\\u%04x", (int) c));
}
return b.toString();
}
Here a working code snippet to make the conversion:
public class HexTest {
public static void main(String[] args) {
String testStr = "hello日本語 ";
System.out.println(stringToUnicode3Representation(testStr));
}
private static String stringToUnicode3Representation(String str) {
StringBuilder result = new StringBuilder();
char[] charArr = str.toCharArray();
for (int i = 0; i < charArr.length; i++) {
result.append("\\u").append(Integer.toHexString(charArr[i] | 0x10000).substring(1));
}
return result.toString();
}
}
That display:
\u0068\u0065\u006c\u006c\u006f\u65e5\u672c\u8a9e\u0020
If you want to get rid of the extra zeros you elaborate it as described here.
Here another version to do the conversion, by passing "This is an apple" you get
\u54\u68\u69\u73\u20\u69\u73\u20\u61\u6e\u20\u61\u70\u70\u6c\u65
by using:
private static String str2UnicodeRepresentation(String str) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
int cp = Character.codePointAt(str, i);
int charCount = Character.charCount(cp);
//UTF characters may use more than 1 char to be represented
if (charCount == 2) {
i++;
}
result.append(String.format("\\u%x", cp));
}
return result.toString();
}

Categories

Resources