replace characters according to positions in an loop - java

I'm busy with an hangman application, and I've come to the point where I now have to display the secret word... Now I'm thinking of creating two Strings the original that retrieves an random word from a text file and the secret word that hides... Problem is I don't know how to hide an word in '-'
So i've created the following two strings
String original = readWord();
String secret = new String(new char[original.length()]).replace('\0', '-');
Now my idea is to find the position of the char in the original string and then replace the '-' with that char in the secret String
Now the problem is when my original word is for example "elephant", so I found an loop that finds the position of the char searched
String s = "elephant";
int pos = s.indexOf('e');
while (pos > -1) {
System.out.println(pos);
pos = s.indexOf('e', pos + 1);
now this loop returns
0
2
My Question is how do I use this loop to replace the '-' in the secret string whether there is more than 1 position returned?

Because String is immutable, you could use StringBuilder to build a new string:
StringBuilder builder = new StringBuilder(secret);
for (int i = 0; i < original.length(); i++) {
if (original.charAt(i) == guessLetter) {
builder.setCharAt(i, guessLetter);
}
}
secret = builder.toString();
You would use builder.toString() as your masked word until you picked a new word. When you get a new word you would reset the masked word to '-------' etc.

you can use
String Str = new String("Welcome to Tutorialspoint.com");
// all occurrence of 'o' is replaced with 'T'
System.out.println(Str.replace('o', 'T'));

Related

How to find the last word in a string

I'm trying to create a method that returns the last word in a string but I am having some trouble writing it.
I am trying to do it by finding the last blank space in the string and using a substring to find the word. This is what I have so far:
String strSpace=" ";
int Temp; //the index of the last space
for(int i=str.length()-1; i>0; i--){
if(strSpace.indexOf(str.charAt(i))>=0){
//some code in between that I not sure how to write
}
}
}
I am just beginning in Java so I don't know many of the complicated parts of the language. It would be much appreciated if someone could help me find a simple way to solve this problem. Thanks!
You can do this:
String[] words = originalStr.split(" "); // uses an array
String lastWord = words[words.length - 1];
and you've got your last word.
You are splitting the original string at every space and storing the substrings in an array using the String#split method.
Once you have the array, you are retrieving the last element by taking the value at the last array index (found by taking array length and subtracting 1, since array indices begin at 0).
String str = "Code Wines";
String lastWord = str.substring(str.lastIndexOf(" ")+1);
System.out.print(lastWord);
Output:
Wines
String#lastIndexOf and String#substring are your friends here.
chars in Java can be directly converted to ints, which we'll use to find the last space. Then we'll simply substring from there.
String phrase = "The last word of this sentence is stackoverflow";
System.out.println(phrase.substring(phrase.lastIndexOf(' ')));
This prints the space character itself too. To get rid of that, we just increment the index at which we substring by one.
String phrase = "The last word of this sentence is stackoverflow";
System.out.println(phrase.substring(1 + phrase.lastIndexOf(' ')));
If you don't want to use String#lastIndexOf, you can loop through the string and substring it at every space until you don't have any left.
String phrase = "The last word of this sentence is stackoverflow";
String subPhrase = phrase;
while(true) {
String temp = subPhrase.substring(1 + subPhrase.indexOf(" "));
if(temp.equals(subPhrase)) {
break;
} else {
subPhrase = temp;
}
}
System.out.println(subPhrase);
You can use: (if you are not familiar with arrays or unusual methods)
public static String lastWord(String a) // only use static if it's in the
main class
{
String lastWord = "";
// below is a new String which is the String without spaces at the ends
String x = a.trim();
for (int i=0; i< x.length(); i++)
{
if (x.charAt(i)==' ')
lastWord = x.substring(i);
}
return lastWord;
}
you just need to traverse the input string from tail when first find blank char stop traverse work and return the word.a simple code like this:
public static String lastWord(String inputs) {
boolean beforWords = false;
StringBuilder sb = new StringBuilder();
for (int i = inputs.length() - 1; i >= 0; i--) {
if (inputs.charAt(i) != ' ') {
sb.append(inputs.charAt(i));
beforWords = true;
} else if (beforWords){
break;
}
}
return sb.reverse().toString();
}
You could try:
System.out.println("Last word of the sentence is : " + string.substring (string.lastIndexOf (' '), string.length()));

