I'm trying to create a method that would create an equation for me, as a String.
For example, this method would create:
String formula = "5 + 3";
then another method will solve it.
I don't really know how to create the string. Should i use concat?
Thanks for all the help.
public static String getEquation() {
for(int i=0;i<7;i++){
int rand = rng.nextInt(5);
switch (rand) {
case 0:
operator = "+";
break;
case 1:
operator = "-";
break;
case 2:
operator = "*";
break;
case 3:
operator = "/";
break;
case 4:
operator = "(";
break;
case 5:
operator = ")";
}
}
return formula;
}
Wrote something up really quick, I think this should get you going. You'd have to handle the cases for parentheses though. I didn't account for that.
import java.util.Random;
public class Test {
static Random randomGenerator = new Random();
static String operators = "+-*/P"; //p = parentheses pair
public static char getRandomOperator() {
return operators.charAt(randomGenerator.nextInt(operators.length()));
}
public static int getRandomNumber() {
return randomGenerator.nextInt(100);
}
public static String createEquation() {
//Just for proof of concept, let's do 3 operators
String equation = "";
int numOfOperators = 3;
char operator = ' ';
for (int i = 0; i < numOfOperators; i++) {
equation += getRandomNumber();
equation += getRandomOperator();
}
equation += getRandomNumber();
return equation;
}
public static void main(String[] args) {
String equation = createEquation();
System.out.println(equation);
}
}
I may have time later and come back and address the parentheses issue. For now I just print 'P' where parentheses should be handled.
EDIT
Updated it to handle parentheses. I'm going to paste it down here in case you want to keep it as the old way. Also did a couple tweaks here and there. Note that I didn't handle it matching an exact number of operators when it comes to parenthesis. Which means that if all the open parenthesis weren't closed by the time the loop is done grabbing operators then I append extra parenthesis at the end. Which can result in more than 7 operators. You should probably add logic to either treat a pair of parenthesis as 1 operator or 1 parenthesis as a single operator. Enjoy.
import java.util.Random;
public class Test {
static Random randomGenerator = new Random();
static String operators = "+-*/()";
static int opeatorStringLength = operators.length();
public static char getRandomOperator() {
return operators.charAt(randomGenerator.nextInt(opeatorStringLength));
}
public static int getRandomNumber() {
return randomGenerator.nextInt(100);
}
public static String appendToEquation(String equation, String value1, String value2) {
String temp = equation;
temp += value1;
temp += value2;
return temp;
}
public static String createEquation(int numOfOperators) {
String equation = "";
char operator;
int operand;
int openParenCounter = 0;
for (int i = 0; i < numOfOperators; i++) {
operator = getRandomOperator();
operand = getRandomNumber();
if (operator == '(') {
openParenCounter++;
equation = appendToEquation(equation, Character.toString(operator), Integer.toString(operand));
} else if (operator == ')') {
if (openParenCounter == 0) { //Can't start off with a close parenthesis
openParenCounter++;
equation = appendToEquation(equation, "(", Integer.toString(operand));
} else {
openParenCounter--;
equation = appendToEquation(equation, Integer.toString(operand), Character.toString(operator));
}
} else {
equation = appendToEquation(equation, Integer.toString(operand), Character.toString(operator));
}
}
equation += getRandomNumber();
while (openParenCounter > 0) {
equation += ")";
openParenCounter--;
}
return equation;
}
public static void main(String[] args) {
String equation;
equation = createEquation(7); //The argument passed is the number of operators to use
System.out.println(equation);
}
}
Related
I have this homework in my school where I need to separate the numbers and the letters and print them apart. My problem is I can only return one value which is the number not the letters in my if/else statement, I need to return both values so I can print the numbers and the letters separately.
Any suggestion on how I could do it with only one method?
public static String Separation(String output) {
String number = "";
String letter = "";
for (int i = 0; i < output.length(); i++) {
char x = output.charAt(i);
if (Character.isDigit(x)) {
number += x;
} else {
letter += x;
}
}
return number;
}
You could do things like:
return an array of String: return new String[] { number, letter };
or return a List of String: return Arrays.asList(number, letter)
Or, more OOP: you create a small class that holds two Strings, like:
class Entry {
String number;
String letter;
...
and then you return an instance of that class. Of course, you have to adapt the signature of your method accordingly, to use the desired return type instead of public String ....
… I need to separate the numbers and the letters and print them apart.
Do you really need a static method that returns something?
public class WTF {
String number;
String letter;
public void separation(String output) {
number = "";
letter = "";
for (int i = 0; i < output.length(); i++) {
char x = output.charAt(i);
if (Character.isDigit(x)) {
number += x;
} else {
letter += x;
}
}
}
public static void main(String args[]) {
WTF wtf = new WTF();
wtf.separation("2 to 5 the jury decides");
System.out.println(wtf.number + " " + wtf.letter);
}
}
public class Result {
private String number;
private String letter;
public Result(String number, String letter) {
this.number = number;
this.letter = letter;
}
public void setNumber(String number) {
this.number = number;
}
public void setLetter(String letter) {
this.letter = letter;
}
public String getNumber() {
return number;
}
public String getLetter() {
return letter;
}
}
then
public static Result Separation(String output) {
String number = "";
' String letter = "";
for (int i = 0; i < output.length(); i++) {
char x = output.charAt(i);
if (Character.isDigit(x)) {
number += x;
} else {
letter += x;
}
}
return new Result(number, letter);
}
Edited:
Change from c# to java
You can use two separate lists, one for numbers and other for letters.
I am trying to convert an expression given as a String into an Integer. For ex. if given "1+5*5" the method should return "26". I started writing the code only for solving a multiplication, however, when I run it there is not an output
public static void operationS(ArrayList<String> m)
{
for (int i=0; i<m.size(); i++)
{
while ( (m.get(i)).contains("*"))
{
int x = ((m.get(i)).indexOf("*"));
char A=((m.get(i)).charAt(x-1));
char B= ((m.get(i)).charAt(x+1));
int r= Character.getNumericValue(A)*Character.getNumericValue(B);
String numberAsString = Integer.toString(r);
if(x==1 && (m.get(i)).length()==3)
{
m.set(i, numberAsString);
}
if(x==1 && (m.get(i)).length()>3)
{
String n = numberAsString+((m.get(i)).substring(x+2));
m.set(i, n);
}
else
{
String k= ((m.get(i)).substring(0,x-1))+numberAsString+((m.get(i)).substring(x+2));
}
}
}
for (int u=0;u<m.size();u++)
{
System.out.println (m.get(u));
}
}
Since I cannot import any libraries, my plan of action was replacing the String every time an operation was completed.
I plan on using the same loop for adding, subtracting and dividing
Consider parsing your expression. You can probably use an Prefix, Infix, or Postfix notation and parsing to evaluate the input expression.
I came across an article that can help you in understanding how to achieve this:
http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html
The article basically talks about different approaches to solve this problem.
I personally liked the recursive approach. So if you understand recursion, you can choose that.
But if you have a requirement to use only a loop, you may prefer one of the other approaches.
Update: Adding a sample piece of code implementing recursion based on the article linked above.
static final char[] ops = { '-', '+', '*', '/'};
static double evaluate(String s){
for(char op: ops) {
if(s.contains(String.valueOf(op))){
String op1 = s.substring(0, s.indexOf(op));
String op2 = s.substring(s.indexOf(op) + 1, s.length());
switch(op) {
case '-': return evaluate(op1) - evaluate(op2);
case '+': return evaluate(op1) + evaluate(op2);
case '*': return evaluate(op1) * evaluate(op2);
case '/': return evaluate(op1) / evaluate(op2);
}
}
}
/* at this point there is no operator in the term anymore, just a number */
return (convertToDouble(s));
}
private static double convertToDouble(String s) {
return Double.parseDouble(s);
}
Try this.
static String replaceAll(CharSequence cseq, String regex, Function<MatchResult, String> replacement) {
Matcher matcher = Pattern.compile(regex).matcher(cseq);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String replaced = replacement.apply(matcher.toMatchResult());
matcher.appendReplacement(sb, Matcher.quoteReplacement(replaced));
}
matcher.appendTail(sb);
return sb.toString();
}
static int toInt(String s) {
return Integer.parseInt(s);
}
And
String input = "1 + 5 * 5";
String output = input;
while (true) {
String r = replaceAll(output, "(\\d+)\\s*\\*\\s*(\\d+)",
m -> "" + (toInt(m.group(1)) * toInt(m.group(2))));
if (r.equals(output)) break;
output = r;
}
while (true) {
String r = replaceAll(output, "(\\d+)\\s*\\+\\s*(\\d+)",
m -> "" + (toInt(m.group(1)) + toInt(m.group(2))));
if (r.equals(output)) break;
output = r;
}
System.out.println(input + " -> " + output);
result:
1 + 5 * 5 -> 26
I'm writing a short program which be able to generate 5 digits code mixed with 0-9, a-z, A-Z.
This is my code:
import java.util.*;
public class FiveDigitsRandom
{
public static void main(String[] args)
{
new FiveDigitsRandom().use();
}
public void use()
{
char choice;
while((choice=readChar()) != 'x')
{
switch(choice)
{
case'n':
generateAll();
break;
}
}
}
public char readChar()
{
System.out.print("Please choose n/x: ");
Scanner scanner = new Scanner(System.in);
return scanner.nextLine().charAt(0);
}
public void generateAll()
{
String[]code = new String[5];
for(int i=0; i<code.length; i++)
{
int random = generate0_2();
switch(random)
{
case 0:
code[i] = generate0_9();
break;
case 1:
code[i] = generate_a_z();
break;
case 2:
code[i] = generate_A_Z();
break;
}
}
for(int j=0; j<code.length; j++)
{
System.out.print(code[j]);
}
System.out.println(" ");
}
public int generate0_2()
{
return (int)Math.random()*3;
}
public String generate0_9()
{
int a = (int)(Math.random() * 10);
String AA = Integer.toString(a);
return AA;
}
public String generate_a_z()
{
char a = (char)((int)'a'+ Math.random() * ((int)'z' - (int)'a' + 1));
String AA = Character.toString(a);
return AA;
}
public String generate_A_Z()
{
char a = (char)((int)'A'+ Math.random() * ((int)'Z' - (int)'A' + 1));
String AA = Character.toString(a);
return AA;
}
}
It suppose to generate a random code as 0AzhG, Hg78N. But now I can only have 5 digits code with random number 0-9. Please tell me where is wrong in my code??
Thank you!
Your generate0_2 method is wrong.
public int generate0_2()
{
return (int)Math.random()*3;
}
When you cast it to int, it works like ((int)Math.random)*3 which means, it provides 0 every time.
change it to
public int generate0_2()
{
return (int)(Math.random()*3);
}
A problem you have is that your won't have an even distribution. i.e. individual digits are more likely than individual letters. One way to have an even distribution is you have an even function.
public static char randomChar() {
// random.nextInt(62) would be faster.
int n = (int) (Math.random() * 62);
if (n < 10) return (char) ('0' + n);
n -= 10;
if (n < 26) return (char) ('A' + n);
n -= 26;
return (char) ('a' + n);
}
public static String randomString(int length) {
char[] chars = new char[length];
for (int i = 0; i < length; i++)
char[i] = randomChar();
return new String(chars);
}
Maybe it's easely to use RandomStringUtils
import org.apache.commons.lang3.RandomStringUtils;
class Main {
public static void main(String[] args) {
// Prints only A-Z, a-z, 0-9
System.out.println(RandomStringUtils.randomAlphabetic(5));
// Prints only A-Z, a-z
System.out.println(RandomStringUtils.randomAlphanumeric(5));
}
}
This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 5 years ago.
I have this homework in Java where I have to convert an infix string without parenthesis to a postfix string. I've been tinkering with the code from two days but I haven't been able to catch the bug. Here's my code.
public class itp
{
String exp, post;
double res;
int l;
stack st;
public itp(String s)
{
exp = s;
post = "";
l = exp.length();
st = new stack(l);
conv();
calc();
System.out.println("The postfix notation of "+exp+" is "+post);
System.out.println("The result of "+exp+" is "+res);
}
public void conv()
{
char ch = ' ';
char pre = ' ';
for(int i =0;i<l;i++)
{
ch = exp.charAt(i);
if("+-*/".indexOf(ch)==-1)post = post + ch;
else
{
pre = st.pop();
if(val(ch)>=val(pre))
{
st.push(pre);
st.push(ch);
}
else
{
while((val(ch)<=val(pre))&&(pre!='$'))
{
post = post + pre;
pre = st.pop();
}
st.push(ch);
}
}
}
for(pre = st.pop();pre!='$';pre = st.pop())
{
post = post + pre;
}
}
public void calc()
{
res = 0.0;
}
public int val(char c)
{
switch(c)
{
case '$' : return 0;
case '+' : return 1;
case '-' : return 2;
case '*' : return 3;
case '/' : return 4;
default : return -1;
}
}
}
Here, the variables are as follows:
st is a character stack
ch is the current character
pre is the topmost char on the stack
exp is the input infix expression
post is the output postfix expression
The pop() methods works as expected except when the stack is empty, where it will return $. The function val() takes a char input and returns 4 for /, 3 for *. 2 for -. 1 for +. The integer l holds the length of exp.
It works well in most cases except when I give it a string like a*b-b*c+c*d-d*e where it outputs ab*bc*-cd*de*- which is the expected output without a + in the end.
Any advice would be much appreciated. This bug is making me crazy!
Here's the entire code:
public class itp
{
String exp, post;
double res;
int l;
stack st;
public itp(String s)
{
exp = s;
post = "";
l = exp.length();
st = new stack(l);
conv();
calc();
System.out.println("The postfix notation of "+exp+" is "+post);
System.out.println("The result of "+exp+" is "+res);
}
public void conv()
{
char ch = ' ';
char pre = ' ';
for(int i =0;i<l;i++)
{
ch = exp.charAt(i);
if("+-*/".indexOf(ch)==-1)post = post + ch;
else
{
pre = st.pop();
if(val(ch)>=val(pre))
{
st.push(pre);
st.push(ch);
}
else
{
while((val(ch)<=val(pre))&&(pre!='$'))
{
post = post + pre;
pre = st.pop();
}
st.push(ch);
}
}
}
for(pre = st.pop();pre!='$';pre = st.pop())
{
post = post + pre;
}
}
public void calc()
{
res = 0.0;
}
public int val(char c)
{
switch(c)
{
case '$' : return 0;
case '+' : return 1;
case '-' : return 2;
case '*' : return 3;
case '/' : return 4;
default : return -1;
}
}
}
here's the stack class:
public class stack
{
char[] a;
int top,size;
public stack(int s)
{
size = s;
a = new char[size];
top = -1;
}
public void push(char el)
{
a[++top] = el;
}
public char pop()
{
if(empty()) return '$';
else return a[top--];
}
public boolean empty()
{
return (top == -1);
}
}
Here's the main class
import java.util.Scanner;
class client
{
public static void main(String args[])
{
System.out.println("Enter the expression");
Scanner in = new Scanner(System.in);
itp i = new itp(in.next());
}
}
First of all the post fix of a*b-b*c+c*d-d*e is not ab*bc*-cd*de*-+ but ab*bc*-cd*+de*-.
Secondly the mistake is in your val() function. It should instead be :
case '$' : return 0;
case '+' : return 1;
case '-' : return 1;
case '*' : return 2;
case '/' : return 2;
default : return -1;
Change it and check. It will certainly work.
Hey Guys I'm having a problem when I run my program. In the PostfixEvaluate() Method is where it takes in a string and solves the postfix problem and returns it. Well when I go to run it, I'm getting a bunch of random numbers(some repeated), I'm going crazy because I don't know what else to try and I've spent more time on this than it should normally take.
Heres the PostfixEvaluate Method:
public int PostfixEvaluate(String e){
//String Operator = "";
int number1;
int number2;
int result=0;
char c;
//number1 = 0;
//number2 = 0;
for(int j = 0; j < e.length(); j++){
c = e.charAt(j);
if (c != '+'&& c!= '*' && c!= '-' && c!= '/') {
//if (c == Integer.parseInt(e)) {
s.push(c);
}
else {
number1 = s.pop();
number2 = s.pop();
switch(c) {
case '+':
result = number1 + number2;
break;
case '-':
result = number1 - number2;
break;
case '*':
result = number1 * number2;
break;
case '/':
result = number1 / number2;
break;
} s.push(result);
}
System.out.println(result);
}
return s.pop();
}
public static void main(String[] args) {
Stacked st = new Stacked(100);
String y = new String("(z * j)/(b * 8) ^2");
String x = new String("2 3 + 9 *");
TestingClass clas = new TestingClass(st);
clas.test(y);
clas.PostfixEvaluate(x);
}
}
This is the Stack Class:
public class Stacked {
int top;
char stack[];
int maxLen;
public Stacked(int max) {
top = -1;
maxLen = max;
stack = new char[maxLen];
}
public void push(int result) {
top++;
stack[top] = (char)result;
}
public int pop() {
int x;
x = stack[top];
//top = top - 1;
top--;
return x;
}
public boolean isStackEmpty() {
if(top == -1) {
System.out.println("Stack is empty " + "Equation Good");
return true;
}
else
System.out.println("Equation is No good");
return false;
}
public void reset() {
top = -1;
}
public void showStack() {
System.out.println(" ");
System.out.println("Stack Contents...");
for(int j = top; j > -1; j--){
System.out.println(stack[j]);
}
System.out.println(" ");
}
public void showStack0toTop() {
System.out.println(" ");
System.out.println("Stack Contents...");
for(int j=0; j>=top; j++){
System.out.println(stack[j]);
}
System.out.println(" ");
}
}
It looks to me like you aren't handling spaces at all.
This means that when you put in a space, it is implicitly converting the character space to the ascii value of it (32) when it pops it off the stack during an operation. Also, it looks like you are assuming that all numbers/results will be single digit, and casting from char to int, which is not what you want to do, since that will convert the char to the ascii value of the char, ' ' -> 32, '3' -> 51, etc.
If I were you, I would do this for your loop in PostfixEvaluate:
while(!e.equals("")){
string c;
int space = e.indexOf(' ');
if(space!=-1){
c = e.substring(0,space);
e = e.substring(space+2);
} else{
c = e;
e = "";
}
if (!c.equals("+")&& !c.equal("*") && !c.equals("-") && !c.equals("/")) {
//...
}
and change your stack to hold strings or ints.
The problem is that you are pushing char onto a stack as an int, so you are unintentionally working with the ascii representations of numbers, which is not the actual value of the number.
Instead of this complicated character walking, tokenize the input string using String.split(). Example:
String[] tokens = e.split(" ");
for(String token:tokens){
if (!"+".equals(token) && !"*".equals(token) && !"-".equals(token) && !"/".equals(token)) {
s.push(Integer.parseInt(token));
} else {
....
}
}
You need to split the string into tokens first:
/* Splits the expression up into several Strings,
* all of which are either a number or and operator,
* none of which have spaces in them. */
String [] expressionAsTokens = e.split(" ");
Then you need to make sure you compare Strings, not chars:
//compare strings instead of chars
String token = expressionAsTokens[j];
if (!"+".equals(token) && !"*".equals(token) && !"-".equals(token) && !"/".equals(token)) {
s.push(Integer.parseInt(token));
} else {
//same code as you had before
}
Also, is there any reason you are storing everything as a char array in your Stacked class? Your pop() method returns and integer, yet everything is stored as a char.
For this application, everything should be stored as an integer:
public class Stacked {
int stack[]; // array is of type integer
int top;
int maxLen;
// constructor
public void push() {/*...*/}
public int pop() {/*...*/} //pop returns an int as before
//...
}
One final note: Be careful what order you add and subtract the numbers in. I don't remember if postfix operands are evaluated left first or right first, but make sure you get them in the right order. As you have it now, 2 3 - 4 * would evaluate as 4 * (3 - 2) and I think it should be (2 - 3) * 4. This won't matter with adding and multiplying, but it will with subtracting and dividing.