I'm relatively new to coding and my teacher asked us to make a code for a hangman game. He told us that we must accomplish this without the use of Arrays. My question is along the lines of this: If I have a String that is declared by the user and then a correct letter is guessed, how would I specifically be able to replace a substituted underscore with the guessed letter?
For example...
input is "cats"
system types "_ _ _ _"
say I typed the letter "a" and I want the output to be:
"_ a _ _"
How would I get the placement number of that letter and then manipulate the underscore to make it the letter?
StringBuilder.charAt()
StringBuilder.setCharAt()
You may want to have a look at these methods.
For the purpose of printing, you may want StringBuilder.toString().
You could use substrings. Something like this.
String original = "apple";
String guessed = original;
String withUnderscores = "_____";
String guess = "a";
while (guessed.contains(guess))
{
int index = guessed.indexOf(guess);
withUnderscores = withUnderscores.substring(0, index) + guess + withUnderscores.substring(index + 1);
guessed = guessed.substring(0, index) + "." + guessed.substring(index + 1);
}
System.out.println(original);
System.out.println(guessed);
Use one variable to store the underscore string. (ie "____"
Use another variable to store the answer string. (ie "cats").
Get the users input and and loop through the string taking the character at each index. If any variable matches the input letter (string1.equals(string2)) replace the character in the underscore string at whatever index your loop is at.
Use charAt() to get the character at a place in a string.
You can do this with a String or the StringBuilder class. If you haven't learned about StringBuilder in your classes, you probably shouldn't use it for your assignment.
Try something like this (I would prefer to have the guesses on a Set, it would be more clear than using a string to hold them):
public String maskUnguessedLetters(String answer, String guessed) {
Char MASKED = '_';
StringBuilder sb = new StringBuilder();
for (Char c : answer.toCharArray()) {
sb.append(guessed.contains(c.toString())
? c
: MASKED);
}
return sb.toString();
}
I don't completely understand the question, but I think this might help.
final String trueWord="cats";
String guessWord="____";
String input="a";
//if the input matches
if(trueWord.contains(input)){
//last Index of input in trueWord
int lastEntry=-1;
//hold all indices of input character in trueWord
ArrayList<Integer> indices=new ArrayList<>();
while(trueWord.indexOf(input,lastEntry+1) >= 0){
lastEntry=trueWord.indexOf(input);
indices.add(lastEntry);
}
//now replace the characters at the indices
StringBuilder newGuessWord = new StringBuilder(guessWord);
for(int index:indices){
//replace one character at a time.
newGuessWord.setCharAt(index, input.charAt(0));
}
//the new word
guessWord=newGuessWord.toString();
}
This is the not the most optimised code but will definitely give you an idea of how your task can be done.
public static void main(String[] args) {
final String word = "cats";
Scanner scanner = new Scanner(System.in);
System.out.println("Guess the character");
String finalString = "";
char letter = scanner.next().charAt(0);
for (char s : word.toCharArray()) {
if (s == letter) {
finalString += s;
} else
finalString += "_";
}
System.out.println(finalString);
scanner.close();
}
Related
String str="b5l*a+i";//trying to replace the characters by user input (integer)
StringBuffer sb=new StringBuffer(str);
for(int i=0;i<sb.length();i++)
{
for(int j='a';j<='z';j++)
{
if(sb.charAt(i)==j)
{
System.out.println("Enter value for "+j);
int ip=sc.nextInt();
char temp=(char)ip;
//here how to replace the characters by int????
}
}
}
/* finally it will look like enter value b 4 enter value a 5 enter value i 6 the output is 451*5+6 */
With a Regular Expression
You should use regular expressions, it's more elegant and much more powerful. For example, without changing a line of code, you can use variable names that make more than one letter.
Example
Scanner sc = new Scanner(System.in);
String str = "b5l*a+i";
// This pattern could be declared as a constant
// It matches any sequence of alpha characters
Pattern pattern = Pattern.compile("[a-zA-Z]+");
Matcher matcher = pattern.matcher(str);
StringBuffer result = new StringBuffer();
// For each match ...
while(matcher.find()) {
// matcher.group() returns the macth found
System.out.println("Enter value for "+ matcher.group());
Integer input = sc.nextInt();
// ... append the parsed string with replacement of the match ...
matcher.appendReplacement(result, input.toString());
}
// ... and don't forget to append tail to add characters that follow the last match
matcher.appendTail(result);
System.out.println(result);
Taking your code and adapting it by following up on Kevin Anderson's comment, this seems to do what you're looking for:
Scanner sc = new Scanner(System.in);
String str="b5l*a+i";
StringBuffer sb=new StringBuffer(str);
for(int i=0;i<sb.length();i++)
{
for(int j='a';j<='z';j++)
{
if(sb.charAt(i)==j)
{
System.out.println("Enter value for "+(char)j);
int ip=sc.nextInt();
sb.deleteCharAt(i);
sb.insert(i, ip);
}
}
}
Might I also suggest this code which would behave similarly?
Scanner sc = new Scanner(System.in);
String str="b5l*a+i";
StringBuffer sb=new StringBuffer(str);
for(int i=0;i<sb.length();i++)
{
char original = sb.charAt(i);
if(original >= 'a' && original <= 'z')
{
System.out.println("Enter value for "+original);
int ip=sc.nextInt();
sb.deleteCharAt(i);
sb.insert(i, ip);
}
}
It should be more efficient, as it will not have to loop through the characters.
EDIT
After seeing #Sebastien's excellent answer, and applying some more of my own changes, I believe the following is an even better solution than the above ones, if it fits your project's constraints.
Scanner sc = new Scanner(System.in);
String str = "b5l*a+i";
Matcher matcher = Pattern.compile("[a-z]").matcher(str);
StringBuilder sb = new StringBuilder(str);
while (matcher.find())
{
System.out.println("Enter value for " + matcher.group());
int ip = sc.nextInt();
sb.setCharAt(matcher.start(), Character.forDigit(ip, 10));
}
Here is what is better:
Pattern matching with regular expressions. This way you don't need to manually search through each character of the String and check if it is a letter, then decide what to do with it. You can let the Matcher do that for you. The regular expression [a-z] means "exactly one character in the range of a to z. The matcher.find() method returns true each time it finds a new match for that expression as it moves through the String, and false when there are no more. Then, matcher.group() gets the character from the past find() operation (as a String, but that doesn't matter to us). matcher.start() gets the index for the match (the methods are named start() and end() because a typical match will be more than one character and have a start and end index, but only start() matters to us).
Switched to StringBuilder. StringBuilder is considered the newer implementation of what StringBuffer was designed for. It is generally preferred to use StringBuilder, unless you need your application to be thread-safe (which you don't, unless you know for sure that you specifically do need it to be). In our case, it also makes the action a lot easier by providing the setCharAt method, which does exactly what we need to do. Now we can just plop in the index of the char we intend to change (which the Matcher so conveniently provides us with), and the new character we got from the input. We must first make a character out of the int, using the convenient static method of the Character class, forDigit. The first part is the digit we read from input, and the second bit is the radix, which it needs to know to determine the digit's validity (for example, in base-10, the input 10 will be invalid, but in base-16, hexadecimal, it will return 'a'), in our case we put 10, because base-10 is the most common English number system. If the input is invalid (i.e. more than one base-10 digit, like 10, or less than 0), it will return a null character, so you may want to pop that out of the forDigit argument and first check if it is null, and handle input accordingly, something like the following:
char ipChar = Character.forDigit(ip, 10);
if (ipChar == '\u0000') throw new MyCustomNotADigitException("error message");
sb.setCharAt(matcher.start(), ipChar);
String str = "muthu", str1 = "";
int n = 5;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'u') {
str1 = str1 + n;
} else
str1 = str1 + str.charAt(i);
}
I have inputs like
AS23456SDE
MFD324FR
I need to get First Character values like
AS, MFD
There should no first two or first 3 characters input can be changed. Need to get first characters before a number.
Thank you.
Edit : This is what I have tried.
public static String getPrefix(String serial) {
StringBuilder prefix = new StringBuilder();
for(char c : serial.toCharArray()){
if(Character.isDigit(c)){
break;
}
else{
prefix.append(c);
}
}
return prefix.toString();
}
Here is a nice one line solution. It uses a regex to match the first non numeric characters in the string, and then replaces the input string with this match.
public String getFirstLetters(String input) {
return new String("A" + input).replaceAll("^([^\\d]+)(.*)$", "$1")
.substring(1);
}
System.out.println(getFirstLetters("AS23456SDE"));
System.out.println(getFirstLetters("1AS123"));
Output:
AS
(empty)
A simple solution could be like this:
public static void main (String[]args) {
String str = "MFD324FR";
char[] characters = str.toCharArray();
for(char c : characters){
if(Character.isDigit(c))
break;
else
System.out.print(c);
}
}
Use the following function to get required output
public String getFirstChars(String str){
int zeroAscii = '0'; int nineAscii = '9';
String result = "";
for (int i=0; i< str.lenght(); i++){
int ascii = str.toCharArray()[i];
if(ascii >= zeroAscii && ascii <= nineAscii){
result = result + str.toCharArray()[i];
}else{
return result;
}
}
return str;
}
pass your string as argument
I think this can be done by a simple regex which matches digits and java's string split function. This Regex based approach will be more efficient than the methods using more complicated regexs.
Something as below will work
String inp = "ABC345.";
String beginningChars = inp.split("[\\d]+",2)[0];
System.out.println(beginningChars); // only if you want to print.
The regex I used "[\\d]+" is escaped for java already.
What it does?
It matches one or more digits (d). d matches digits of any language in unicode, (so it matches japanese and arabian numbers as well)
What does String beginningChars = inp.split("[\\d]+",2)[0] do?
It applies this regex and separates the string into string arrays where ever a match is found. The [0] at the end selects the first result from that array, since you wanted the starting chars.
What is the second parameter to .split(regex,int) which I supplied as 2?
This is the Limit parameter. This means that the regex will be applied on the string till 1 match is found. Once 1 match is found the string is not processed anymore.
From the Strings javadoc page:
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.
This will be efficient if your string is huge.
Possible other regex if you want to split only on english numerals
"[0-9]+"
public static void main(String[] args) {
String testString = "MFD324FR";
int index = 0;
for (Character i : testString.toCharArray()) {
if (Character.isDigit(i))
break;
index++;
}
System.out.println(testString.substring(0, index));
}
this prints the first 'n' characters before it encounters a digit (i.e. integer).
I am a beginner in Java trying to write a program to convert strings into title case. For example, if String s = "my name is milind", then the output should be "My Name Is Milind".
import java.util.*;
class TitleCase
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
System.out.println("ent");
String s=in.nextLine();
String str ="";
char a ;
for(int i =0;i<s.length()-1;i++)
{
a = s.charAt(i);
if(a==' ')
{
str = str+(Character.toUpperCase(s.charAt(i+1)));
}
else
{
str =str+(Character.toLowerCase(a));
}
}
//for(int i =0; i<s.length();i++)
//{
System.out.println(str);
//}
}
}
You are trying to capitalize every word of the input.
So you have to do following steps:
get the words separated
capitalize each word
put it all together
print it out
Example Code:
public static void main(String args[]){
Scanner in = new Scanner(System.in);
System.out.println("ent");
String s=in.nextLine();
//now your input string is storred inside s.
//next we have to separate the words.
//here i am using the split method (split on each space);
String[] words = s.split(" ");
//next step is to do the capitalizing for each word
//so use a loop to itarate through the array
for(int i = 0; i< words.length; i++){
//we will save the capitalized word in the same place again
//first, geht the character on first position
//(words[i].charAt(0))
//next, convert it to upercase (Character.toUppercase())
//then add the rest of the word (words[i].substring(1))
//and store the output back in the array (words[i] = ...)
words[i] = Character.toUpperCase(words[i].charAt(0)) +
[i].substring(1);
}
//now we have to make a string out of the array, for that we have to
// seprate the words with a space again
//you can do this in the same loop, when you are capitalizing the
// words!
String out = "";
for(int i = 0; i<words.length; i++){
//append each word to out
//and append a space after each word
out += words[i] + " ";
}
//print the result
System.out.println(out);
}
Using Java 8 streams:
String titleCase = (new ArrayList<>(Arrays.asList(inputString.toLowerCase().split(" "))))
.stream()
.map(word -> Character.toTitleCase(word.charAt(0)) + word.substring(1))
.collect(Collectors.joining(" "));
The problem is with the way you're adding characters. Take a look at your if condition:
a = s.charAt(i);
if(a==' ')
{
// Here you are adding not the current character, but the NEXT character.
str = str+(Character.toUpperCase(s.charAt(i+1)));
}
else
{
// Here you are adding the current character.
str =str+(Character.toLowerCase(a));
}
As a result of this condition, you will skip a character if your input string contains a space, then repeat another character that you've already added.
Additionally, you're not looping through the whole string because your loop conditional goes to s.length()-1. Change that to just s.length(). However, if you do that, you may run into an exception if the input string ends with a space (since you'll try to check for a character at an out-of-bound index).
Here's what the fixed code would look like:
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
System.out.println("ent");
String s=in.nextLine();
String str ="";
char a ;
for(int i =0;i<s.length();i++)
{
a = s.charAt(i);
if(a==' ')
{
str = str+Character.toLowerCase(a)+(Character.toUpperCase(s.charAt(i+1)));
i++; // "skip" the next element since it is now already processed
}
else
{
str =str+(Character.toLowerCase(a));
}
}
System.out.println(str);
}
NOTE: I only fixed the code that you supplied. However, I'm not sure it works the way you want it to - the first character of the string will still be whatever case it started in. Your conditional only uppercases letters that are preceded by a space.
You want to change the case of the first letter of each word of a String.
To do so, I would follow the following steps :
split the String in words : see String.split(separator)
retrieve the first letter of each word : see String.charAt(index)
retrieve its capitalized version : the Character.toUpperCase(char) you use is perfect
concatenate the capitalized letter with the rest of the word : concatenation operator (+) and String.substring
create a new String from the capitalized words : see String.join(separator)
Code Golf variation... I challenge anyone to make it any simpler than this:
public String titleCase(String str) {
return Arrays
.stream(str.split(" "))
.map(String::toLowerCase)
.map(StringUtils::capitalize)
.collect(Collectors.joining(" "));
}
By the way: Unicode distinguishes between three cases: lower case, upper case and title case. Although it does not matter for English, there are other languages where the title case of a character does not match the upper case version. So you should use
Character.toTitleCase(ch)
instead of Character.toUpperCase(ch) for the first letter.
There are three character cases in Unicode: upper, lower, and title. Uppercase and lowercase are familiar to most people. Titlecase distinguishes characters that are made up of multiple components and are written differently when used in titles, where the first letter in a word is traditionally capitalized. For example, in the string "ljepotica",[2] the first letter is the lowercase letter lj(\u01C9 , a letter in the Extended Latin character set that is used in writing Croatian digraphs). If the word appeared in a book title, and you wanted the first letter of each word to be in uppercase, the correct process would be to use toTitleCase on the first letter of each word, giving you "Ljepotica" (using Lj, which is \u01C8). If you incorrectly used toUpperCase, you would get the erroneous string "LJepotica" (using LJ, which is \u01C7).
[The Java™ Programming Language, Fourth Edition, by James Gosling, Ken Arnold, David Holmes (Prentice Hall). Copyright 2006 Sun Microsystems, Inc., 9780321349804]
WordUtils.capitalizeFully() worked for me like charm as it gives: WordUtils.capitalizeFully("i am FINE") = "I Am Fine"
import java.util.Scanner;
public class TitleCase {
public static void main(String[] args) {
System.out.println("please enter the string");
Scanner sc1 = new Scanner(System.in);
String str = sc1.nextLine();
//whatever the format entered by user, converting it into lowercase
str = str.toLowerCase();
// converting string to char array for
//performing operation on individual elements
char ch[] = str.toCharArray();
System.out.println("===============");
System.out.println(str);
System.out.println("===============");
//First letter of senetence must be uppercase
System.out.print((char) (ch[0] - 32));
for (int i = 1; i < ch.length; i++) {
if (ch[i] == ' ') {
System.out.print(" " + (char) (ch[i + 1] - 32));
//considering next variable after space
i++;
continue;
}
System.out.print(ch[i]);
}
}
}
You can use lamda instead-
String titalName = Arrays.stream(names.split(" "))
.map(E -> String.valueOf(E.charAt(0))+E.substring(1))
.reduce(" ", String::concat);
I have one String generated of random characters that will encrypt another String given by the user by adding the first character from the String with the first character of the given String. It's working fine, but if the user were to enter multiple words with spaces in between, I want to choose the next character of the first String rather than code the space itself. Is that possible? This is what I have:
(random is the coded string and sentenceUpper is string given by user)
public static void encrypt(String sentenceUpper){
String newSentence = "";
for(int i = 0; i < sentenceUpper.length(); i++){
char one = random.charAt(i);
char two = sentenceUpper.charAt(i);
if(one < 'A' || one > 'Z'){
two = sentenceUpper.charAt(1 + i);}
char result = (char)((one + two)%26 + 'A');
newSentence += "" + result;
}
EDIT FOR BETTER EXPLANATION:
I have:
String random = "WFAZYZAZOHS";
I would like to code user input:
String upperCase: "YOU GO";
So, I'm going to take Y + L = U, etc...
to get :
"UTUSEN
"
But I see that there's a space in "YOU GO" , So I'd like to change it to:
WFA ZY + YOU GO = UTU SE.
I hope that's better explained.
The simplest way to do this would probably be to use an if statement to run the code in the loop only if the character is not a space. If you don't want to skip the character in the random string, you would need a separate variable to track the current character index in that string.
Example: Put this after defining one and two and put the rest of the loop inside it:
if(two==' '){
...
}
Then, add the space in the output:
else{
newSentence+=" ";
}
I'm able to separate the words in the sentence but I do not know how to check if a word contains a character other than a letter. You don't have to post an answer just some material I could read to help me.
public static void main(String args [])
{
String sentance;
String word;
int index = 1;
System.out.println("Enter sentance please");
sentance = EasyIn.getString();
String[] words = sentance.split(" ");
for ( String ss : words )
{
System.out.println("Word " + index + " is " + ss);
index++;
}
}
What I would do is use String#matches and use the regex [a-zA-Z]+.
String hello = "Hello!";
String hello1 = "Hello";
System.out.println(hello.matches("[a-zA-Z]+")); // false
System.out.println(hello1.matches("[a-zA-Z]+")); // true
Another solution is if (Character.isLetter(str.charAt(i)) inside a loop.
Another solution is something like this
String set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String word = "Hello!";
boolean notLetterFound;
for (char c : word.toCharArray()){ // loop through string as character array
if (!set.contains(c)){ // if a character is not found in the set
notLetterfound = true; // make notLetterFound true and break the loop
break;
}
}
if (notLetterFound){ // notLetterFound is true, do something
// do something
}
I prefer the first answer though, using String#matches
For more reference goto-> How to determine if a String has non-alphanumeric characters?
Make the following changes in pattern "[^a-zA-Z^]"
Not sure if I understand your question, but there is the
Character.isAlpha(c);
You would iterate over all characters in your string and check whether they are alphabetic (there are other "isXxxxx" methods in the Character class).
You could loop through the characters in the word calling Character.isLetter(), or maybe check if it matches a regular expression e.g. [\w]* (this would match the word only if its contents are all characters).
you can use charector array to do this like..
char[] a=ss.toCharArray();
not you can get the charector at the perticulor index.
with "word "+index+" is "+a[index];