Replacing the letters of a String with blank if they are found in another

I am working on an assignment and this part is tripping me up.
Construct cipher1 by first filling in the matrix with the unique letters from the first key.
For example, if the key is “testkey”, then fill in the key with the letters T, E, S, K, Y.
Do not fill in repeated characters from the key. Then fill the matrix with the remaining characters of the alphabet (again, skipping Q).
Do not repeat any characters that appeared in the key. So, for “testkey”, cipher1 looks like this: "
The cypher is a 5 by 5 array usually filled with the letters of the alphabet minus 'q'.
So if my key is testkey, the cipher will now be filled with "TESKYABCDFGHIJLMNOPRUVWXZ" instead of "ABCDEFGHIJKLMNOPRSTUVWXYZ".
I thought something like this would work but it doesn't.
for (int i = 0; i < key.length(); i++)
{
key.toCharArray();
alphabet.replace(key[i], "");
}
The key variable being a string "TESTKEY" and the alphabet variable also being a string containing "ABCDEFGHIJKLMNOPRSTUVWXYZ".
Looking at it now that code is obviously flawed and now I'm just stuck. Please any one give the suggestion to me
Try this :
public static void main(String[] args) {
String testS = "testkey";
String key = "ABCDEFGHIJKLMNOPRSTUVWXYZ";
testS = testS.toUpperCase() + key;
testS = removeDuplicates(testS);
System.out.println(testS);
}
static String removeDuplicates(String string) {
StringBuilder noDuplicateChars = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
String letter = string.substring(i, i + 1);
if (noDuplicateChars.indexOf(letter) == -1) {
noDuplicateChars.append(letter);
}
}
return noDuplicateChars.toString();
}
If from some reason you don't want to use StringBuilder, you can change the implementation of removeDuplicates to :
static String removeDuplicates(String string) {
String noDuplicates = new String("");
for (int i = 0; i < string.length(); i++) {
if (!noDuplicates.contains("" + string.charAt(i))) {
noDuplicates += "" + string.charAt(i);
}
}
return noDuplicates;
}
You can use LinkedHashSet. In for loop add key characters and in second loop add alphabet characters. Then iterate through set elements and build string.
Note that method add do not place element if it already exist in the set, hence no additional checks are needed.
You just need to use regular expression;
example: 1 - key
input: testkey
code: `String newString = input.replaceAll("(.)\\1{1,}", "$1").toUpperCase();`
output: TESKY
Example 2; Concat newString with the alphapatical string
input: testkey + "ABCDEFGHIJKLMNOPRSTUVWXYZ";
code: `String FinalString = input.replaceAll("(.)\\1{1,}", "$1").toUpperCase();`
output: TESKYABCDFGHIJLMNOPRUVWXZ

How to check if a string contains all the letters of the alphabet? [duplicate]

