Any alternative to the indexOfAny method? - java

I'm trying to find the index of a char that splits two numbers, the char can either be +, -, / or *. I'm making a simple calculator.
The process would be extremely trivial if i could use the indexofAny method, because i would be able to check for all 4 values in 1 line. Sadly, it's not available in Java.
NOTE: I do not want to use indexOf, since i would have to write 4 lines of nearly identical code.
My main class:
import java.util.Scanner;
public class Main {
static Scanner scanner = new Scanner(System.in);
public static MathUserInput readInput() {
String input = scanner.nextLine();
String[] parts = input.split("\\+|-|/|\\*");
int firstNumber = Integer.parseInt(parts[0]);
int secondNumber = Integer.parseInt(parts[1]);
char operation = input.charAt(1);
return new MathUserInput(firstNumber, secondNumber, operation);
}
public static void main(String[] args) {
System.out.println("This is a calculator.");
System.out.println();
System.out.println("Please provider a number, an operator and a number");
System.out.println();
MathUserInput input = readInput();
char operation = input.getOperation();
switch (operation) {
case '+':
System.out.println(input.getFirstNumber() + input.getSecondNumber());
break;
case '-':
System.out.println(input.getFirstNumber() - input.getSecondNumber());
break;
case '*':
System.out.println(input.getFirstNumber() * input.getSecondNumber());
break;
case '/':
System.out.println(input.getFirstNumber() / input.getSecondNumber());
break;
}
}
}
I'm currently using a switch statement, but i'm hoping that there's a better alternative. Essentially, i'm aiming to only have 1 line that outputs the result in the calculator.
Thank you!

You can use StringUtils#indexOfAny(CharSequence, char...) from Apache Commons Lang which does exactly what you want.
import org.apache.commons.lang3.StringUtils;
public static MathUserInput readInput() {
String input = scanner.nextLine();
int pos = StringUtils.indexOfAny(input, '+', '-', '/', '*');
return new MathUserInput(input.substring(0, pos), input.substring(pos + 1), input.charAt(pos));
}
If you don't want to include a library for this, you can always write your own utility. Have a look at the code of StringUtils to be inspired. They are basically looping over the characters of the input string and in a nested loop over the characters to be found. The index of the first match is then returned.

I think you can use enum for the operations and encapsulate logic in it:
public class Main {
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
scan.useLocale(Locale.ENGLISH);
System.out.println("This is a calculator.");
System.out.println("Please provider a number, an operator and a number");
MathUserInput input = readInput(scan);
System.out.println(input.execute());
}
private static final Pattern PATTERN = Pattern.compile("(?<a>[^+\\-*\\/]+)(?<operation>[+\\-*\\/]+)(?<b>[^+\\-*\\/]+)");
private static MathUserInput readInput(Scanner scan) {
Matcher matcher = PATTERN.matcher(scan.nextLine());
if (!matcher.matches())
throw new RuntimeException("Incorrect expression");
double a = Double.parseDouble(matcher.group("a").trim());
double b = Double.parseDouble(matcher.group("b").trim());
Operation operation = Operation.parseSign(matcher.group("operation").trim().charAt(0));
return new MathUserInput(a, b, operation);
}
private static final class MathUserInput {
private final double a;
private final double b;
private final Operation operation;
public MathUserInput(double a, double b, Operation operation) {
this.a = a;
this.b = b;
this.operation = operation;
}
public double execute() {
return operation.execute(a, b);
}
}
private enum Operation {
SUM('+', Double::sum),
SUBTRACTION('-', (a, b) -> a - b),
MULTIPLY('*', (a, b) -> a * b),
DIVISION('/', (a, b) -> a / b);
private final char sign;
private final BiFunction<Double, Double, Double> func;
Operation(char sign, BiFunction<Double, Double, Double> func) {
this.sign = sign;
this.func = func;
}
public final double execute(double a, double b) {
return func.apply(a, b);
}
public static Operation parseSign(char sign) {
for (Operation operation : values())
if (operation.sign == sign)
return operation;
throw new EnumConstantNotPresentException(Operation.class, Character.toString(sign));
}
}
}

Related

why is calculator.getValue() always 0?

