华为8.07笔试

一、全量字符集与已占用字符集

输入描述:
输入一个字符串,字符串中包含了全量字符集和已占用字符集,两个字符集用@相连。@前的字符集合为全量字符集,@后的字符集为已占用字符集合。已占用字符集中的字符一定是全量字符集中的字符。字符集中的字符跟字符之间使用英文逗号分隔。字符集中的字符表示为字符加数字,字符跟数字使用英文冒号分隔,比如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,压入栈中,如果是操作数,则通过相应的逻辑运算符进行运算,最终求得结果值!!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值