This question already has answers here:
Check if string has all the letters of the alphabet
(15 answers)
Closed 6 years ago.
I am trying to check if a string contains all the letters of the alphabet. I created an ArrayList which contains the whole alphabet. I converted the string to char array and I'm iterating through the character array, and for every character present in the ArrayList I'm removing an element from it. And in the end, I'm trying to check if the Arraylist is empty to see if all elements have been removed. That would indicate the string contains all the letters of the alphabet.
Unfortunately, the code is throwing IndexOutOfBoundsException error inside the if condition where I'm removing elements from the arraylist
List<Character> alphabets = new ArrayList<Character>();
alphabets.add('a');
alphabets.add('b');
alphabets.add('c');
alphabets.add('d');
alphabets.add('e');
alphabets.add('f');
alphabets.add('g');
alphabets.add('h');
alphabets.add('i');
alphabets.add('j');
alphabets.add('k');
alphabets.add('l');
alphabets.add('m');
alphabets.add('n');
alphabets.add('o');
alphabets.add('p');
alphabets.add('q');
alphabets.add('r');
alphabets.add('s');
alphabets.add('t');
alphabets.add('u');
alphabets.add('v');
alphabets.add('w');
alphabets.add('x');
alphabets.add('y');
alphabets.add('z');
// This is the string- I've just put a random example
String str = "a dog is running crazily on the ground who doesn't care about the world";
//Remove all the spaces
str = str.replace(" ", "");
// Convert the string to character array
char[] strChar = str.toCharArray();
for (int i = 0; i < strChar.length; i++) {
char inp = strChar[i];
if (alphabets.contains(inp)) {
alphabets.remove(inp);
}
}
if (alphabets.isEmpty())
System.out.println("String contains all alphabets");
else
System.out.println("String DOESN'T contains all alphabets");
All these solutions seem to do a lot of work for a relatively simple check, especially given Java 8's stream API:
/* Your lowercase string */.chars()
.filter(i -> i >= 'a' && i <= 'z')
.distinct().count() == 26;
Edit: For speed
If you want to end the string iteration as soon as the entire alphabet is found while still using streams, then you can keep track with a HashSet internally:
Set<Integer> chars = new HashSet<>();
String s = /* Your lowercase string */;
s.length() > 25 && s.chars()
.filter(i -> i >= 'a' && i <= 'z') //only alphabet
.filter(chars::add) //add to our tracking set if we reach this point
.filter(i -> chars.size() == 26) //filter the 26th letter found
.findAny().isPresent(); //if the 26th is found, return
This way, the stream will cease as soon as the Set is filled with the 26 required characters.
There are some (even still) more efficient solutions in terms of performance below, but as a personal note I will say to not bog yourself in premature optimization too much, where you could have readability and less effort in writing the actual code.
List.remove removes by index. Since a char can be cast to an int you are effectively removing index values that do not exist, ie char 'a' is equal to int 97. As you can see your list does not have 97 entries.
You can do alphabet.remove(alphabets.indexOf(inp));
As pointed out by #Scary Wombat(https://stackoverflow.com/a/39263836/1226744) and #Kevin Esche (https://stackoverflow.com/a/39263917/1226744), there are better alternative to your algorithm
O(n) solution
static Set<Integer> alphabet = new HashSet<>(26);
public static void main(String[] args) {
int cnt = 0;
String str = "a dog is running crazily on the ground who doesn't care about the world";
for (char c : str.toCharArray()) {
int n = c - 'a';
if (n >= 0 && n < 26) {
if (alphabet.add(n)) {
cnt += 1;
if (cnt == 26) {
System.out.println("found all letters");
break;
}
}
}
}
}
Adding to #Leon answer, creating a List and removing from it seems quite unnecessary. You could simply loop over 'a' - 'z' and do a check with each char. Additionally you are looping over the whole String to find out, if each letter is present. But the better version would be to loop over each letter itself. This can potentionally safe you a few iterations.
In the end a simple example could look like this:
// This is the string- I've just put a random example
String str = "a dog is running crazily on the ground who doesn't care about the world";
str = str.toLowerCase();
boolean success = true;
for(char c = 'a';c <= 'z'; ++c) {
if(!str.contains(String.valueOf(c))) {
success = false;
break;
}
}
if (success)
System.out.println("String contains all alphabets");
else
System.out.println("String DOESN'T contains all alphabets");
Regex is your friend. No need to use a List here.
public static void main(String[] args) {
String s = "a dog is running crazily on the ground who doesn't care about the world";
s = s.replaceAll("[^a-zA-Z]", ""); // replace everything that is not between A-Za-z
s = s.toLowerCase();
s = s.replaceAll("(.)(?=.*\\1)", ""); // replace duplicate characters.
System.out.println(s);
System.out.println(s.length()); // 18 : So, Nope
s = "a dog is running crazily on the ground who doesn't care about the world qwertyuioplkjhgfdsazxcvbnm";
s = s.replaceAll("[^a-zA-Z]", "");
s = s.toLowerCase();
s = s.replaceAll("(.)(?=.*\\1)", "");
System.out.println(s);
System.out.println(s.length()); //26 (check last part added to String) So, Yes
}
Another answer has already pointed out the reason for exception. You have misused List.remove(), as it implicitly convert char to int which it called the List.remove(int) which remove by index.
The way to solve is actually easy. You can make it call the List.remove(Object) by
alphabets.remove((Character) inp);
Some other improvements:
You should use Set instead of List in this case.
You can even use a boolean[26] to keep track of whether an alphabet has appeared
You do not need to convert your string to char array. Simply do a str.charAt(index) will give you the character at certain position.
One integer variable is enough to store this information. You can do it like this
public static boolean check(String input) {
int result = 0;
input = input.toLowerCase();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= 'a' && c <= 'z') {
result |= 1 << (input.charAt(i) - 'a');
}
}
return result == 0x3ffffff;
}
Each bit corresponds to a letter in English alphabet. So if your string contains all letters the result will be of form 00000011111111111111111111111111
How about creating
List<String> alphabets = new ArrayList <String> ();
and add values as strings
then
for (String val : alphabets) { // if str is long this will be more effecient
if (str.contains (val) == false) {
System.out.println ("FAIL");
break;
}
}
You can get rid of the exception, by changing this line in your code
char inp = strChar[i];
to
Character inp = strChar[i];
Refer https://docs.oracle.com/javase/7/docs/api/java/util/List.html#remove(java.lang.Object)
List.remove('char') is treated as List.remove('int'), which is why you are getting indexOutOfBoundsException, because it is checking the ASCII value of 'a' which is 97. Converting variable 'inp' to Character would call List.remove('Object') api.
And if you like Java 8 streams like me:
final List<String> alphabets = new ArrayList<>();
And after filling alphabets with a-z:
final String str = "a dog is running crazily on the ground who doesn't care about the world";
final String strAsLowercaseAndWithoutOtherChars = str.toLowerCase()
.replaceAll("[^a-z]", "");
final boolean anyCharNotFound = alphabets.parallelStream()
.anyMatch(t -> !strAsLowercaseAndWithoutOtherChars.contains(t));
if (anyCharNotFound) {
System.out.println("String DOESN'T contains all alphabets");
} else {
System.out.println("String contains all alphabets");
}
This converts the string to lower case (skip if you really are only looking for the small letters), removes all characters from the string which are not small letters and then checks for all members of your alphabets if they are contained in the string by using a parallel stream.
Here's another naive solution that uses String.split("") to split every character into a String[] array, then Arrays.asList() to convert that to a List<String>. You can then call yourStringAsList.containsAll(alphabet) to determine whether your String contains the alphabet:
String yourString = "the quick brown fox jumps over the lazy dog";
List<String> alphabet = Arrays.asList("abcdefghijklmnopqrstuvwxyz".split(""));
List<String> yourStringAsList = Arrays.asList(yourString.split(""));
boolean containsAllLetters = yourStringAsList.containsAll(alphabet);
System.out.println(containsAllLetters);
This approach might not be the fastest, but I think the code is a littler easier to understand than the solutions proposing loops and streams and whatnot.
Just do something like
sentence.split().uniq().sort() == range('a', 'z')
For Java 8, it could be written like:
boolean check(final String input) {
final String lower = input.toLowerCase();
return IntStream.range('a', 'z'+1).allMatch(a -> lower.indexOf(a) >= 0);
}
Convert the string to lower case or capitals. Then loop thru the equivalent ascii decimal values for A-Z or a-z and return false if not found in character array. You will have to cast the int to char.
I've thought about playing with the ASCII codes of the characters.
String toCheck = yourString.toLowerCase();
int[] arr = new int[26];
for(int i = 0; i < toCheck.length(); i++) {
int c = ((int) toCheck.charAt(i)) - 97;
if(c >= 0 && c < 26)
arr[c] = arr[c] + 1;
}
After running the loop you eventually get an array of counters, each representing a letter of alphabet (index) and it's occurrence in the string.
boolean containsAlph = true;
for(int i = 0; i < 26; i++)
if(arr[i] == 0) {
containsAlph = false;
break;
}
Character inp = strChar[i];
Use this instead of char, List remove method have 2 overloaded methods , one with object and one with int .If you pass char its been treated as the int one.