I am a java student and I am working to make my code more object oriented. I can easily code calculator in main but I'm really struggling to implement it with methods. The following code will always return 0...but the goal is to create a program which allows a user to enter an operator and a number in one line (example +5) the code should output the previous value, the new value, and allow for resetting. I believe I am really close to solving this and just need a point in the right direction..
output
Enter an operator and a number:
+5
0.0
Calculator class
import java.util.Scanner;
public class Calculator {
private final int RESET = 0;
private double number = 0;
private double result = 0; // I believe this is the issue but how can I resolve it?
private char operator;
private static Scanner keyboard = new Scanner(System.in);
public Calculator(double number)
{
this.number = number;
}
// this method invokes the whatOperator() to create a new result
// the edited method still returns 0
public double aResult(Calculator other)
{
other.whatOperator();
this.result = other.result;
return result;
}
// I created this method in hopes that it would do most of the work..when I invoke it and enter my operator and number it does not seem to function correctly
public void whatOperator()
{
String operator = null;
operator = enterNumber();
double theNumber = Double.parseDouble(operator);
char theOperator =operator.charAt(0);
operator = null;
operator += theOperator;
// switch method to find the operator
switch(operator){
case "*":
result = getNumber() * theNumber;
break;
case "/":
result = getNumber() / theNumber;
break;
case "+":
result = getNumber() + theNumber;
break;
case "-":
result = getNumber() - theNumber;
break;
case "R":
result = RESET;
break;
}
}
// methods for operation...I was hoping to not use these
public double add(double secondNumber)
{
result = number + secondNumber;
return result;
}
public double divide(double secondNumber)
{
result = number / secondNumber;
return result;
}
public double multiply(double secondNumber)
{
result = number * secondNumber;
return result;
}
public void subtract(double secondNumber)
{
result = number - secondNumber;
}
public double getNumber()
{
return number;
}
// method for getting input
public static String enterNumber()
{
System.out.println("Enter an operator and a number:");
String toString = keyboard.nextLine();
return toString;
}
public static void main (String[] args) {
// the calculator is initialized at 0
Calculator a = new Calculator(0);
// now I create a second calculator with the result from the aResult()
Calculator b = new Calculator(a.aResult(a));
// why is b.getNumber() = 0 at this point?
String theString = String.valueOf(b.getNumber());
// prints 0 every time
System.out.println(theString);
}
}
There are some mistakes in your code.
public double aResult(Calculator other)
{
other = new Calculator(getNumber());
other.whatOperator();
this.result = result;
return result;
}
The line this.result = result doesn't make any sense. I think you wanted the method whatOperator() to return a result e.g.
this.result = other.whatOperator();
I also think that you don't want to override the "other" calculator. You never use the new calculator. But you want to print the output of the new calculator in your main method. Because you never used the new calculator, the output is 0.
In your aResult method you are initiating another new instance of Calculator
public double aResult(Calculator other) {
//other = new Calculator(getNumber()); // this should not be here
other.whatOperator();
this.result = result;
return result;
}
The solution to the problem:
//change
this.result = result; //this does nothing
//to
this.result = other.result; //this changes the result to the new value
//erase this line
other = new Calculator(getNumber()); // do not need to create a new calculator
change the method whatOperator to a double and return a double with it

How can I scan a string for only four specific characters?

