一、字符串表达式计算
如 1+(2-2*3)
package TcpIO;
import java.util.Deque;
import java.util.LinkedList;
public class StringCalculate {
static int getPriority(char ch){
if(ch=='(') return 1;
if(ch=='+' || ch=='-') return 2;
if(ch=='*' || ch=='/') return 3;
return 4;
}
static void calculate(Deque<Integer> numStk,char opr){
int num2=numStk.pop();
int num1=numStk.pop();
int res=0;
if(opr=='+'){
res=num1+num2;
}else if(opr=='-'){
res=num1-num2;
}else if(opr=='*'){
res=num1*num2;
}else if(opr=='/'){
res=num1/num2;
}
numStk.push(res);
return;
}
public static void main(String[] args) {
String s = "1+23*4-(5+6)";
char[] arr = s.toCharArray();
Deque<Integer> numStack = new LinkedList<>();
Deque<Character> oprStack = new LinkedList<>();
int i = 0;
int strLength = s.length();
char tmpOpr;
boolean negative = false;
// char first = s.charAt(1);
if(arr[0] == '-'){
i = 1;
negative = true;
}
while(i < strLength){
if(i !=0 && arr[i] == '-' && arr[i-1] != ')' && (arr[i-1] < '0' || arr[i - 1] > '9')){
negative = true;
i++;
continue;
}
if(arr[i]>='0' && arr[i]<='9'){
int tmpNum = 0;
while(i < strLength && arr[i]>='0' && arr[i]<='9'){
tmpNum = 10 * tmpNum + arr[i] - '0';
i++;
}
if(negative){
tmpNum *= -1;
negative = false;
}
numStack.push(tmpNum);
}
else if(arr[i] == '+' || arr[i] == '-' || arr[i]=='*' || arr[i]=='/'){
if (oprStack.isEmpty()){
oprStack.push(arr[i]);
}
else{
while(!oprStack.isEmpty()){
tmpOpr = oprStack.peek();
if(getPriority(tmpOpr) >= getPriority(arr[i])){
//calculate
calculate(numStack,tmpOpr);
oprStack.pop();
}else{
break;
}
}
oprStack.push(arr[i]);
}
i++;
}
else{
if (arr[i] == '('){
oprStack.push(arr[i]);
}
else{
while(oprStack.peek() != '('){
tmpOpr = oprStack.pop();
calculate(numStack, tmpOpr);
}
oprStack.pop();
}
i++;
}
}
while(!oprStack.isEmpty()){
tmpOpr = oprStack.pop();
calculate(numStack, tmpOpr);
}
System.out.println(numStack.peek());
}
}
二、n个字符(没有重复字符)选m个元素,生成所有排列,不能有重复字符,返回值按照字典序升序返回
融合 组合(剑指 Offer II 080. 含有 k 个元素的组合) 排列(剑指 Offer 38. 字符串的排列)两个题
注意排列解题思想 递归交换发生在回去的时候,逆向思想;
输入 n个字符 m
[0,1,2], 2
输出 ["01", "02", "10", "12", "20", "21"]
输入 [0,1,2,3,A], 3
输出 ["012","013","01A",....]
共60个不重复字符
package zsh;
import java.util.*;
public class Qianxing2 {
public static void main(String[] args) {
// List<Character> list = new ArrayList<>();
// list.add('0');
// list.add('1');
// list.add('2');
// String str = String.valueOf(list);
// permu(list);
// Collections.sort(res);
char[] seed = {'0', '1', '2', '3', 'A'};
int size = 3;
Combine (seed, size);
System.out.println(1);
}
static List<String> res = new LinkedList<>();
public static String[] Combine (char[] seed, int size) {
char[] arr = new char[size];
List<List<Character>> lists = new ArrayList<>();
dfsCombine(0, lists, new ArrayList<>(), seed, size);
for (int i = 0; i < lists.size(); i++) {
Permutation(lists.get(i));
}
Collections.sort(res); //按字典序
return res.toArray(new String[res.size()]);
}
static void dfsCombine(int index, List<List<Character>> lists, List<Character> listCom, char[] seed, int remain){
//当剩余需要添加的数的个数是0的时候,已经满足数据个数了,保存并结束方法
if(remain == 0){
lists.add(new ArrayList<>(listCom));
return;
}
//当index>n时,已经超出n的范围了,结束
if(index >= seed.length){
return;
}
for (int i = index; i <= seed.length - remain; i++) {
listCom.add(seed[i]);
dfsCombine(i+1, lists, listCom, seed,remain - 1);
listCom.remove(listCom.size() - 1);
}
}
//排列
public static void Permutation(List<Character> listPer){
dfsPermutation(0, listPer);
}
static void dfsPermutation(int index, List<Character> listPer){
if(index == listPer.size() - 1){
StringBuilder sb = new StringBuilder();
for (char c : listPer){
sb.append(c);
}
res.add(sb.toString()); // 添加排列方案
// res.add(String.valueOf(listPer));
return;
}
HashSet<Character> set = new HashSet<>();
for (int i = index; i < listPer.size(); i++) {
if(set.contains(listPer.get(i))){
continue; // 重复,因此剪枝
}
set.add(listPer.get(i));
swap(i, index, listPer); // 交换,将 c[i] 固定在第 x 位
dfsPermutation(index+1, listPer); // 开启固定第 x + 1 位字符
swap(i, index, listPer); // 恢复交换
}
}
static void swap(int a, int b, List<Character> list){
char temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
}
三、在字符串S中不重叠的“AB”和“BA”子串,找到返回true,否则返回false
例 “ABBA” true “ABA” false “ABABA” true
"ABAAB" true "BABBA" true
思路:正反两遍遍历字符串,避免出现ABAAB,正向遍历搜不出来的情况。
package zsh;
public class YiTu {
public static void main(String[] args) {
boolean res = substr("BAB");
System.out.println(res);
}
public static boolean substr(String str){
boolean flag1 = false;
boolean sign1 = false;
boolean flag2 = false;
boolean sign2 = false;
int len = str.length();
char[] chars = str.toCharArray();
for(int i = 0; i < len - 1; i++){
if(!flag1 && chars[i] == 'A' && chars[i+1] == 'B'){
flag1 = true;
i++;
}
else if(!sign1 && chars[i] == 'B' && chars[i+1] == 'A'){
sign1 = true;
i++;
}
}
for(int i = len-1; i > 0; i--){
if(!sign2 && chars[i] == 'A' && chars[i-1] == 'B'){
sign2 = true;
i--;
}
else if(!flag2 && chars[i] == 'B' && chars[i-1] == 'A'){
flag2 = true;
i--;
}
}
return (sign1 && flag1) || (sign2 && flag2);
}
}