Java, split string by punctuation sign, process string, add punctuation signs back to string

I have string like this:
Some text, with punctuation sign!
I am splitting it by punctuation signs, using str.split("regex"). Then I process each element (switch characters) in the received array, after splitting.
And I want to add all punctuation signs back to their places. So result should be like this:
Smoe txet, wtih pinctuatuon sgin!
What is the best approach to do that?
How about doing the whole thing in one tiny line?
str = str.replaceAll("(?<=\\b\\w)(.)(.)", "$2$1");
Some test code:
String str = "Some text, with punctuation sign!";
System.out.println(str.replaceAll("(?<=\\b\\w)(.)(.)", "$2$1"));
Output:
Smoe txet, wtih pnuctuation sgin!
Since you aren't adding or removing characters, you may as well just use String.toCharArray():
char[] cs = str.toCharArray();
for (int i = 0; i < cs.length; ) {
while (i < cs.length() && !Character.isLetter(cs[i])) ++i;
int start = i;
while (i < cs.length() && Character.isLetter(cs[i])) ++i;
process(cs, start, i);
}
String result = new String(cs);
where process(char[], int startInclusive, int endExclusive) is a method which jumbles the letters in the array between the indexes.
I'd read through the string character by character.
If the character is punctuation append it to a StringBuilder
If the character is not punctuation keep reading characters until you reach a punctuation character, then process that word and append it to the StringBuilder.
Then skip to that next punctuation character.
This prints, rather than appends to a StringBuilder, but you get the idea:
String sentence = "This is a test, message!";
for (int i = 0; i<sentence.length(); i++) {
if (Character.isLetter(sentence.charAt(i))) {
String tmp = "" +sentence.charAt(i);
while (Character.isLetter(sentence.charAt(i+1)) && i<sentence.length()) {
i++;
tmp += sentence.charAt(i);
}
System.out.print(switchChars(tmp));
} else {
System.out.print(sentence.charAt(i));
}
}
System.out.println();
You can use:
String[] parts = str.split(",");
// processing parts
String str2 = String.join(",", parts);

