I'm writing a Java program in which I'm checking a list against a string, and then doing stuff to that. In fortran I'd write something along the lines of
where(list(:)==stringToCheck){
...
statements
...
}
Instead I have a headache of a block of for-loops, if staments and breaks all over the place. No perhaps I could neaten the code a little but it still feels far more inefficient than fortran.
Edit, this is the code I've resorted to:
for(int idx=0;idx<player.get_charactersOwned().size();idx++)
{
if(player.get_charactersOwned().get(idx).get_characterName().equals(charName))
{
/* Add character to the game
* Add game to the character*/
System.out.println("Character "+charName+" Found ");
gameToMake.addCharacters(player.get_charactersOwned().get(idx));
player.get_charactersOwned().get(idx).addGame(gameToMake);
break;
}else
{
System.err.println("Character "+ charName +" not found");
System.out.println("Shall I add that Character? y/n ");
choice = scanner.nextLine();
if(choice.equalsIgnoreCase("y"))
{
charName = scanner.nextLine();
Character character = new Character(charName);
characterTempList.add(character);
player.addCharacter(characterTempList);
gameToMake.addCharacters(player.get_charactersOwned().get(idx));
player.get_charactersOwned().get(idx).addGame(gameToMake);
break;
}else{break;}
}
}
As tempting as it is to fix this code, I'd much rather use a work around.
Is there a Java equivilant of this without the use of external libraries?
No, there isn't an equivalent in Java. Instead if you need to check if a list of characters (each with a name) contains a character name then simply do this:
// search the name
boolean found = false;
for (Character c : player.get_charactersOwned()) {
if (c.get_characterName().equals(charName)) {
found = true;
break;
}
}
// perform the check
if (found) {
// do something
} else {
// do something else
}
And by the way, Character is a bad name for your class, it clashes with Java's own Character class. Rename it if possible, to avoid confusion. Alternatively, the loop could have been written like this:
boolean found = false;
for (int i = 0, n = player.get_charactersOwned().size(); i < n && !found; i++) {
Character c = player.get_charactersOwned().get(i);
if (c.get_characterName().equals(charName)) {
found = true;
}
}
Related
I am writing a hangman program and one of the requirements to a hangman game is preventing the user from entering the same letter twice.
I have written the code for that, but the problem is every time I enter a letter it says it is already entered. I need to only say it when it is entered the second time. You guys have any suggestions? I've been trying to fix this for the past few hours, I figured I could ask on here to find some help. I already looked at another Stackoverflow question regarding something similar to this but all those solutions have the same result.
In Java, how can I determine if a char array contains a particular character?
I've tried something like this but it won't work either:
boolean contains = false;
for (char c : store) {
if (c == character) {
System.out.println("Already Entered");
contains = true;
break;
}
}
if (contains) {
// loop to top
continue;
}
SECOND CLASS-
public void hangman(String word, int life) {
KeyboardReader reader = new KeyboardReader();
char[] letter = new char[word.length()];
char[] store = new char[word.length()];
String guess;
int i = 0, tries = 0, incorrect = 0, count = 1, v = 0;
while (i < word.length()) {
letter[i] = '-';
I would just use the String.contains() method:
String aString = "abc";
char aChar = 'a';
return aString.contains(aChar + "");
To keep track of guessed letters you can use a StringBuffer, appending them using a StringBuffer.append() to append new letters (maintaining state) and use the StringBuffer.toString() method to get the String representation when you need to do the comparison above.
Since Java 1.5 the class String contains the method contains(). My idea is to collect all entered letters into a string variable and using above method:
// My code line
String letterAlreadyEntered = "";
// Your code line
char character = reader.readLine().charAt(0);
// My code line
if (letterAlreadyEntered.contains("" + character) == true) {
//Put code here what ever you want to do with existing letter
} else {
letterAlreadyEntered += character;
}
In my opinion, this is an easier way to check for occurrences than in arrays, where you have to write your own check method.
beginner here. I want to be able to ask the user a question. If the user's answer is empty or contains only spaces, it should print out an error, then go back to the unanswered question. Thus creating a loop until the question is answered. Please see code below:
do {
while(true) {
System.out.print("Dog's name: ");
String dogName = scan.nextLine().toLowerCase().trim();
if(dogName.isEmpty()) {
System.out.println("Error: This can't be empty.");
continue;
}
do {
while(true) {
System.out.print("Breed: ");
String breed = scan.nextLine().toLowerCase().trim();
if(breed.isEmpty()) {
System.out.println("Error: Breed can't be empty.");
continue;
}
This code works but it gets very repetitive and long. Is there a shorter and faster way of writing this? Thank you.
This is an ideal use case for a function. A function encapsulates a piece of code that you need multiple times and allows for both input via parameters and output via return types.
I suggest to read beginner tutorials of Java on how to use functions (also called methods in Java if they belong to a certain object, i.e. are not static).
Functions (also called procedures sometimes in other languages) are the basic building block of procedural programming, so I suggest you to learn about that topic as well.
In your specific case, that function could look like this:
String input(String label)
{
System.out.print(label+": ");
String s = scan.nextLine().toLowerCase().trim(); // assuming "scan" is defined in the enclosing class
if(s.isEmpty())
{
System.out.println("Error: "+label+" can't be empty.");
return input(label);
}
return s;
}
This is a recursive function but you can do it iteratively as well.
Create a method for the code which takes the question as a parameter,if the input is wrong you need to ask the same question, call the same method(recursion) with the same question.
pseudo code::
public void test(String s) {
System.out.print(s + ": ");
String input = scan.nextLine().toLowerCase().trim();
if(dogName.isEmpty()) {
System.out.println("Error: This can't be empty.");
test(s);
} else {
return input;
}
To read about recursion.
You can try something like this so you can have many questions but same amount code, this is to illustrate the idea, may not fully work
String questions[] = {"Dog's name: ","Breed: "};
for (int i = 0; i < questions.length; i++) {
System.out.print(questions[i]);
Scanner scan = new Scanner(System.in);
String answer = null;
while(!(answer = scan.nextLine()).isEmpty()) {
System.out.print("You answered: " + answer + "\n");
}
}
You can do this :
while ((dogName = scan.nextLine().toLowerCase().trim()).isEmpty()) {
System.out.println("Error: This can't be empty.");
}
// Use dogName not empty
while ((breed = scan.nextLine().toLowerCase().trim()).isEmpty()) {
System.out.println("Error: Breed can't be empty.");
}
// Use breed not empty
Best
I am trying to get my code to prevent a user input from having a number in it.
Essentially I want the code to do as follows:
ask for input
receive input
test whether or not the input contains a number(ex: 5matt vs matt)
if contains a number I want to System.out.println("Error: please do not input a number");
Heres the kicker (and why it's not a duplicate question): I can't use loops or other statements we haven't learned yet. So far the only true statements we've learned are if/else/else if statements. That means I can not use for loops, like some of the answers are suggesting. While they're great answers, and work, I'll lose points for using them.
System.out.println("Please input the first name: ");
String name1 = in.next();
System.out.println("Please input the second name: ");
String name2 = in.next();
System.out.println("Please input the third name: ");
String name3 = in.next();
name1 = name1.substring(0,1).toUpperCase() + name1.substring(1).toLowerCase();
name2 = name2.substring(0,1).toUpperCase() + name2.substring(1).toLowerCase();
name3 = name3.substring(0,1).toUpperCase() + name3.substring(1).toLowerCase();
I have this already but I can't figure out how to test if the input only contains letters.
Okay, there are many ways to deal with this. A good thing would be to use Regex (text matching stuff). But it seems that you should only use very basic comparison methods.
So, let's do something very basic and easy to understand: We iterate over every character of the input and check whether it's a digit or not.
String input = ...
// Iterate over every character
for (int i = 0; i < input.length(); i++) {
char c = s.charAt(i);
// Check whether c is a digit
if (Character.isDigit(c)) {
System.out.println("Do not use digits!");
}
}
This code is very straightforward. But it will continue checking even if a digit was found. You can prevent this using a helper-method and then returning from it:
public boolean containsDigit(String text) {
// Iterate over every character
for (int i = 0; i < input.length(); i++) {
char c = s.charAt(i);
// Check whether c is a digit
if (Character.isDigit(c)) {
return true;
}
}
// Iterated through the text, no digit found
return false;
}
And in your main program you call it this way:
String input = ...
if (containsDigit(input)) {
System.out.println("Do not use digits!");
}
Use a regular expression to filter the input
Eg
str.matches(".*\\d.*")
See this link for more info
There are several ways you could do this, among others:
Iterate over all the chars in the string and check whether any of them is a digit.
Check whether the string contains the number 1, number 2, number 3, etc.
Use a regular expression to check if the string contains a digit.
(Java Regular Expressions)
If you're allowed to define functions, you can essentially use recursion to act as a loop. Probably not what your prof is going for, but you could be just inside the requirements depending on how they're worded.
public static boolean stringHasDigit(String s) {
if (s == null) return false; //null contains no chars
else return stringHasDigit(s, 0);
}
private static boolean stringHasDigit(String s, int index) {
if (index >= s.length()) return false; //reached end of string without finding digit
else if (Character.isDigit(s.charAt(index))) return true; //Found digit
else return stringHasDigit(s, index+1);
}
Only uses if/elseif/else, Character.isDigit, and String.charAt, but recursion might be off limits as well.
I am trying to write one java program. This program take a string from the user as an input and display the output by removing the special characters in it. And display the each strings in new line
Let's say I have this string Abc#xyz,2016!horrible_just?kidding after reading this string my program should display the output by removing the special characters like
Abc
xyz
2016
horrible
just
kidding
Now I know there are already API available like Matcher and Patterns API in java to do this. But I don't want to use the API since I am a beginner to java so I am just trying to crack the code bit by bit.
This is what I have tried so far. What I have done here is I am taking the string from the user and stored the special characters in an array and doing the comparison till it get the special character. And also storing the new character in StringBuilder class.
Here is my code
import java.util.*;
class StringTokens{
public void display(String string){
StringBuilder stringToken = new StringBuilder();
stringToken.setLength(0);
char[] str = {' ','!',',','?','.','_','#'};
for(int i=0;i<string.length();i++){
for(int j =0;j<str.length;j++){
if((int)string.charAt(i)!=(int)str[j]){
stringToken.append(str[j]);
}
else {
System.out.println(stringToken.toString());
stringToken.setLength(0);
}
}
}
}
public static void main(String[] args){
if(args.length!=1)
System.out.println("Enter only one line string");
else{
StringTokens st = new StringTokens();
st.display(args[0]);
}
}
}
When I run this code I am only getting the special characters, I am not getting the each strings in new line.
One easy way - use a set to hold all invalid characters:
Set<Character> invalidChars = new HashSet<>(Arrays.asList('$', ...));
Then your check boils down to:
if(invaidChars.contains(string.charAt(i)) {
... invalid char
} else {
valid char
}
But of course, that still means: you are re-inventing the wheel. And one does only re-invent the wheel, if one has very good reasons to. One valid reason would be: your assignment is to implement your own solution.
But otherwise: just read about replaceAll. That method does exactly what your current code; and my solution would be doing. But in a straight forward way; that every good java programmer will be able to understand!
So, to match your question: yes, you can implement this yourself. But the next step is to figure the "canonical" solution to the problem. When you learn Java, then you also have to focus on learning how to do things "like everybody else", with least amount of code to solve the problem. That is one of the core beauties of Java: for 99% of all problems, there is already a straight-forward, high-performance, everybody-will-understand solution out there; most often directly in the Java standard libraries themselves! And knowing Java means to know and understand those solutions.
Every C coder can put down 150 lines of low-level array iterating code in Java, too. The true virtue is to know the ways of doing the same thing with 5 or 10 lines!
I can't comment because I don't have the reputation required. Currently you are appending str[j] which represents special character. Instead you should be appending string.charAt(i). Hope that helps.
stringToken.append(str[j]);
should be
stringToken.append(string.charAt(i));
Here is corrected version of your code, but there are better solutions for this problem.
public class StringTokens {
static String specialChars = new String(new char[]{' ', '!', ',', '?', '.', '_', '#'});
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Enter only one line string");
} else {
display(args[0]);
}
}
public static void display(String string) {
StringBuilder stringToken = new StringBuilder();
stringToken.setLength(0);
for(char c : string.toCharArray()) {
if(!specialChars.contains(String.valueOf(c))) {
stringToken.append(c);
} else {
stringToken.append('\n');
}
}
System.out.println(stringToken);
}
}
public static void main(String[] args) {
String a=",!?#_."; //Add other special characters too
String test="Abc#xyz,2016!horrible_just?kidding"; //Make this as user input
for(char c : test.toCharArray()){
if(a.contains(c+""))
{
System.out.println(); //to avoid printing the special character and to print newline
}
else{
System.out.print(c);
}
}
}
you can run a simple loop and check ascii value of each character. If its something other than A-Z and a-z print newline skip the character and move on. Time complexity will be O(n) + no extra classes used.
String str = "Abc#xyz,2016!horrible_just?kidding";
char charArray[] = str.toCharArray();
boolean flag=true;;
for (int i = 0; i < charArray.length; i++) {
int temp2 = (int) charArray[i];
if (temp2 >= (int) 'A' && temp2 <= (int) 'Z') {
System.out.print(charArray[i]);
flag=true;
} else if (temp2 >= (int) 'a' && temp2 <= (int) 'z') {
System.out.print(charArray[i]);
flag=true;
} else {
if(flag){
System.out.println("");
flag=false;
}
}
}
I have here a String that contains the source code of a class. Now i have another String that contains the full name of a method in this class. The method name is e.g.
public void (java.lang.String test)
Now I want to retieve the source code of this method from the string with the class' source code. How can I do that? With String#indexOf(methodName) i can find the start of the method source code, but how do i find the end?
====EDIT====
I used the count curly-braces approach:
internal void retrieveSourceCode()
{
int startPosition = parentClass.getSourceCode().IndexOf(this.getName());
if (startPosition != -1)
{
String subCode = parentClass.getSourceCode().Substring(startPosition, parentClass.getSourceCode().Length - startPosition);
for (int i = 0; i < subCode.Length; i++)
{
String c = subCode.Substring(0, i);
int open = c.Split('{').Count() - 1;
int close = c.Split('}').Count() - 1;
if (open == close && open != 0)
{
sourceCode = c;
break;
}
}
}
Console.WriteLine("SourceCode for " + this.getName() + "\n" + sourceCode);
}
This works more or less fine, However, if a method is defined without body, it fails. Any hints how to solve that?
Counting braces and stopping when the count decreases to 0 is indeed the way to go. Of course, you need to take into account braces that appear as literals and should thus not be counted, e.g. braces in comments and strings.
Overall this is kind of a thankless endeavour, comparable in complexity to say, building a command line parser if you want to get it working really reliably. If you know you can get away with it you could cut some corners and just count all the braces, although I do not recommend it.
Update:
Here's some sample code to do the brace counting. As I said, this is a thankless job and there are tons of details you have to get right (in essence, you 're writing a mini-lexer). It's in C#, as this is the closest to Java I can write code in with confidence.
The code below is not complete and probably not 100% correct (for example: verbatim strings in C# do not allow spaces between the # and the opening quote, but did I know that for a fact or just forgot about it?)
// sourceCode is a string containing all the source file's text
var sourceCode = "...";
// startIndex is the index of the char AFTER the opening brace
// for the method we are interested in
var methodStartIndex = 42;
var openBraces = 1;
var insideLiteralString = false;
var insideVerbatimString = false;
var insideBlockComment = false;
var lastChar = ' '; // White space is ignored by the C# parser,
// so a space is a good "neutral" character
for (var i = methodStartIndex; openBraces > 0; ++i) {
var ch = sourceCode[i];
switch (ch) {
case '{':
if (!insideBlockComment && !insideLiteralString && !insideVerbatimString) {
++openBraces;
}
break;
case '}':
if (!insideBlockComment && !insideLiteralString && !insideVerbatimString) {
--openBraces;
}
break;
case '"':
if (insideBlockComment) {
continue;
}
if (insideLiteralString) {
// "Step out" of the string if this is the closing quote
insideLiteralString = lastChar != '\';
}
else if (insideVerbatimString) {
// If this quote is part of a two-quote pair, do NOT step out
// (it means the string contains a literal quote)
// This can throw, but only for source files with syntax errors
// I 'm ignoring this possibility here...
var nextCh = sourceCode[i + 1];
if (nextCh == '"') {
++i; // skip that next quote
}
else {
insideVerbatimString = false;
}
}
else {
if (lastChar == '#') {
insideVerbatimString = true;
}
else {
insideLiteralString = true;
}
}
break;
case '/':
if (insideLiteralString || insideVerbatimString) {
continue;
}
// TODO: parse this
// It can start a line comment, if followed by /
// It can start a block comment, if followed by *
// It can end a block comment, if preceded by *
// Line comments are intended to be handled by just incrementing i
// until you see a CR and/or LF, hence no insideLineComment flag.
break;
}
lastChar = ch;
}
// From the values of methodStartIndex and i we can now do sourceCode.Substring and get the method source
Have a look at:- Parser for C#
It recommends using NRefactory to parse and tokenise source code, you should be able to use that to navigate your class source and pick out methods.
You will have to, probably, know the sequence of the methods listed in the code file. So that, you can look for the method closing scope } which may be right above start of next method.
So you code might look like:
nStartOfMethod = String.indexOf(methodName)
nStartOfNextMethod = String.indexOf(NextMethodName)
Look for .LastIndexOf(yourMethodTerminator /*probably a}*/,...) between a string of nStartOfMethod and nStartOfNextMethod
In this case, if you dont know the sequence of methods, you might end up skipping a method in between, to find an ending brace.