一、全量字符集与已占用字符集
输入描述:
输入一个字符串,字符串中包含了全量字符集和已占用字符集,两个字符集用@相连。@前的字符集合为全量字符集,@后的字符集为已占用字符集合。已占用字符集中的字符一定是全量字符集中的字符。字符集中的字符跟字符之间使用英文逗号分隔。字符集中的字符表示为字符加数字,字符跟数字使用英文冒号分隔,比如a:1,表示1个a字符。字符只考虑英文字母,区分大小写,数字只考虑正整形,数量不超过100,如果一个字符都没被占用,@标识符仍在,例如a:3,b:5,c:2@
输出描述:
可用字符集。输出带回车换行。
示例1:
输入:a:3,b:5,c:2@a:1,b:2
输出:a:2,b:3,c:2
说明:全量字符集为3个a,5个b,2个c。已占用字符集为1个a,2个b。由于已占用字符集不能再使用,因此,剩余可用字符为2个a,3个b,2个c。因此输出a:2,b:3,c:2。注意,输出的字符顺序要跟输入一致。不能输出b:3,a:2,c:2。如果某个字符已全被占用,不需要输出。例如a:3,b:5,c:2@a:3,b:2,输出为b:3,c:2。
package HuaWei;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Num1 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
String str = "a:3,b:5,c:2@a:3,b:4";
String res = solution(str);
System.out.println(res);
}
private static String solution(String str){
StringBuilder sb = new StringBuilder();
String[] tmp = str.split("@");
if(tmp.length == 1){
sb.append(tmp[0]).append("@");
return sb.toString();
}
String[] str1 = tmp[0].split(",");
String[] str2 = tmp[1].split(",");
Map<String, Integer> map1 = new HashMap<>();
Map<String, Integer> map2 = new HashMap<>();
for(int i = 0; i < str1.length; i++){
map1.put(str1[i].substring(0, 1), Integer.parseInt(str1[i].substring(2, 3)));
}
for(int i = 0; i < str2.length; i++){
map2.put(str2[i].substring(0, 1), Integer.parseInt(str2[i].substring(2, 3)));
}
for(String s : map1.keySet()){
if(!map2.containsKey(s)){
sb.append(s).append(":").append(map1.get(s)).append(",");
}
for(String s2 : map2.keySet()){
if(s.equals(s2)){
int num = map1.get(s) - map2.get(s2);
if(num > 0){
sb.append(s).append(":").append(num).append(",");
}
}
}
}
return sb.toString();
}
}
二、Trie树
题目描述:
如下是一棵Trie树,圆圈表示内部节点,指向孩子节点的每个标记的值范围在0-255之间,每个内部节点最多有256个孩子节点。三角形表示叶子节点,每个叶子节点中存储一个value,根节点到叶子节点之间路径上的所有字符构成一个完整key。
输入描述:
第1行的数字M表示Labels、HasChild、POUDS数组大小,紧跟着的3行分别表示Labels、HasChild、POUDS数组内容,用空格分开。第5行的数字N表示Values数组大小,随后1行表示Values数组内容。第7行的数字表示Key数组大小,随后1行表示要查找的key字符数组。
输出描述:
输出一行key对应的value,若key不存在,输出0。
示例1:
输入:
15
115 112 116 97 111 121 114 101 105 112 121 114 102 115 116
0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
1 1 0 1 0 1 1 1 0 0 0 1 1 0 0
8
1 2 3 4 5 6 7 8
3
116 114 112
输出:
7
package class07;
public class Code01_TrieTree {
public static class TrieNode {
public int path;
public int end;
public TrieNode[] nexts;
public TrieNode() {
path = 0;
end = 0;
nexts = new TrieNode[26];
}
}
public static class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
if (word == null) {
return;
}
char[] chs = word.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];
node.path++;
}
node.end++;
}
public void delete(String word) {
if (search(word) != 0) {
char[] chs = word.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (--node.nexts[index].path == 0) {
node.nexts[index] = null;
return;
}
node = node.nexts[index];
}
node.end--;
}
}
public int search(String word) {
if (word == null) {
return 0;
}
char[] chs = word.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
return 0;
}
node = node.nexts[index];
}
return node.end;
}
public int prefixNumber(String pre) {
if (pre == null) {
return 0;
}
char[] chs = pre.toCharArray();
TrieNode node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
return 0;
}
node = node.nexts[index];
}
return node.path;
}
}
public static void main(String[] args) {
Trie trie = new Trie();
System.out.println(trie.search("zuo"));
trie.insert("zuo");
System.out.println(trie.search("zuo"));
trie.delete("zuo");
System.out.println(trie.search("zuo"));
trie.insert("zuo");
trie.insert("zuo");
trie.delete("zuo");
System.out.println(trie.search("zuo"));
trie.delete("zuo");
System.out.println(trie.search("zuo"));
trie.insert("zuoa");
trie.insert("zuoac");
trie.insert("zuoab");
trie.insert("zuoad");
trie.delete("zuoa");
System.out.println(trie.search("zuoa"));
System.out.println(trie.prefixNumber("zuo"));
}
}
三、逻辑计算
题目描述:
常用的逻辑计算有And(表示为&);Or(表示为|);Not(表示为!)。其中,他们的优先级关系是Not(!)>And(&)>Or(|)。
输入描述:
1、测试用例中间无空格,无需考虑空格。
2、测试用例表达式只会出现如下字符:“0”,“1”,“(”,“)”,“&”,“|”,“!”。
3、测试用例所给的输入都是合法输入,无需要考虑非法输入。
4、测试用例长度不会超过128个字符。
5、括号可以重复嵌套。
例如:
1 | ( 1 & 0 ) 返回值:1
1 & 0 | 0 & 1 返回值:0
! 0 & 1 | 0 返回值:1
( ( ! 0 & 1 ) ) | 0 返回值:1
输出描述:
输出逻辑运算后的最终结果:0或者1
示例1:
输入:! ( 1 & 0 ) | 0 & 1
输出:1
示例2:
输入:! ( 1 & 0 ) & 0 | 0
输出:0
import java.util.Scanner;
import java.util.Stack;
public class Solution {
public static String transfer(String mathStr) {
StringBuilder result = new StringBuilder();
Stack<Character> stack = new Stack();
if (mathStr == null || mathStr.length() == 0) {
return null;
}
char[] arr = mathStr.toCharArray();
for (int i = 0; i < arr.length; i++) {
char s = arr[i];
if (s=='1'||s=='0') {
result.append(s);
}
else if ('(' == s) {
stack.push(s);
}
else if ('!' == s || '&' == s || '|' == s) {
if (!stack.isEmpty()) {
char stackTop = stack.pop();
if (compare(s, stackTop)) {
stack.push(stackTop);
stack.push(s);
}
else {
result.append(stackTop);
stack.push(s);
}
}
else {
stack.push(s);
}
}
else if (s == ')') {
while (!stack.isEmpty()) {
char item = stack.pop();
if (item != '(') {
result.append(item);
} else {
break;
}
}
}
}
while (!stack.isEmpty()) {
result.append(stack.pop());
}
return result.toString();
}
//比较优先级
public static boolean compare(char s, char item) {
if (item == '(') {
return true;
}
if (s == '!') {
if (item == '&' || item == '|') {
return true;
}
}else if(s == '&') {
if (item == '|') {
return true;
}
}
return false;
}
//计算结果
public static int calculate(String transferToPostfix) {
Stack<Integer> stack = new Stack();
char[] c = transferToPostfix.toCharArray();
int a, b;
for (int i = 0; i < c.length; i++) {
switch (c[i]) {
case '!':
a = Integer.valueOf(stack.pop().toString());
//b = Integer.valueOf(stack.pop().toString());
if(a==1) {
stack.push(0);
}else {
stack.push(1);
}
break;
case '&':
a = Integer.valueOf(stack.pop().toString());
b = Integer.valueOf(stack.pop().toString());
stack.push(b&a);
break;
case '|':
a = Integer.valueOf(stack.pop().toString());
b = Integer.valueOf(stack.pop().toString());
stack.push(b|a);
break;
default:
Character d = c[i];
stack.push(Integer.valueOf(d.toString()));
break;
}
}
return stack.pop();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//System.out.println(calculate(transfer("!(1&0)|0&1")));
Scanner sc = new Scanner(System.in);
String str = sc.next();
System.out.println(calculate(transfer(str)));
}
}
通过括号的一个层级关系,来一步一步进行子表达式的解析过程,首先申请一个列表和栈,其中列表开始放置01,然后栈中堆积操作符和左括号,进行遍历一个一个插入,如果后面的操作符优先级小于前面,则直接压入栈中,如果大于前面,则将优先级低的操作符放到列表里,优先级高的操作符压入栈中,(中间会有一个比较函数),如果遍历到左括号,则将栈中的操作符一个一个的压入列表,知道遇到左括号,(这里进行子表达式的计算),最后将栈中剩余操作符压入列表中,这些就是子表达式之外的操作。
然后通过计算函数进行逻辑运算,就是将列表中的元素遍历,这里还需要一个栈,如果遍历的元素为01,压入栈中,如果是操作数,则通过相应的逻辑运算符进行运算,最终求得结果值!!!!