Replace letters but NOT special characters and capital letters in strings (Java) - java

I am able to replace lower case letters to next letter. Special Character and Upper Case letters shouldn't change but I can't figure out how.
/** Return s but with each occurrence of a letter in 'a'..'y'
* replaced by the next letter and 'z' replaced by 'a'
*
* Examples: nextChar("") = ""
* nextChar("abcz") = "bcda"
* nextChar("1a$b") = "1b$c"
* nextChar("AB") = "AB"
* nextChar("love") = "mpwf" */
public static String nextLetter(String s) {
// TODO 3
String next = "";
for (char x: s.toCharArray()) {
next += Character.toString((char)(((x - 'a' + 1) % 26) + 'a'));
}
return next;
}

Just use an if statement to check if the character is a lowercase letter and then promote it to the next letter. The Character type already has a Character.isLowerCase() to check if the character is a lowercase letter.
You can also do a range check like if ('a' <= character && character <= 'z') to check if the letter is lowercase.
When you determine the letter is lowercase, promote it to the next letter (Also check if the character passes 'z', and roll it back to 'a' if it does) and append it to the result. If it's not a lowercase letter, you just append it to the result.
public class MyClass {
public static void main(String args[]) {
System.out.println(nextLetter("abcz1a$bABlove"));
}
private static String nextLetter(String data) {
String result = "";
for (int i = 0; i < data.length(); i++) {
char character = data.charAt(i);
if (Character.isLowerCase(character)) {
character++;
// Account for rollover on 'z'
if (character == '{') {
character = 'a';
}
}
result += character;
}
return result;
}
}
Result
bcda1b$cABmpwf

You can use an if condition to check if a letter is lowercase.
Also, I've used Java 8 lambda function to iterate through characters in the string.
public static String nextLetter(String s) {
StringBuilder sb = new StringBuilder();
s.chars().forEach(c -> {
if (Character.isLowerCase(c)) {
sb.append((char) (((c - 'a' + 1) % 26) + 'a'));
} else {
sb.append((char)c);
}
});
return sb.toString();
}

Related

How to add chars to String value at specific intervals in Java

Ii am having trouble my below code I am building a project which requires the user to input "This is some \"really\" great. (Text)!?" which is then converted into THISISSOMEREALLYGREATTEXT and the value is passed into the next parameter. then in my Obify method I am attempting to add OB in front of every vowel AEIOUY but in my function it does not do this effectively, it prints out THISISSOMEREALLYGREATTEXT numerous times and with each new time it passes THISISSOMEREALLYGREATTEXT it adds in OB at the end when I need OB infront of every vowel instead of just at the end. please do show me where I am going wrong so I can continue to progress. once again thank you in advance and the code under review is below.
import java.util.*;
public class Main {
public static void main(String[] args) {
normalizeText();
obify("THISISSOMEREALLYGREATTEXT" );
}
// Part 1 Normalized Method to convert all letter to uppercase and removing all special characters and placing it into String codey.
public static String normalizeText (){
Scanner sc = new Scanner( System.in );
String normText;
System.out.println("Please input text to encrypt");
normText = sc.nextLine();
System.out.println(normText.replaceAll(" ","").replaceAll("[^a-zA-Z ]", "").toUpperCase());
return normText;
}
//This method will take in the Normalized text and insert a capital O and B in-front of every vowel and return the text
private static String obify (String input) {
String obifiledInput = input;
for (int i = 0; i < input.length(); i++) {
if (input.contains( Character.toString( input.charAt( i ) ) )) {
obifiledInput = obifiledInput + "OB" + Character.toString( input.charAt( i ) );
} else {
obifiledInput = obifiledInput + Character.toString( input.charAt( i ) );
}
System.out.println(obifiledInput);
}
return obifiledInput;
}
}
Looking at your obify function, I don't quite see where it is that you are checking if the Character is a vowel. What the following code:
if (input.contains( Character.toString( input.charAt( i ) ) ))
is doing is checking if input contains a character at a certain position in input. That doesn't quite solve your problem of checking if the letter is a vowel. Additionally, you are setting obifiledInput to input directly without first going through and adding the OB when required. To fix these problems, you can try my code below:
private static String obify (String input) {
String obifiledInput = "";
for (int i = 0; i < input.length(); i++) {
char temp = input.charAt(i);
if (char == 'A' || char == 'E' || char == 'I' || char == 'O' || char == 'U') {
obifiledInput += "OB" + temp;
} else {
obifiledInput += "" + temp;
}
}
return obifiledInput;
}
I think that you should find that this works. It checks if the character is a vowel, ["A", "E", "I", "O", "U"]. Then, it adds "OB" and the character to obifiledInput. Otherwise, it just adds the Character. Finally, it returns the String that has been "obified".
Just match input.charAt(i) with all the vowels it should do fine. Also there is a small mistake in your code, you have initialized oblifiedInput with input and then you are adding OB to that string. Even if your for loop was correct it still would have not resulted in the required output.
private static String obify (String input) {
String obifiledInput = "";
char c;
for (int i = 0; i < input.length(); i++) {
c=input.charAt(i);
if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u') {
obifiledInput +="OB";
}
obifiledInput +=c;
}
System.out.println(obifiledInput);
return obifiledInput;
}
Wouldn't it be easier to use an array of char, pass said array into a for each structure, and then use the replaceAll​(String regex, String replacement) method on your String?
Plus, there is the risk of having the 'O' of "OB" being considered as another vowel of the code; so 'O' will have to be the first vowel to be checked.
It would give something around the line of:
String obifiledInput = input;
ArrayList<Character> vowels = { 'O', 'A', 'E', 'I', 'U', 'Y' };
for (char curr_char : vowels) {
obifiledInput.remplaceAll( "[" + curr_char + "]", "OB" + curr_char)
System.out.println(obifiledInput);
}
return obifiledInput;