I want the user to input a DNA sequence, if it doesn't have the letters A, C, T, or G then it should print out an error. But how can I scan the string entered for those specific characters in the constructot method DNASequence?
heres what I have so far.
import java.util.*;
public class DNASequence {
private String DNASequence;//create a private static variable that can be accessed
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("Please input a sequence of DNA: ");
String DNAInput = input.nextLine();
}
public DNASequence(String DNAStrand){//Constructor Method that takes parameter a string and checks to see if its only A, T, C, G.
DNASequence = DNAStrand;
// Invoke the countLetters method to count each letter
int[] counts = countLetters(DNAStrand.toUpperCase());
// Display results
for (int i = 0; i < counts.length; i++) {
if (counts[i] != 0)
System.out.println((char)('a' + i) + " appears " +
counts[i] + ((counts[i] == 1) ? " time" : " times"));
}
}
/** Count each letter in the string */
public static int[] countLetters(String s) {
int[] counts = new int[26];
for (int i = 0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i)))
counts[s.charAt(i) - 'a']++;
}
return counts;
}
public String toString(){//Method that just returns the stored sequence
return DNASequence;
}
private static char NucleotideBaseCount(char BaseCount){//Method to count bases
}
private static boolean isSubsequenceOf(String DNAStrand){
}
}
You could use the following regular expression for this: ^[ACTG]+$.
To match the input string against the regex, use String.matches().
Here in a sample implementation based on #NPE 's comment:
import java.util.*;
public class DNASequence
{
private String DNASequence = null; //create a private static variable that can be accessed
public static void main(String[] args)
{
System.out.println("Please input a sequence of DNA: ");
DNASequence dnaS = new DNASequence((new Scanner(System.in)).nextLine().toUpperCase());
}
//Constructor Method that takes parameter a string and checks to see if its only A, T, C, G.
public DNASequence(String DNAStrand) throws IllegalArgumentException
{
if (DNAStrand.matches("^[ATCG]+$"))
{
DNASequence = DNAStrand;
}
else
{
throw new IllegalArgumentException("DNA Sequences should only contain A, T, C, G charaters");
}
}
/** Count each letter in the string */
public int[] countLetters() throws IllegalArgumentException
{
int[] counts = new int[4];
if (DNASequence != null)
{
for (int i = 0; i < DNASequence.length(); i++)
{
switch (DNASequence.charAt(i))
{
case 'A':
counts[0]++;
break;
case 'T':
counts[1]++;
break;
case 'C':
counts[2]++;
break;
case 'G':
counts[3]++;
break;
default:
throw new IllegalArgumentException("DNA Sequences should only contain A, T, C, G charaters, found: " + DNASequence.charAt(i));
}
}
}
return counts;
}
//Method that just returns the stored sequence
public String toString()
{
return DNASequence;
}
private char NucleotideBaseCount(char BaseCount){//Method to count bases
return 'a'; // replace with real implementation
}
private boolean isSubsequenceOf(String DNAStrand)
{
return false; // repalce with real implementation
}
}

Postfix evaluation in java with stack

I made this program that evaluates a postfix expression.
It works fine if only single digit numbers are used.
My problem is how do I push multiple-digit numbers if input has spaces?
ex. input: 23+34*- output is -7
but if I input: 23 5 + output is only 3(which is the digit before the space)
it should have an output of 28
my codes:
public class Node2
{
public long num;
Node2 next;
Node2(long el, Node2 nx){
num = el;
next = nx;
}
}
class stackOps2
{
Node2 top;
stackOps2(){
top = null;
}
public void push(double el){
top = new Node2(el,top);
}
public double pop(){
double temp = top.num;
top = top.next;
return temp;
}
public boolean isEmpty(){
return top == null;
}
}
public class ITP {
static stackOps2 so = new stackOps2();
public static final String operator = "+-*/^";
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the infix:");
String s = input.next();
String output;
InToPost theTrans = new InToPost(s);
output = theTrans.doTrans();
System.out.println("Postfix is " + output + '\n');
System.out.println(output+" is evaluated as: "+evaluate(output));
}
public static double evaluate(String value)throws NumberFormatException{
for(int i=0;i<value.length();i++){
char val = value.charAt(i);
if(Character.isDigit(value.charAt(i))){
String v = ""+val;
so.push(Integer.parseInt(v));
}
else if(isOperator(val)){
double rand1=so.pop();
double rand2=so.pop();
double answer ;
switch(val){
case '+': answer = rand2 + rand1;break;
case '-': answer = rand2 - rand1;break;
case '*': answer = rand2 * rand1;break;
case '^': answer = Math.pow(rand2, rand1);break;
default : answer = rand2 / rand1;break;
}
so.push(answer);
}
else if(so.isEmpty()){
throw new NumberFormatException("Stack is empty");
}
}
return so.pop();
}
public static boolean isOperator(char ch){
String s = ""+ch;
return operator.contains(s);
}
}
This is a small, self-contained example that does all the string parsing and evaluation. The only difference from your example is that it accepts the whole string at once instead of using a Scanner. Note the use of Integer.parseInt -- that's missing in your example. I think you can easily extend this for your needs.
#SuppressWarnings({"rawtypes", "unchecked"})
public static void main(String[] args) {
final String in = "5 9 + 2 * 6 5 * +";
final Deque<Object> s = new LinkedList();
for (String t : in.split(" ")) {
if (t.equals("+")) s.push((Integer)s.pop() + (Integer)s.pop());
else if (t.equals("*")) s.push((Integer)s.pop() * (Integer)s.pop());
else s.push(Integer.parseInt(t));
}
System.out.println(s.pop());
}

