Read 2 letters in a string using JAVA - java

I need to write a Java program that reads a string and determines if there are these two letters: the lowercase letter “e” or “d”.
That's what i written so far! any ideas why this doesn't work?
class ex2 {
public static void main(String[] args) {
//boolean arg1;
char e = 'e';
char d = 'd';
String x = "This is my test";
char[] xh = new char[x.length()];
for(int i=0; i<= x.length();i++) {
if (xh[i] == e || xh[i] == d) {
// arg1 = true;
System.out.println("Correct"); // Display he string
} else {
//arg1 = false;
System.out.println("Wrong");
}
}
}
}

First you have an ArrayOutOfBound exception because you need to stop just before the length, i.e. i<x.length().
Now your problem is that you test against an array of char that is full of null chars. You need to test against the string :
if (x.charAt(i) == e || x.charAt(i) == d) {

You never put anything in your array. char[] xh = new char[x.length()]; simply declares an array of length equal to x, it does not set the elements of xh to the elements of x. Instead, use:
char[] xh = x.toCharArray();
You also need to change your loop to:
for(int i=0; i < x.length(); i++) {
to avoid the out of bounds exception you are currently seeing.

Your main problem is the fact that you don't properly iterate over the char of your String, here is the best way to do it:
for (int i = 0, length = x.length(); i < length; i++) {
char c = x.charAt(i);
...
}
Assuming that you use Java 8, you could rely on the Stream API to do the same thing as next:
boolean result = x.chars().anyMatch(c -> c == 'e' || c == 'd');

this is the simple solution if you want to use it
NOTE from comments, you must keep account that if there is no e and d, this will iterate twice on the content of the String but not is second code as second example is just short form of for each
String str = "ewithd";
if (str.contains("e") || str.contains("d")) {
System.out.println("sucess");
} else
System.out.println("fail");
if you want to go with array then you can use foreach() too
char[] ch = str.toCharArray();
for (char c : ch) {
if (c == 'e' || c == 'd') {
System.out.println("success");
else
System.out.println("fail");
}
}

Related

Problem with even indexes in Java program

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 :

How to add new values into existing upperCase to new lowerCase

I am developing a method which takes ArrayList as an argument.
Then, the method makes some changes into the array and returns transformed arrayList.
The input array is going to be like that {A123, C123, 15B2} and I would like to get the following output {Aa123, Cc123, 15Bb2}.
That is to say, after any capital letter I need to add the same lowercase letter.
And there are any order and quantity of letters, e.g. it is also possible to get strings like those Hkjk124, hy71.
The method is shown below:
protected ArrayList<String> enrichValues(ArrayList<String> list) {
for (int i = 0; i < list.size(); i++) {
char[] charArray = list.get(i).toCharArray();
List<Character> listChars = new ArrayList<>();
for (char c : charArray) {
listChars.add(c);
}
for (int j = 0; j < listChars.size(); j++) {
if (listChars.get(j).charValue() == 'A') {
listChars.add(j + 1, 'a');
}
}
String newChar = "";
for (Character c : listChars)
newChar += c.toString();
list.set(i, newChar);
}
return list;
}
The main problem I have faced to is that I do not know how to check if a letter is uppercase.
I failed to apply something like:
if(Character.isLetter(c) && Character.isUpperCase(c)) {
listChars.add(j + 1, 'a');
}
Because of that I have to add lots of checks:
if (listChars.get(j).charValue() == 'B') {
listChars.add(j + 1, 'b');
}
if (listChars.get(j).charValue() == 'C') {
listChars.add(j + 1, 'c');
}
But it is a very bad approach. I would appreciate any help.
Here's a way of doing it that works like a charm :
public static ArrayList<String> enrichValues(ArrayList<String> values){
ArrayList<String> array = new ArrayList<String>();
for (String str : values){ //For each string
StringBuilder copy = new StringBuilder();
for (char c : str.toCharArray()) {//For each char
copy.append(c);
if(Character.isLetter(c) && Character.isUpperCase(c)){
copy.append(Character.toLowerCase(c));
}
}
array.add(copy.toString());
}
return array;
}
Example :
public static void main(String[] args) {
String a = "A123";
String b = "C123";
String c = "15B2";
String d = " Hkjk124";
String e = "hy71";
String g = "AbCdE645 DeeeFFD";
ArrayList<String> values = new ArrayList<String>();
values.add(a);
values.add(b);
values.add(c);
values.add(d);
values.add(e);
values.add(g);
values = enrichValues(values);
System.out.println(values.toString());
}
Output : [Aa123, Cc123, 15Bb2, Hhkjk124, hy71, AabCcdEe645 DdeeeFfFfDd]
When you are writing some method which accepts concrete implementation of the List interface such as ArrayList, consider to change it to List type. This will allow you to pass in any form of list: LinkedList, ArrayList, ...
Another thing you shoud know is, that joining strings via += is inefficient, as it creates new String instance each time += is applied. Instead of doing this, you should use StringBuilder which allocates resizable buffer for string where you can append other characters.
Condition Character.isLetter(c) && Character.isUpperCase(c) is redudant, since Character.isUpperCase(char) already returns false for non-letter characters.
If you need to convert character to lower-case use Character.toLowerCase(char).
Note, characters are basically integers, so when you write something like this: char c = 65; and print the value, you will see 'A' in output, because 65 is ASCII value for character 'A'. If you add 32, you will obtain 97 which is 'a'. Putting all together you can write something like this:
char c = ...;
// c is in range of upper-case characters
if (c >= 65 && c <= 90) {
char lower = c + 32;
}
// c is in range of lower-case characters
if (c >= 97 && c <= 122) {
char upper = c - 32;
}
Try following method which mutates original list:
protected List<String> enrichValues(List<String> list) {
for (int i = 0; i < list.size(); i++) {
StringBuilder sb = new StringBuilder(list.get(i));
for (int j = 0; j < sb.length(); j++) {
char c = sb.charAt(j);
if ( Character.isUpperCase(c) ) {
sb.insert(++j, Character.toLowerCase(c));
}
}
list.set(i, sb.toString());
}
return list;
}
or this one which creates new list for transformed values:
protected List<String> enrichValues(List<String> original) {
List<String> transformed = new ArrayList<>(list.size());
for (String s : original) {
StringBuilder sb = new StringBuilder(s);
for (int j = 0; j < sb.length(); j++) {
char c = sb.charAt(j);
if ( Character.isUpperCase(c) ) {
sb.insert(++j, Character.toLowerCase(c));
}
}
transformed.add(sb.toString());
}
return transformed;
}
Test:
System.out.println( enrichValues(Arrays.asList("A123", "C123", "15B2")) );
// Output: [Aa123, Cc123, 15Bb2]
To find out whether if a letter is upper case you just need to use the ASCII alphabet. Upper case characters go from 65 to 90.
So you just need to use a loop over the length of your string and check for each char if it´s ASCII value is between 65 and 90. So it would look like this, assuming the variable temp is one character of the string:
if((int)temp >= 65 && (int)temp <= 90){
//Add the lower case character by adding 22 to the character value (lower case are from 97-122)
char additionalChar = ((int)temp)+22;
}
Note that I´ve not tried the code so ((int)temp)+22 might not work that way, but it would look pretty similar.
There is an easier way to do this with regular expressions:
final ArrayList< String > outputList = new ArrayList<>();
for ( String str : list ) {
final String[] letters = str.replaceAll( "[^A-Z]", "" ).toLowerCase().split( "" );
final String result = String.format( str.replaceAll( "([A-Z])", "$1%s" ), letters );
outputList.add( result );
}
return outputList;

Is there a way to dynamically change conditions in if statement in Java?

I have this code that filters a String str, keeping only some chars, resulting in the reduced String fStr. The subtlety is that I only keep a target char, if it is not equal to the last char in fStr:
ArrayList<Character> targetChars = //{a, b, c};
String str = "axxbxxxxbxbxcxa", fStr = "";
for(int i = 0, s = 0 ; i < str.length() ; i++) {
char c = str.charAt(i);
if(targetChars.contains(c)) {
if(s > 0 && fStr.charAt(s-1) != c) {
fStr += c;
s++;
}
}
}
fStr → "abca"
In the innermost if statement, I have to include s > 0 before fStr.charAt(s-1) != c, otherwise the latter will throw an OutOfBounds exception the first time targetChars.contains(c) is true. But only the first time, it annoys me that the loop will always check that I won't be out of bounds, given that it only has to do it once. I know I could do something like that:
ArrayList<Character> targetChars = //{a, b, c};
String str = "auebskrubnbocpa", fStr = "";
int i = 0, s = 0;
for(; i < str.length() ; i++) {
char c = str.charAt(i);
if(targetChars.contains(c)) {
fStr += c;
s++;
i++;
break;
}
}
for(; i < str.length() ; i++) {
char c = str.charAt(i);
if(targetChars.contains(c)) {
if(fStr.charAt(s-1) != c) {
fStr += c;
s++;
}
}
}
But is there a more elegant and less annoying way to dynamically truncate a conditional statement?
Is there a way to dynamically change conditions in if statement in Java?
No there isn't. The original version of your code is the best from a readability perspective.
However, if you are concerned about efficiency, then you should be using a StringBuilder rather than fStr += c.
Also a char[] and an explicit for loop is likely to be faster than ArrayList<Character>.contains.
Here is how I would do it, but not sure if it suits your needs
public class Example {
public static void main(String[] args) {
char[] targetChars = {'a', 'b', 'c'};
String str = "axxbxxxxbxbxcxa", fStr = " ";
for(int i = 0 ; i < str.length() ; i++) {
char c = str.charAt(i);
if(isAcceptableChar(c, targetChars)) {
if(fStr.charAt(fStr.length() - 1) != c) {
fStr = fStr.trim() + c;
}
}
}
System.out.println(fStr);
}
private static boolean isAcceptableChar(char newChar, char[] targetChars) {
boolean value = false;
for(char ch : targetChars){
if(ch == newChar) {
value = true;
break;
}
}
return value;
}
}
Sure there is, just call a function that returns a boolean value that you use in your if condition. Different functions could be called at different times by using a function pointer.

Convert java char inside string to lowerCase/upperCase

I have a String called "originalstring" which contains a sentence with mixed upper and lower case characters.
I simply want to flip the string so that if a character is a lowercase make it upper case and vice versa and return it.
I have tried this code, which returns the original string in upperCase:
for (int i = 0; i < originalString.length(); i++) {
char c = originalString.charAt(i);
if (Character.isUpperCase(c)) {
originalString += Character.toLowerCase(c);
}
if (Character.isLowerCase(c)) {
originalString += Character.toUpperCase(c);
}
}
return originalString;
You are adding characters to the original string. Also, this means that your for loop will never get to the end of the iteration of the for loop, because originalString.length() changes each loop also. It's an infinite loop.
Instead, create a StringBuilder that stores the converted characters as you're iterating over the original string. The convert it to a String and return it at the end.
StringBuilder buf = new StringBuilder(originalString.length());
for (int i = 0; i < originalString.length(); i++) {
char c = originalString.charAt(i);
if (Character.isUpperCase(c)) {
buf.append(Character.toLowerCase(c));
}
else if (Character.isLowerCase(c)) {
buf.append(Character.toUpperCase(c));
}
// Account for case: neither upper nor lower
else {
buf.append(c);
}
}
return buf.toString();
Common-lang provide a swapCase function, see the doc. Sample from the doc:
StringUtils.swapCase(null) = null
StringUtils.swapCase("") = ""
StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
And if you really want to do it by yourself, you can check the source of common-lang StringUtils
Instead of using existing utilities, you may try below conversion using boolean operation:
To upper case:
char upperChar = (char) (c & 0x5f)
To lower case:
char lowerChar = (char) (c ^ 0x20)
In your program:
StringBuilder result = new StringBuilder(originalString.length());
for (int i = 0; i < originalString.length(); i++) {
char c = originalString.charAt(i);
if (Character.isUpperCase(c)) {
result.append((char) (c ^ 0x20));
}
else if ((c >= 'a') && (c <= 'z')) {
result.append((char) (c & 0x5f));
}
else {
result.append(c);
}
}
System.out.println(result);

Increase string value

Java question here:
If i have a string "a", how can I "add" value to the string, so I get a "b" and so on?
like "a++"
String str = "abcde";
System.out.println(getIncrementedString(str));
Output
bcdef
//this code will give next char in unicode sequence
public static String getIncrementedString(String str){
StringBuilder sb = new StringBuilder();
for(char c:str.toCharArray()){
sb.append(++c);
}
return sb.toString();
}
If you use the char primitive data type you can accomplish this:
char letter = 'a';
letter++;
System.out.println(letter);
prints out b
i made some changes to te paulo eberman code, to handle digits and characters, if valuable for someone i share this mod....
public final static char MIN_DIGIT = '0';
public final static char MAX_DIGIT = '9';
public final static char MIN_LETTER = 'A';
public final static char MAX_LETTER = 'Z';
public String incrementedAlpha(String original) {
StringBuilder buf = new StringBuilder(original);
//int index = buf.length() -1;
int i = buf.length() - 1;
//while(index >= 0) {
while (i >= 0) {
char c = buf.charAt(i);
c++;
// revisar si es numero
if ((c - 1) >= MIN_LETTER && (c - 1) <= MAX_LETTER) {
if (c > MAX_LETTER) { // overflow, carry one
buf.setCharAt(i, MIN_LETTER);
i--;
continue;
}
} else {
if (c > MAX_DIGIT) { // overflow, carry one
buf.setCharAt(i, MIN_DIGIT);
i--;
continue;
}
}
// revisar si es numero
buf.setCharAt(i, c);
return buf.toString();
}
// overflow at the first "digit", need to add one more digit
buf.insert(0, MIN_DIGIT);
return buf.toString();
}
i hope be usefull for someone.
use this code to increment char value by an integer
int a='a';
System.out.println("int: "+a);
a=a+3;
char c=(char)a;
System.out.println("char :"+c);
Convert the string to a char.
Increment the char.
Convert the char
back to a string.
Example:
//convert a single letter string to char
String a = "a";
char tmp = a.charAt(0);
//increment char
tmp++;
//convert char to string
String b = String.valueOf(tmp);
System.out.println(b);
Assuming you want something like aaab => aaac and not => bbbc, this would work:
public String incremented(String original) {
StringBuilder buf = new StringBuilder(original);
int index = buf.length() -1;
while(index >= 0) {
char c = buf.charAt(i);
c++;
buf.setCharAt(i, c);
if(c == 0) { // overflow, carry one
i--;
continue;
}
return buf.toString();
}
// overflow at the first "digit", need to add one more digit
buf.insert(0, '\1');
return buf.toString();
}
This treats all characters (in fact char values) the same, and fails (does strange stuff) for some unicode code-points outside the first plane (which occupy two char values in a String).
If you only want to use english lowercase letters as digits, you can try this variant:
public final static char MIN_DIGIT = 'a';
public final static char MAX_DIGIT = 'z';
public String incrementedAlpha(String original) {
StringBuilder buf = new StringBuilder(original);
int index = buf.length() -1;
while(index >= 0) {
char c = buf.charAt(i);
c++;
if(c > MAX_DIGIT) { // overflow, carry one
buf.setCharAt(i, MIN_DIGIT);
i--;
continue;
}
buf.setCharAt(i, c);
return buf.toString();
}
// overflow at the first "digit", need to add one more digit
buf.insert(0, MIN_DIGIT);
return buf.toString();
}
This does a => b => c, y => z => aa => ab.
if you want to do more calculation with the string, consider staying with StringBuilder (or StringBuffer for multithreaded access) instead of repeatedly copying between String and StringBuilder.
Or use a class made to do this, like BigInteger.

Categories