Is it more efficient to use arrays or character?

is this the most efficient method to determine that there is a minimum of two unique characters in a String? Should I have used arrays to hold the characters? Thank you
public static Boolean checkPW(String pw) {
Boolean validLower = false, validUpper = false, validNumber = false;
char lowerCompare = '0', upperCompare = '0', numberCompare = 'a';
for(int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if(character >= 'a' && character <= 'z') {
if(lowerCompare == '0')
lowerCompare = character;
else if(lowerCompare != character)
validLower = true;
} // lower-case if END
} // for-loop END
if(validLower)
return true;
else
return false;
} // checkPW END
If I had to do this in Java, in production, I might just use a set here:
String input = "abcdefgzz";
char[] letters = input.toCharArray();
Set<Character> set = new HashSet<>();
boolean valid = false;
for (char letter : letters) {
set.add(letter);
if (set.size() > 1) {
valid = true;
break;
}
}
if (valid) {
System.out.println("Minimum of two unique letters");
}
else {
System.out.println("Only one unique letter");
}
is this the most efficient method to determine that there is a minimum of two unique characters in a String?
No. The loop continues to run after 2 unique valid characters are found, which is unnecessary. It could stop immediately, and then it will be more efficient. Consider for example the string "ab" followed by a million characters. There's no need to go further than the first two.
Should I have used arrays to hold the characters?
The question is not clear. To make it meaningful, you would need to include reasoning for the benefits of both methods. And it's not clear what technique you're referring to.
It would be good to remove all the unnecessary variables from the program.
After fixing the inefficiency, and a bit of cleanup:
public static boolean checkPW(String pw) {
char first = '0';
for (int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if ('a' <= character && character <= 'z') {
if (first == '0') {
first = character;
} else if (first != character)
return true;
}
}
}
return false;
}
I'd do this:
public static boolean checkPW(String pw) {
Character lowerCompare = null;
for (int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if(Character.isLowerCase(c)) { // this handles non-ASCII lower case characters
if(lowerCompare == null) {
lowerCompare = character;
} else if(lowerCompare != character) {
return true;
}
}
}
return false;
}

Java: Remove non alphabet character from a String without regex