Calculator without if/else or switch

I am trying to write calculator for + - * / without conditions. The operator is stored as a string.
Is there anyway to achieve it?
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
////String Operator = "";
String L1="";
String L2="";
String op = "+";
double a = 3;
double b = 2;
//Operator p = p.
Operator p;
b = Operator.count(a, op, b);
System.out.println(b);
}
public enum Operator {
PLUS("+"), MINUS("-"), DIVIDE("/"), MULTIPLY("*");
private final String operator;
public static double count(double a,String op,double b) {
double RetVal =0;
switch (Operator.valueOf(op)) {
case PLUS:
RetVal= a + b;
case MINUS:
RetVal= a - b;
case DIVIDE:
RetVal= a / b;
case MULTIPLY:
RetVal= a * b;
}
return RetVal;
}
Operator(String operator) {
this.operator = operator;
}
// uniwersalna stała grawitacyjna (m3 kg-1 s-2)
}
}
Got this error:
Exception in thread "main" java.lang.IllegalArgumentException: No enum const class Main$Operator.+
Any clues?
You could use a strategy pattern and store a calculation strategy for each operator.
interface Calculation {
double calculate(double op1, double op2);
}
class AddCalculation implements Calculation {
double calculate(double op1, double op2) {
return op1 + op2;
}
}
//others as well
Map<String, Calculation> m = ...;
m.put("+", new AddCalculation());
During execution you then get the calculation objects from the map and execute calculate().
i think using an enum would be a nice option:
Enum Operation{
PLUS("+")
MINUS("-")
DIVIDE("/")
MULTIPLY("*")
}
then you could go with
switch(Operation.valueOf(userInputString)){
case PLUS: return a+b;
case MINUS: return a-b;
case DIVIDE: return a/b;
case MULTIPLY: return a*b;
}
how about hashing? Hash the operators as a key-value pair ("+": +). For the string operatory, hash it and grab the value. Experiment with that
As mentioned by Peter Lawrey, ScriptEngine/JavaScript might be a good choice for this. Visit this little JavaScript interpreter applet to explore the possibilities.

Console based command processing: Mapping string to enum in java

For my java console application, I need to call a set of functions with user given arguments. My operations O1, O2, .. O5 are defined as an enum as
enum Operations {O1, O2, O3, O4, O5};
I need to read user input args[0] and call function F1, F2,...F5.
For example user is going to give:
>java MyApp O1 5 6
For this I suppose I need to map sting (args[0]) to an enum so that I can use switch select. How to do this?
Enum.valueOf(Class, String).
Example
Operations oper = Enum.valueOf(Operations.class, args[0]);
Will throw an exception if there are no enum values that matches args[0]
I suppose using what chuk lee 's lead you can come up with pritty cool program
here what I did.
public class Main {
public static void main(String[] args) {
if(args.length < NUMBER_OF_OPERATORS){
throw new IllegalArgumentException(INSUFFICIENT_OPERANDS);
}
Operator operator = Enum.valueOf(Operator.class,
args[OPERATION_NAME].toUpperCase());
System.out.println(operator.operate(args[FIRST_OPERAND],
args[SECOND_OPERAND]));
}
private enum Operator {
ADD,SUBSTRACT,MULTIPLY,DIVIDE;
public String operate(String aString, String bString) {
int a = Integer.valueOf(aString);
int b = Integer.valueOf(bString);
int out = 0;
switch(this) {
case ADD : out = a + b; break;
case SUBSTRACT : out = a - b; break;
case MULTIPLY : out = a * b; break;
case DIVIDE : out = a / b; break;
default: throw new UnsupportedOperationException();
}
return String.valueOf(out);
}
}
private static final int NUMBER_OF_OPERATORS = 3;
private static final int OPERATION_NAME = 0;
private static final int FIRST_OPERAND = 1;
private static final int SECOND_OPERAND = 2;
private static final String INSUFFICIENT_OPERANDS =
"Insufficient operads to carry out the operation.";
}

Categories

Resources