程序填空题:
【程序说明】
应用计算机处理日常事务或者是编写程序的时候,经常需要用到带有通配符的字符串
匹配。比如:linux命令行下输入,ls*.txt 就是列出当前目录下所有的结尾是.txt
的文件。下面一段函数实现了带有$和*两种通配符的字符串的匹配功能。其中:$表示
长度大于0的数字串,*表示任意长度的字符串。
要求:按照自己对于算法的理解填写该函数的5个空白。
请注意:必须是完全匹配才能返回true,比如1.txt, a.txt可以匹配*.txt, 2.tx或者
2.txta不能匹配*.txt。函数的参数与返回值的说明请参见函数的注释。
import java.io.*;
import java.util.*;
import java.math.*;
// 功能描述: 表达式是否匹配成功, $表示长度大于 0 的数字串,*表示任意长的字符串
// 输入参数: @pRule, 以'\0'结束的字符串,表示规则;
// @pStr, 以'\0'结束的待匹配的字符串;
// 返回值:true:匹配成功; false: 匹配失败
public class Main {
public static boolean isRegularMatching(String rule, String str) {
int lRule = rule.length();
int lStr = str.length();
int iRule = 0;
int iStr = 0;
while (iRule < lRule && iStr < lStr) {
switch (rule.charAt(iRule)) {//从iRule下标开始逐个匹配
case '*': {//如果是通配符*
iRule += 1;//规则串下标+1
if (iRule >= lRule) {//如果规则串已走完,则匹配成功
return true;
} else {
for (int i = iStr; i < lStr; i++) {
if (str.substring(i).equals(rule.substring(iRule))) {//匹配两个字符串是否存在相同的结尾,若存在,则匹配成功
return true;
}
}
}
break;
}
case '$': {//如果是数字串$
if (!Character.isDigit(str.charAt(iStr))) {//匹配字符串该位置是否为数字,若不是就直接返回
return false;
}
while ((iStr < lStr) && (str.charAt(iStr) >= '0') && (str.charAt(iStr) <= '9')) {//匹配字符串连续的数字
iStr += 1;
}
iRule += 1;
break;
}
default: {
if (rule.charAt(iRule) != str.charAt(iStr)) {//若不是以上两种情况,就直接判断字符是否相同
return false;
}
iRule += 1;
iStr += 1;
break;
}
}
}
//有一个串没走完或者都走完了
if (iRule < lRule && iStr >= lStr) {//若规则串还没走完
if (rule.charAt(iRule) == '*') {
return true;
}
} else {//规则串走完
return iStr>=lStr;//若lStr也匹配完了就可以返回true
}
return false;
}
}
编程题:
输入任意一种物质,要求输出其每种元素的数量。
比如
输入 CaCO3,其组成分别为 Ca:1,C:1,O:3,输出 Ca1C1O3
输入 Fe2(SO4)3,其组成分别为 Fe:2,S:3,O:12,输出 Fe2S3O12
(注意:元素名称首字母大写,剩余字母都小写;括号括起来表示括号中的结构作为整体出现多少次)
个人思路:
这题算是困难题了,条件判断很多,写起来很费时间。
我用的方法是递归,大致思路是:用栈装载元素字符串,用hashmap记录元素的次数,遇见括号开一个小栈,递归返回后把小栈里的字符串倒进大栈。
在笔试过程匆忙写的,笔试后加了详细注释,还有很多可以优化的地方,欢迎大佬批评指正。
import java.io.*;
import java.util.*;
import java.math.*;
public class Main
{
static String param;//输入串
static HashMap<String,Integer>map;//hashmap记录元素出现次数
public static void main(String[] args)
{
InputReader in = new InputReader();
PrintWriter out=new PrintWriter(new BufferedOutputStream(System.out));
//在下方输入代码
StringBuilder ans=new StringBuilder();//结果串
param=in.next();
map=new HashMap<>();
Deque<String>stack=new ArrayDeque<>();
Deque<String>ansStack=method(0,stack);//最后的结果栈
while (!ansStack.isEmpty()){
String s=ansStack.pollLast();
ans.append(s).append(map.get(s));//把栈里的字符和对应的次数进行拼接
}
out.println(ans);
//在上方输入代码
out.close();
}
static int temindex=0;//设置全局静态变量:乘数下标
public static Deque<String> method(int index,Deque<String>big){//递归方法
Deque<String>small=new ArrayDeque<>();//开个小栈,预装载
for (int i = index; i < param.length(); ++i) {//for循环对字符串进行挨个校验
if (param.charAt(i)=='('){//如果字符为‘(’,则要进入递归
small=method(i+1, small);//由小栈装载递归结果
int mul=param.charAt(temindex)-'0';//得出所乘次数
for (String s:small ) {//foreach循环取出小栈里的元素
map.put(s, map.get(s)*mul);//map重新记录元素出现次数
}
while (!small.isEmpty()){//把小栈里的元素倒入大栈中
String s=small.pollLast();
big.push(s);
}
i=temindex;//下标设置为‘)’数字后的索引
}else if (Character.isUpperCase(param.charAt(i))){//如果是大写字母
String s;
if (i==param.length()-1||!Character.isLowerCase(param.charAt(i+1))){//如果下标是最后一位 或 第二个字符不是小写字母,则说明是单字母元素
s= String.valueOf(param.charAt(i));
}else {//否则是双字母元素
s = param.substring(i, i + 2);
i++;
}
map.put(s, 1);
big.push(s);
}else if(param.charAt(i)==')'){//如果遇到‘)’,则设置乘数下标,并将此次递归返回
temindex=i+1;
return big;
}else if(Character.isDigit(param.charAt(i))&&')'!=param.charAt(i-1)){//此判断是针对 元素后直接带数字 的情况
int mul=param.charAt(i)-'0';//计算乘数
if (big.peek()!=null)//如果栈顶有值
map.put(big.peek(),map.get(big.peek())*mul);//修改map中的记录值
}
}
return big;
}
}
class InputReader
{
BufferedReader buf;
StringTokenizer tok;
InputReader()
{
buf = new BufferedReader(new InputStreamReader(System.in));
}
boolean hasNext()
{
while(tok == null || !tok.hasMoreElements())
{
try
{
tok = new StringTokenizer(buf.readLine());
}
catch(Exception e)
{
return false;
}
}
return true;
}
String next()
{
if(hasNext()) return tok.nextToken();
return null;
}
int nextInt()
{
return Integer.parseInt(next());
}
long nextLong()
{
return Long.parseLong(next());
}
double nextDouble()
{
return Double.parseDouble(next());
}
BigInteger nextBigInteger()
{
return new BigInteger(next());
}
BigDecimal nextBigDecimal()
{
return new BigDecimal(next());
}
}
再贴一个改的C++版本
#include <bits/stdc++.h>
using namespace std;
static string param;
static unordered_map<string,int>maps;
static int temindex=0;
static deque<string> method(int index,deque<string>big){
deque<string>samll;
for (int i = index; i < param.length(); ++i) {
if (param[i]=='('){
samll= method(i+1,samll);
int mul=param[temindex]-'0';
while (!samll.empty()){
string s=samll.front();
samll.pop_front();
maps[s]=maps[s]*mul;
big.emplace_front(s);
}
i=temindex;
} else if (isupper(param[i])){
string s;
if (i==param.length()-1||!islower(param[i+1])){
s=param[i];
} else{
s=param.substr(i,i+2);
++i;
}
maps[s]=1;
big.emplace_front(s);
} else if (param[i]==')'){
temindex=i+1;
return big;
} else if (isdigit(param[i])&&')'!=param[i-1]){
int mul=param[i]-'0';
if (!big.empty()){
maps[big.front()]=maps[big.front()]*mul;
}
}
}
return big;
}
int main()
{
cin>>param;
string ans="";
deque<string>deques;
deque<string>ansdeque= method(0,deques);
while (!ansdeque.empty()){
string s=ansdeque.back();
ansdeque.pop_back();
ans.append(s).append(to_string(maps[s]));
}
cout<<ans;
}
上述为乐言科技笔试题,面试过程问详请私信