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;
}
}
Related
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;
}
}
}
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();
}
I'm trying to convert a sentence to pig latin but can't seem to get the correct output to work. For example the input
the rain in spain stays mainly in the plain yields an output of ethay ethay ethay with my current code whereas the expected output is ethay ainray inay ainspay aysstay ainlymay inay ethay ainplay
For those unfamiliar, the basic rules of pig latin are:
If the word begins with a consonant, take the beginning consonants up until the first vowel and move them to the end of the word. Then append ay at the very end. (so cricket would become icketcray)
If the word begins with a vowel, simply add ay to the end. (apple would become appleay)
If y is the first letter in the word, treat it as a consonant, otherwise it is used as a vowel. (young would become oungyay and system would become ystemsay)
My code is as follows:
import java.util.Scanner;
public class PigLatin{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String line = scan.next();
String piglatin = translateSentence(line);
System.out.println(piglatin);
}
public static String translateSentence(String line){
for (int i =0; i < line.length(); i++ ) {
char c = line.charAt(i);
//for loop to analyze each word
if (Character.isAlphabetic(c)) {
//if (i <='a' || i<='A' || i>='z' || i>='Z'){
String piglatin = translateword(line);
return piglatin;
}
}
return line;
}
public static String translateword(String line) {
Scanner scan = new Scanner(System.in);
int position = firstVowel(line);
String words = "";
String output = "";
for(int i = 0; i<line.length();i++){
words = "";
if (firstVowel(line) == 0) {
words = line + "-way";
} else if (firstVowel(line) == -1) {
words = line + "";
} else {
String first = line.substring(position);
String second = line.substring(0,position) + "ay";
words = first + second;
}
output = output + " " + words;
//words = "";
}
return output;
}
public static int firstVowel(String line) {
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == 'a' || line.charAt(i) == 'e'
|| line.charAt(i) == 'i' || line.charAt(i) == 'o'
|| line.charAt(i) == 'u') {
return i;
}
}
return -1;
}
}
Any help is greatly appreciated, thank you.
first write a separate function to get list of words from line
public String[] getWords(String line) {
String list[]=new String[100];
int j=0;
int end;
end=line.indexOf(' ');
while (end!=-1) {
list[j]=line.substring(0, end);
line=line.substring(end+1,line.length());
j++;
end=line.indexOf(' ');
}
list[j]=line.substring(0,line.length());
return list;
}
then modify your translate line to call translate word multiple times, each time pass a single word.
Assuming your translateWord() returns a single correctly translated word. translateLine change in the following way:
if (Character.isAlphabetic(c)) {
String wordList[]=getWords(line);
String piglatin="";
int i=0;
while(!line[i].equals("")) {
piglatin = piglatin+translateword(word[i]);
i++;
}
return piglatin;
}
I'm writing a program that has two rules:
1. If the first character of the word is a vowel, then move it to the end of the word.
2. If the first character of the word is a consonant, then move it to the end of the word and append 'ae'.
import java.util.Scanner;
public class Program5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
System.out.print("Please enter a sentence: ");
String english = scanner.nextLine();
String piggy = piggyEnglish(english);
System.out.print("Translated: " + piggy);
}
private static String piggyEnglish(String s) {
String piggy = "";
int i = 0;
while (i<s.length()) {
while (i<s.length() && !isLetter(s.charAt(i))) {
piggy = piggy + s.charAt(i);
i++;
}
if (i>=s.length()) break;
int begin = i;
while (i<s.length() && isLetter(s.charAt(i))) {
i++;
}
int end = i;
piggy = piggy + piggyWord(s.substring(begin, end));
}
return piggy;
}
private static boolean beginsWithVowel(String word){
String vowels = "aeiou";
char letter = word.charAt(0);
return (vowels.indexOf(letter) != -1);
}
private static boolean isLetter(char c) {
return ( (c >='A' && c <='Z') || (c >='a' && c <='z') );
}
private static String piggyWord(String word) {
int split = firstVowel(word);
if(beginsWithVowel(word)) {
return word.substring(split) + word.substring(0, split);
} else {
return word.substring(split) + word.substring(0, split)+"ae";
}
}
private static int firstVowel(String word) {
word = word.toLowerCase();
for (int i=0; i<word.length(); i++)
if (word.charAt(i)=='a' || word.charAt(i)=='e' ||
word.charAt(i)=='i' || word.charAt(i)=='o' ||
word.charAt(i)=='u')
return i;
return 0;
}
}
The following is the expected output:
Please enter a sentence: today is a beautiful day
Translated: odaytae si a eautifulbae aydae
However, this is what I'm getting:
Please enter a sentence: today is a beautiful day
Translated: odaytae is a eautifulbae aydae
Basically, it doesn't translate any words that start with a vowel. I think the problem stems from the piggyWord method, but I'm not certain. Can I get any pointers on how to fix this?
The error lies in the piggyWord function:
private static String piggyWord(String word) {
int split = firstVowel(word);
if(beginsWithVowel(word)) {
return word.substring(split + 1) + word.substring(0, split + 1); //Since vowel is in 1st place, substring(0,0) returns empty string.
} else {
return word.substring(split) + word.substring(0, split)+"ae";
}
}
Based on your rules, you don't need the method firstVowel() to get the index of the first vow in a word because you only need to know whether the first character in the word is a vow or not.
So simply change you piggyWord method to the following will solve your problem:
private static String piggyWord(String word) {
if(beginsWithVowel(word)) {
return word.substring(1) + word.substring(0, 1);
} else {
return word.substring(1) + word.substring(0, 1)+"ae";
}
}
Or more simply:
private static String piggyWord(String word) {
String result = word.substring(1) + word.substring(0, 1);
return beginsWithVowel(word) ? result : result + "ae";
}
Because you always have to move the first character of a word to the end, the only thing is that whether you need to append an extra "ae" in the end or not.
If only the first letter is concerned than in "firstVowel" you can return 1 if vowel is at first position.
private static int firstVowel(String word) {
word = word.toLowerCase();
for (int i=0; i<word.length(); i++)
if (word.charAt(i)=='a' || word.charAt(i)=='e' ||
word.charAt(i)=='i' || word.charAt(i)=='o' ||
word.charAt(i)=='u')
return 1;
return 0;
}
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