Is there a way to remove all non alphabet character from a String without regex?
I'm trying to check if the String is a palindrome
This is what i tried so far.
public static boolean isPalindrome( String text )
{
int textLength = text.length() - 1;
String reformattedText = text.trim().toLowerCase();
for( int i = 0; i <= textLength; i++ )
{
if( reformattedText.charAt( i ) != reformattedText.charAt( textLength - i ) )
{
return false;
}
}
return true;
}
But if the input is:
System.out.println( isPalindrome( "Are we not pure? No sir! Panama’s moody"
+ "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) );
It should be true.
I'm really having a hard time thinking of how to remove or ignore those non alphabet characters on the String.
I would do something like this:
public static String justAlphaChars(String text) {
StringBuilder builder = new StringBuilder();
for (char ch : text.toCharArray())
if (Character.isAlphabetic(ch))
builder.append(ch);
return builder.toString();
}
Just tested method above in your example bellow and worked. Returned true.
System.out.println( isPalindrome( justAlphaChars ( "Are we not pure? No sir! Panama’s moody"
+ "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) ) );
OOPS. Java, not Python.
You can still use list-like access in Java, just a bit more work.
char[] letters = text.toCharArray();
int nletters = 0;
for (int i=0; i<letters.length; ++i) {
if (Character.isLetter(letters[i])
letters[nletters++] = Character.toUpperCase(letters[i]);
}
// print out letters in array:
System.out.print("letters only: ");
for (int i=0; i<nletters; ++i) {
System.out.print(letters[i]);
}
System.out.println();
Now use the first nletters positions only in the letters array, since those positions will hold the lowercased letters from the input. An example that just displays the remaining characters is included above.
Now write a loop to compare letters[0] with letters[nletters-1], letters[1] with letters[nletters-2], and so on. If all pairs are equal, you have a palindrome.
String removeNonAlpha(final String word) {
final StringBuilder result = new StringBuilder();
for (final char ch : word.toCharArray()) {
final int ascii = ch;
if (((ascii >= 65) && (ascii <= 90)) || ((ascii >= 97) && (ascii <= 122))) {
result.append(ch);
}
}
return result.toString();
}
Explanation:
The method will retrieve a string containing only A-Z and a-z characters.
I am simply verifying the ascii code for the given char.
Please refer to the ASCII code table

Add separator in string using regex in Java

I have a string (for example: "foo12"), and I want to add a delimiting character in between the letters and numbers (e.g. "foo|12"). However, I can't seem to figure out what the appropriate code is for doing this in Java. Should I use a regex + replace or do I need to use a matcher?
A regex replace would be just fine:
String result = subject.replaceAll("(?<=\\p{L})(?=\\p{N})", "|");
This looks for a position right after a letter and right before a digit (by using lookaround assertions). If you only want to look for ASCII letters/digits, use
String result = subject.replaceAll("(?i)(?<=[a-z])(?=[0-9])", "|");
Split letters and numbers and concatenate with "|". Here is a one-liner:
String x = "foo12";
String result = x.replaceAll("[0-9]", "") + "|" + x.replaceAll("[a-zA-Z]", "");
Printing result will output: foo|12
Why even use regex? This isn't too hard to implement on your own:
public static String addDelimiter(String str, char delimiter) {
StringBuilder string = new StringBuilder(str);
boolean isLetter = false;
boolean isNumber = false;
for (int index = 0; index < string.length(); index++) {
isNumber = isNumber(string.charAt(index));
if (isLetter && isNumber) {
//the last char was a letter, and now we have a number
//so here we adjust the stringbuilder
string.insert(index, delimiter);
index++; //We just inserted the delimiter, get past the delimiter
}
isLetter = isLetter(string.charAt(index));
}
return string.toString();
}
public static boolean isLetter(char c) {
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z';
}
public static boolean isNumber(char c) {
return '0' <= c && c <= '9';
}
The advantage of this over regex is that regex can easily be slower. Additionally, it is easy to change the isLetter and isNumber methods to allow for inserting the delimiter in different places.

Search for Capital Letter in String

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

Categories