Ai
2 Star 0 Fork 0

Paparazzi/软工结对编程

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Arithmetic.java 11.86 KB
一键复制 编辑 原始数据 按行查看 历史
Paparazzi 提交于 2018-03-25 14:53 +08:00 . 修改
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
package szys;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
class Rational {
private long m_up;
private long m_down;
public Rational() {
}
public Rational(long up, long down) {
super();
// 约分
long g = gcd(up >= 0 ? up : -up, down > 0 ? down : -down);
this.m_up = up / g;
this.m_down = down / g;
}
public long getM_up() {
return m_up;
}
public long getM_down() {
return m_down;
}
private static long gcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
public Rational add(Rational r) {
long up = m_up * r.m_down + m_down * r.m_up;
long down = m_down * r.m_down;
return new Rational(up, down);
}
public Rational subtract(Rational r) {
long up = m_up * r.m_down - m_down * r.m_up;
long down = m_down * r.m_down;
return new Rational(up, down);
}
public Rational multiply(Rational r) {
long up = m_up * r.m_up;
long down = m_down * r.m_down;
return new Rational(up, down);
}
//不会有除0错误,哇哈哈哈!!!
public Rational divide(Rational r) {
long up = m_up * r.m_down;
long down = m_down * r.m_up;
return new Rational(up, down);
}
private static long quickPow(long a, int n) {
long res = 1;
while (n > 0) {
if ((n & 1) == 1) {
res *= a;
}
a *= a;
n >>= 1;
}
return res;
}
public Rational pow(int n) {
return new Rational(quickPow(m_up, n), quickPow(m_down, n));
}
@Override
public String toString() {
if (m_down < 0) {
m_up = -m_up;
m_down = -m_down;
}
return m_up + (m_down == 1 ? "" : "/" + m_down);
}
}
class Node {
private String val;
private Node left, right;
public Node() {
val = null;
left = right = null;
}
public Node(String val, Node left, Node right) {
super();
this.val = val;
this.left = left;
this.right = right;
}
public String getVal() {
return val;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
}
//比较两个最小表示法字符串的大小
class MinPreFormatComparator implements Comparator<MinPreFormat> {
@Override
public int compare(MinPreFormat o1, MinPreFormat o2) {
ArrayList<String> list1 = o1.getVal();
ArrayList<String> list2 = o2.getVal();
int lim = Math.min(list1.size(), list2.size());
for (int i = 0; i < lim; i++) {
if (!list1.get(i).equals(list2.get(i))) {
return list1.get(i).compareTo(list2.get(i));
}
}
return list1.size() - list2.size();
}
}
class MinPreFormat {
private ArrayList<String> val;
public MinPreFormat() {
}
public MinPreFormat(ArrayList<String> val) {
this.val = val;
}
public ArrayList<String> getVal() {
return val;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((val == null) ? 0 : val.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MinPreFormat other = (MinPreFormat) obj;
if (val == null) {
if (other.val != null)
return false;
} else if (!val.equals(other.val))
return false;
return true;
}
}
class ExpAndAns {
String exp;
Rational ans;
public String getExp() {
return exp;
}
public Rational getAns() {
return ans;
}
public ExpAndAns() {
}
public ExpAndAns(String exp, Rational ans) {
super();
this.exp = exp;
this.ans = ans;
}
}
public class Arithmetic {
private static int count(char c) {
if (c == '=')
return 0;
if (c == '(')
return 1;
if (c == '+')
return 2;
if (c == '-')
return 3;
if (c == '*')
return 4;
if (c == '/')
return 5;
if (c == '^')
return 6;
return 7;
}
private static boolean isNum(String exp, int pos) {
char ch = exp.charAt(pos);
if (ch >= '0' && ch <= '9') {
return true;
}
return false;
}
private static String trans(String exp) {
// 负数都用括号括起来
for (int i = 0; i < exp.length(); i++) {
if (exp.charAt(i) == '-' && exp.charAt(i - 1) == '(') {
exp = exp.substring(0, i) + '0' + exp.substring(i, exp.length());
i++;
}
}
// System.out.println(exp);
String postexp = new String();
int lpri[] = { 0, 1, 3, 3, 5, 5, 7, 8 }; // =(+-*/^)
int rpri[] = { 0, 8, 2, 2, 4, 4, 6, 1 };
ArrayList<Character> op = new ArrayList<>();
op.add('=');
for (int i = 0; i < exp.length();) {
if (isNum(exp, i)) {
while (i < exp.length() && isNum(exp, i)) {
postexp += exp.charAt(i);
i++;
}
postexp += '#';
} else {
if (lpri[count(op.get(op.size() - 1))] < rpri[count(exp.charAt(i))]) {
op.add(exp.charAt(i));
i++;
} else if (lpri[count(op.get(op.size() - 1))] == rpri[count(exp.charAt(i))]) {
op.remove(op.size() - 1);
i++;
} else {
postexp += op.get(op.size() - 1);
op.remove(op.size() - 1);
}
}
}
while (!op.isEmpty() && op.get(op.size() - 1) != '=') {
postexp += op.get(op.size() - 1);
op.remove(op.size() - 1);
}
return postexp;
}
// 操作数不超过5个,操作符不超过4个,括号不超过3对,乘方只能有一个,而且次数只能小于等于3
private static final int MAX_NUMS = 5;
private static final int MIN_NUMS = 2;
private static final int MAX_PAIRS = 2;
private static String generateNewExp() {
// 产生基本的算式
String exp = new String();
Random random = new Random();
int nums = random.nextInt(MAX_NUMS - MIN_NUMS + 1) + MIN_NUMS;
int pairs = random.nextInt(MAX_PAIRS + 1);
HashMap<Integer, Integer> leftPosMap = new HashMap<>();
HashMap<Integer, Integer> rightPosMap = new HashMap<>();
for (int i = 0; i < nums; i++) {
leftPosMap.put(i + 1, 0);
rightPosMap.put(i + 1, 0);
}
for (int i = 0; i < pairs; i++) {
int leftPos = random.nextInt(nums) + 1;
int rightPos = random.nextInt(nums - leftPos + 1) + leftPos;
// System.out.println(leftPos + " " + rightPos);
leftPosMap.put(leftPos, leftPosMap.get(leftPos) + 1);
rightPosMap.put(rightPos, rightPosMap.get(rightPos) + 1);
}
boolean hasPow = false;
for (int i = 0; i < nums; i++) {
boolean needContinue = false;
if (i != 0) {
int op = random.nextInt(5);
switch (op) {
case 0:
exp += "+";
break;
case 1:
exp += "-";
break;
case 2:
exp += "*";
break;
case 3:
exp += "/";
break;
default:
if (hasPow) {
needContinue = true;
i--;
} else {
exp += "^";
hasPow = true;
}
break;
}
if (needContinue) {
continue;
}
}
int leftNums = leftPosMap.get(i + 1);
for (int j = 0; j < leftNums; j++) {
exp += "(";
}
if (exp.length() > leftNums && exp.charAt(exp.length() - leftNums - 1) == '^') {
int matchPos = i + 1;
for (int j = 0; j < leftNums; j++) {
exp = exp.substring(0, exp.length() - 1);
while (rightPosMap.get(matchPos) <= 0) {
matchPos++;
}
rightPosMap.put(matchPos, rightPosMap.get(matchPos) - 1);
}
exp += random.nextInt(4);
} else {
int generateNum = (random.nextInt(40) - 20);
if (generateNum < 0 && (leftPosMap.get(i + 1) == 0 || rightPosMap.get(i + 1) == 0)) {
exp += "(" + generateNum;
rightPosMap.put(i + 1, rightPosMap.get(i + 1) + 1);
} else {
exp += generateNum;
}
}
int rightNums = rightPosMap.get(i + 1);
for (int j = 0; j < rightNums; j++) {
exp += ")";
}
// System.out.println(exp);
}
return exp;
// 加括号
}
private static Rational calc(String postexp) {
ArrayList<Rational> st = new ArrayList<>();
// System.out.println(postexp);
for (int i = 0; i < postexp.length();) {
switch (postexp.charAt(i)) {
case '+':
Rational r1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
Rational r2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(r1.add(r2));
break;
case '-':
r1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
r2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(r2.subtract(r1));
break;
case '*':
r1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
r2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(r1.multiply(r2));
break;
case '/':
r1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
r2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(r2.divide(r1));
break;
case '^':
r1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
r2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(r2.pow((int) r1.getM_up()));
break;
default:
long num = 0;
while (i < postexp.length() && isNum(postexp, i)) {
num = num * 10 + postexp.charAt(i) - '0';
i++;
}
st.add(new Rational(num, 1));
break;
}
i++;
// for (Rational rational : st) {
// System.out.print(rational);
// System.out.print(" ");
// }
// System.out.println();
}
return st.get(st.size() - 1);
}
//产生除0的需要被T出
public static ArrayList<ExpAndAns> generateExps(int num) {
HashSet<MinPreFormat> hashSet = new HashSet<>();
ArrayList<ExpAndAns> res = new ArrayList<>();
for (int i = 0; i < num; i++) {
String exp = generateNewExp();
String postexp = trans(exp);
Node root = createExpTree(postexp);
MinPreFormat minPreFormat = minPre(root);
if (hashSet.contains(minPreFormat)) {
i--;
} else {
Rational ans = calc(postexp);
if (ans.getM_down() == 0) {
i--;
} else {
hashSet.add(minPreFormat);
res.add(new ExpAndAns(exp, ans));
}
}
}
return res;
}
private static Node createExpTree(String postexp) {
ArrayList<Node> st = new ArrayList<>();
for (int i = 0; i < postexp.length();) {
switch (postexp.charAt(i)) {
case '+':
Node nd1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
Node nd2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(new Node("+", nd2, nd1));
break;
case '-':
nd1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
nd2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(new Node("-", nd2, nd1));
break;
case '*':
nd1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
nd2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(new Node("*", nd2, nd1));
break;
case '/':
nd1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
nd2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(new Node("/", nd2, nd1));
break;
case '^':
nd1 = st.get(st.size() - 1);
st.remove(st.size() - 1);
nd2 = st.get(st.size() - 1);
st.remove(st.size() - 1);
st.add(new Node("^", nd2, nd1));
break;
default:
String num = new String();
while (i < postexp.length() && isNum(postexp, i)) {
num += postexp.charAt(i);
i++;
}
st.add(new Node(num, null, null));
break;
}
i++;
}
return st.get(st.size() - 1);
}
private static MinPreFormat minPre(Node root) {
if (root == null) {
return null;
}
MinPreFormat LeftMinPre = minPre(root.getLeft());
MinPreFormat RightMinPre = minPre(root.getRight());
ArrayList<String> rootStrings = new ArrayList<>();
rootStrings.add(root.getVal());
MinPreFormat res = new MinPreFormat(rootStrings);
MinPreFormatComparator minPreFormatComparator = new MinPreFormatComparator();
if (LeftMinPre != null && RightMinPre != null) {
if ((root.getVal().equals("+") || root.getVal().equals("*"))
&& minPreFormatComparator.compare(LeftMinPre, RightMinPre) < 0) {
res.getVal().addAll(RightMinPre.getVal());
res.getVal().addAll(LeftMinPre.getVal());
} else {
res.getVal().addAll(LeftMinPre.getVal());
res.getVal().addAll(RightMinPre.getVal());
}
} else {
if (LeftMinPre != null) {
res.getVal().addAll(LeftMinPre.getVal());
}
if (RightMinPre != null) {
res.getVal().addAll(RightMinPre.getVal());
}
}
return res;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/huangsh1/software_pair_programming.git
git@gitee.com:huangsh1/software_pair_programming.git
huangsh1
software_pair_programming
软工结对编程
master

搜索帮助