Currently I have an Atoi function in Java which returns an int value on passing a string input. The initial return value is set to 0. However, the value returned will be 0 if invalid characters or all characters are passed in input string and if the actual string passed is just "0". How can I use return values for these two cases? Or is this okay and I should leave it upto the client to handle this ?
You almost certainly shouldn't use a return value in that situation - you should probably use an exception.
At that point though, I'm not sure why you're writing your own method in the first place - use Integer.parseInt instead.
If you need to be able to convey the notion of invalid input without an exception, you could potentially write a method which returns Integer instead of int, and returns null if there's invalid input, and an appropriate Integer reference otherwise.
(I'd also point out that Java tends to favour meaningful names, rather than somewhat arbitrary collections of letters such as atoi.)
This exact function is already handled by the Integer.parseInt() family of methods. Note the way they handle malformed input: they throw an exception.
You should seriously consider using these methods instead of your own.
If your function were returning a float or double, you could return NaN, but that's not the case.
Don't encode this information in the return value. Throw an exception if you encounter an invalid input string.
If zero, 0, is an invalid value, for instance in a banking application transfering money, you won't need to differentiate between invalid zero and input zero.
If negative values are invalid input, you can return invalid negative one, -1, as a return value in case of input errors.
If zero, negative and positive values are all valid inputs, you should consider wrapping the object, for instance using Integer.
If you must use a zero to indicate invalid result, and all above cases are not possible to use, add another method, for instance checkAtoI, that returns a boolean whether the parsed input is correct. In this case, you can check for zero and then call the checkAtoI method to know whether it was a valid zero input, or an invalid input resulting in a zero, 0, returned integer. This implementation is quite easy too:
boolean check(String s) {
return s.equals("0");
}
pay attention: throwing exception is slower then returning null.
My suggest is to return null if parsing failed. But this solution must be taken into account in the context of the whole your application
If you wanted just the integer prefix of a string, i'd probably use regex to grab just numbers
[0-9]*
and then call Integer.parseInt
on that, something like
Pattern p = Pattern.compile("\s*([0-9]*)");
Match m = p.matcher(input);
if (m.matches())
return Integer.parseInt(m.group(1));
else
return 0;
One of the option is to throw an exception which the client would need to handle and then act appropriately, doing so you are delegating the error handling to the client so that as the API implementer you do not have to worry about whether this situation is error, exception or normal for the clients. They will decide and handle the exception (suppress the noise, alert client, ask client to re-enter etc).
Another option would be to return -1 if there is any error in parsing the string, in this case also client will take the decision what to do next.
Although the advantage with throwing an exception is you can always pass details about what the error was in Exception message which is not possible if you pass -1.
private static int getDecValue(char hex) {
int dec = 0;
switch (hex) {
case '0':
dec = 0;
break;
case '1':
dec = 1;
break;
case '2':
dec = 2;
break;
case '3':
dec = 3;
break;
case '4':
dec = 4;
break;
case '5':
dec = 5;
break;
case '6':
dec = 6;
break;
case '7':
dec = 7;
break;
case '8':
dec = 8;
break;
case '9':
dec = 9;
break;
default:
// do nothing
}
return dec;
}
public static int atoi(String ascii) throws Exception {
int integer = 0;
for (int index = 0; index < ascii.length(); index++) {
if (ascii.charAt(index) >= '0' && ascii.charAt(index) <= '9') {
integer = (integer * 10) + getDecValue(ascii.charAt(index));
} else {
throw new Exception("Is not an Integer : " + ascii.charAt(index));
}
}
return integer;
}
Related
im doing an assignment which requires me to create 3 classes.
1 with getting 2 random integers,
1 with getting random operators such as + - * / which should be done so in char method
the last one to check if the simple mathematics answer is correct using booleans via user Scanner input.
i need a little help here as im not sure if i've done the random operators method correctly and am really lost at how i should tabulate both random int and operators together in one class.
here's the code i've done so far:
public static char getOperator (int x, int y)
{
char operator;
int answer;
switch (rand.nextInt(4))
{
case 0: operator = '+';
answer = x + y;
break;
case 1: operator = '-';
answer = x - y;;
break;
case 2: operator = '*';
answer = x * y;;
break;
case 3: operator = '/';
answer = x / y;;
break;
default: operator = '?';
}
return operator;
}
I believe you mean you need to create 3 methods (and not classes).
One that creates a random integer (it's a bad design to create a
method that returns two integers instead of just calling two times
one that returns one int).
One that returns a random operator
One that checks if an operation consisting of "random-number
random-operator random-number" is equal to user input
Anyways, there's a lot to unpack here, so:
Your first method getTwoIntegers is incorrect, you're asking for two integers in input but you never actually use them, then you return one random number.
The method getOperator needs to be redesigned to have no input and return one char (equal to + - x /).
Your final method will call the your first method twice, then the second method once, it will then print the operation for the user to see, and check if the response is correct.
Hopefully this can help you conceptualize better the way you should build your code.
I didn't post the source code since I believe it's much better for you if you try to do it by yourself (this being an assignment and all)
Good luck and have fun :)
this problem causes an infinite loop in the following code excerpt:
public static final List<String> extractTags(String source, Integer nTags) {
List<String> tags = new ArrayList<>();
try (StringReader stringReader = new StringReader(source)) {
String tag = "";
char c;
while ((c = (char) stringReader.read()) >= 0 && tags.size() < nTags) {
switch (c) {
case '<':
tag = "";
break;
case '>':
tags.add(tag);
break;
default:
tag = tag + c;
break;
}
}
} catch (IOException e) {
} finally {
return tags;
}
}
if invoked with the following parameters:
source = "trash"
nTags = 2
Using a debugger I realized that after the string was completely iterated, the read() method returns the char '\uFFFF' 65535 forever. So my question is why?
Thanks!
Because stringReader.read() is returning -1 for end of stream, but you're casting it to char which is the only unsigned datatype in Java. So instead of -1 you're getting 65535 for end of stream therefore never breaking the while loop.
You might want to cast what is read into a char inside the loop, instead of at the while condition.
make it granular
countTags(String source); => use this method to count tags only.
extractTags(String source) => identify what your tags are or what your tags are not then extract tags or extract what tags arent.
rebuild the string without tags/ rebuild as you extract.. StringBuilder/StringReader are not necessary.
some interesting things: you can do string.length when you start & when you end and subtract to find number of tags in the extract method which would give you the count.
you also don't need a while loop for this
For your actual problem: you might want to look into characters that need to be escaped.
In code
switch(token){
case StreamTokenizer.TT_EOF:
eof = true;
break;
case StreamTokenizer.TT_NUMBER:
double value = tokenizer.nval;
operands.add(value);
break;
case StreamTokenizer.TT_WORD:
operate(tokenizer.sval);
break;
default:
throw new WrongPhraseException("Unnexpected operator or operand: " + tokenizer.sval +".");
}
I give as input RPN, ex: 5 4 3 + *
Why is + not treated as TT_WORD, it isn't treated as it so it throws Exception.
From the StreamTokenizer documentation:
For a single character token, its value is the single character, converted to an integer.
Since your + character is single character, it is probably being treated as TT_NUMBER; your case statement for TT_NUMBER will need to handle these cases as well. The same will apply for your unquoted * character as well, I assume. Thus you might try something like this:
case StreamTokenizer.TT_NUMBER:
Double value = new Double(tokenizer.nval);
if (Character.isDigit(value.intValue()) {
operands.add(value.doubleValue());
} else {
// Possibly dealing with operator here. The hard/fun part is
// in coercing that double value back to its tokenized string
// form.
operate(new Character((char) tokenizer.nval).toString());
}
break;
Hope this helps!
This question already has answers here:
How to convert String object to Boolean Object?
(16 answers)
Closed 7 years ago.
I am very, very new at programming so sorry if this is a stupid question, but I can't find an answer anywhere.
In a program that I am working on the user can choose one of five options for problems to practice: addition, subtraction, multiplication, division, and remainders. There is a scanner that asks them to put in the fist letter of the name of the types of problems they want to practice (A or a, S or s, M or m, D or d, R or r). I want to make an if/else statement that will print out different problems depending on which one they choose.
The problem is, from what I can tell if/else statements will only work with boolean variables, but boolean variables don't like strings or string variables. I have seen ways to convert specific strings to variables, but since the user is deciding on the string, I have no way to know what they are going to choose every time. Is there anyway to convert a string variable to a boolean variable?? (i.e. the boolean variable is true when the string variable = "A")
if(s) can take boolean expressions (and use boolean operators, such as or). For example, String.equals(Object) (or String.equalsIgnoreCase(String)). Something like,
if (string.equals("A") || string.equals("a")) {
// ...
} else if (string.equalsIgnoreCase("B")) {// <-- or equalsIgnoreCase(String).
// ...
}
Personally, my favorite way is to use a switch statement when you're dealing with input, and while it doesn't use boolean values as you are use to in an if statement, for me it feels cleaner.
Your code would look like something such as:
switch(userInput.toLowerCase())
{
case "a":
// addition code
break;
case "s":
// subtraction code
break;
case "m":
// multiplication code
break;
case "d":
// division code
break;
case "r":
// remainder code
break;
default: // every other option besides (a, s, m, d, and r)
// print some error, user put wrong input
break;
}
Ypu can use
java.lang.Boolean(String s)
Allocates a Boolean object representing the value true if the string
argument is not null and is equal, ignoring case, to the string
"true".
Here's what you can do.You're dealing with a fairly simple problem.
Pseudo-Code
if(input=="A")
{
Do Addition
}
if(input=="M")
{
Do Multiplication
}
else
{
Give Error
}
Essentially, you want to check if the user input is equal to a particular string. You use the double equal to operator (==) here to perform the check.If the condition is TRUE and it will enter the block.
The Point is that the if block is evaluated on the basis of any expression that results into boolean values(i.e. true or false).
So there is no need to convert a String to Boolean.
All you have to do is just check if input string meets your criteria using a method provided by String Class in java called String.equals(String) or String.equalsIgnoreCase(String);
The return type of above methods is boolean (primitive) which will be evaluated by if statement as per your requirements.
To explore String Class in java
run "javap java.lang.String" on shell/bash/command prompt for programmer's guide to check out the contents of String Class
So your code will be something like
if(input.equalsIgnoreCase("a"))
{
// Calculations for addition
}
else if(input.equalsIgnoreCase("s"))
{
// Calculations for Substraction
}
Instead you can use switch-case as support for String in switch-case has been included from jdk7.
Also switch-case should be faster in this case as it will not check all cases as done by else if.
switch(input)
{
case "a":
case "A":
// Calculations for addition
break;
case "s":
case "S"
// Calculations for subtraction
break;
case "m":
case "M":
// Calculations for multiplication
break;
case "d":
case "D":
// Calculations for division
break;
case "r":
case "R":
// Calculations for remainder
break;
default: // for any other option besides above
// whatever handling you wanna do for wrong input
break;
}
I've got a home automation system working in Java, and I want to add simple math capabilities such as addition, subtraction, multiplication, division, roots, and powers.
At the system current state, it can convert a phrase into tags, as shown in the following examples:
example:
Phrase: "what is one hundred twenty two to the power of seven"
Tagged: {QUESTION/math} {NUMBER/122} {MATH/pwr} {NUMBER/7}
example:
Phrase: "twenty seven plus pi 3 squared"
Tagged: {NUMBER/27} {MATH/add} {NUMBER/3.14159} {MATH/multiply} {MATH/pwr} {NUMBER/2}
This example could be just as easily converted to something like this:
27 + 3.14159 * 3^2
Each tag is an object that can be queried for it value.
Edit: Specific question:
So now I need a way to read that group of tags as an equation, and return a numerical result. As a last resort I could use google or wolfram alpha, but that will be slower, and I'm trying to keep the automation system completely self contained.
If you would like to see the entire source, here it is in github.
Note that I have not committed the last few few changes, so some of the math related things I gave examples will not work.
After some more googleing (I didn't know the name for what I was doing at first) I found someone who has done something similar already:
http://www.objecthunter.net/exp4j/
Edit: Finished:
https://github.com/Sprakle/HomeAutomation/blob/master/src/net/sprakle/homeAutomation/interpretation/module/modules/math/Math.java
What you need is a parsing method that will build an equation and return an answer from your text. I'll take a single line and walk through making such a method which you will then need to work out for yourself. Note that this is just a general idea and that some languages other than Java may be more suitable for this kind of operation.
{QUESTION/math} {NUMBER/122} {MATH/pwr} {NUMBER/7}
//let's assume that the preprocessor reduces the input to an array that is something like this:
// [122, pwr, 7] (this is a very common construction in a language like LISP).
public static int math(string[] question){
while(i < question.length){
if(question[i] == "pwr"){
return pow(Integer.parseInt(question[i-1]), Integer.parseInt(question[i+1]);
}
i++;
}
return 0;
}
Basically what you'll need is a nice way of going from infix to prefix notation with a little bit of string to whatever conversions.
There are likely nicer structures for doing this than what I've produced above, but something like this should get you going.
Ben, he's right. The parsing action that takes natural language is much more difficult. What you need to do is add math precedence to the expression. The way you do that is to put the expression in some expected form, like post/pre/in-fix and provide an evaluation algorithm(post-fix ends up being pop(), pop(), evaluate(), push();. This requires that you check the individual tokens against a table that investigates the intersection of the operators and operands. It isn't anything you can do quickly or easily.
The code I wrote relies that the given order of tags is "NUMBER" "MATH" "NUMBER" "MATH" "NUMBER" and it completely ignores operational rules in math. It is just an outline of what you could do, so you may have to fix it up a bit to do what you want.
I have not tested this file due to lack of time, so debug it if necessary!
import net.sprakle.homeAutomation.interpretation.tagger.tags.*;
import java.util.List;
import java.util.Arrays;
public class Math {
private Tag[] tags; //Stores the converted tags as a "MathTag"
//Requires an array of tags
public Math(Tag[] inputTags) {
tags = new MathTag[inputTags.length]; //create a new MathTag array
System.arraycopy(inputTags, 0, tags, 0, tags.length); //Convert Tag array to MathTag array
}
//returns a value based on the tags
//TODO: ADD MATHEMATICAL ORDER OF OPERATIONS!!!
public double performMath() {
double value = 0;//initial value to return
for (int i = 0; i < tags.length; i++) { //perform initial check of the phrase given
if (tags[i].getType() = TagType.NUMBER && !tags[i].getWasChecked() && i + 1 < tags.length) {
value = performOperation(i, value, Double.parseDouble(tags[i].getValue()), tags[i+1].getType());
} else if (tags[i].getType() = TagType.MATH && !tags[i].getWasChecked() && i + 1 < tags.length) {
value = performOperation(i, value, Double.parseDouble(tags[i + 1].getValue()), tag.getType()); //I'm not positive if this would not cause issues
}
}
}
//Perform individual operations given the index of the operation, value1, value2, and the operation type
//The order of the array "operations" must match the order of the operations in the switch statement.
public double peformOperation(int i, double value1, double value2, String operation) {
String[] operations = {"add", "subtract", "multiply", "divide", "pwr", "root"}; //Array of operations
List list = Arrays.asList(operations); //Not exactly effecient, used to check what operation to perform
switch (list.indexOf(operation)) { //Perform a task based on the operation
case 0: //Addition
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 + value2;
case 1: //Subtraction
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 - value2;
case 2: //Multiplication
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 * value2;
case 3: //Division
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 / value2;
case 4: //Power
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 * value1;
case 5: //Square Root
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return Math.sqrt(value1);
}
return error(); //Non-valid operation found
}
//Need some way to detect an error
public double error() {
return 0;
}
//Need some way to check if a tag was looked at before
class MathTag extends Tag {
protected static boolean wasChecked = false;
public void setChecked(boolean checked) {
wasChecked = true;
}
public boolean getWasChecked() {
return wasChecked;
}
}
}