Java - Get first letter of string

I am trying to extract the first letters of each word in a sentence the user has spoken into my app. Currently if the user speaks "Hello World 2015" it inserts that into the text field. I wish to split this so if the user speaks "Hello World 2015" only "HW2015" is inserted into the text field.
final ArrayList<String> matches = data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS);
The matches variable is storing the users input in an array.I have looked into using split but not sure exactly how this works.
How would I achieve this?
Thank You
pass this regex and your list into applyRegexToList
it reads:
(get first character) or (any continuous number) or (any character after a space)
(^.{0,1})|(\\d+)|((?<=\\s)[a-zA-z])
()
public static ArrayList<String> applyRegexToList(ArrayList<String> yourList, String regex){
ArrayList<String> matches = new ArrayList<String>();
// Create a Pattern object
Pattern r = Pattern.compile(regex);
for (String sentence:yourList) {
// Now create matcher object.
Matcher m = r.matcher(sentence);
String temp = "";
//while patterns are still being found, concat
while(m.find())
{
temp += m.group(0);
}
matches.add(temp);
}
return matches;
}
You can split a string into an array of string by doing this:
String[] result = my_string.split("\\s+"); // This is a regex for matching spaces
You could then loop over your array, taking the first character of each string:
// The string we'll create
String abbrev = "";
// Loop over the results from the string splitting
for (int i = 0; i < result.length; i++){
// Grab the first character of this entry
char c = result[i].charAt(0);
// If its a number, add the whole number
if (c >= '0' && c <= '9'){
abbrev += result[i];
}
// If its not a number, just append the character
else{
abbrev += c;
}
}

Categories