给定两个字符集合,一个为全量字符集,一个为已占用字符集。已占用的字符集中的字符不能再使用,要求输出剩余可用字符集。
输入描述:输入为一个字符串,字符串中包含了全量字符集和已占用字符集,两个字符集使用@连接,前面为全量,后面为已占用。
已占用字符集中的字符一定是全量字符集中的字符。
字符集中的字符跟字符之间用英文逗号分隔。
字符集中的字符表示为字符加数字,字符跟数字使用英文冒号分隔,比如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
注意:输出的字符顺序要跟输入一致!如果某个字符已全被占用,不需要再输出!
示例2:
输入
a:3,b:5,c:2@a:3,b:2
输出
b:3,c:2
用映射来模拟即可。
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef long long LL;
char ss[100010];
map<char,int> mp;
char ans[60];
int main()
{
cin>>ss;
int len = strlen(ss);
mp.clear();
int sum = 0;
int i;
for (i=0 ; i<len ; i++){
if ( (ss[i]>='a' && ss[i]<='z')||(ss[i]>='A' && ss[i]<='Z') ){
char now = ss[i];
i += 2;
int data = 0;
while (ss[i]>='0' && ss[i]<='9'){
data = 10*data + ss[i]-'0';
i++;
}
mp[now] = data;
ans[sum] = now;
sum++;
}
if (ss[i]=='@') break;
}
for (int j=i+1 ; j<len ; j++){
if ( (ss[j]>='a' && ss[j]<='z')||(ss[j]>='A' && ss[j]<='Z') ){
char now = ss[j];
j += 2;
int data = 0;
while (ss[j]>='0' && ss[j]<='9'){
data = 10*data + ss[j]-'0';
j++;
}
mp[now] -= data;
}
}
for (int k=0 ; k<sum ; k++){
if (mp[ans[k]]){
printf("%c:%d",ans[k],mp[ans[k]]);
if (k < sum-1) printf(",");
}
}
printf("\n");
return 0;
}
第二题没看懂题目,时间不太够。。。
常用的逻辑计算有And(表示为&),Or(表示为|),Not(表示为!)。
它们的优先级关系是Not > And > Or
例如: A|B&C = A|(B&C)
A&B|C&D = (A&B)|(C&D)
!A&B|C = ((!A)&B)|C
输入描述:测试用例中间无空格,表达式只包含 0 , 1 , ( , ) , & , !, | , 保证输入为合法输入,长度不超过128字符,括号可以重复嵌套,例如((!0&1))|0 = 1。
输出描述:输出逻辑运算后的最终结果,0或者1
显然这题直接输出0或者1可以至少通过50%的测试样例,如果时间不够的话就应该想到这种保底的做法,正确做法和实现一个四则运算计算器的做法差不多,先把字符串转为逆波兰式,然后计算逆波兰式,用栈搞来搞去。字符按顺序入栈,1.遇到数字,不进栈,直接放入逆波兰式中;2.遇到计算符,把它与栈顶字符进行优先级比较,如果栈顶的字符优先级大或者相同,则栈顶字符放入逆波兰式中,出栈一次,继续判断优先级直到当前计算符优先级比栈顶大,那么当前计算符入栈;3.遇到左括号,直接入栈,遇到右括号,开始出栈并且栈顶元素放入逆波兰式中,此操作可以保证括号内的运算顺序优先于括号外,直到左括号出栈则停止。
最后,把栈中元素全部取出按顺序放入逆波兰式中,由于入栈时保证了优先级是从小到大的,所以出栈以后逆波兰式肯定是按优先级从大到小计算。
计算逆波兰式,从前往后计算即可,遇到数字就入栈,遇到与和或操作则出栈两次,把两个数与(或),把结果入栈,遇到非操作,出栈,取非,结果入栈。
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef long long LL;
char ss[130],ss2[130];
int Precedence(char op)//运算符优先级判断
{
switch(op)
{
case '|':
return 1;
case '&':
return 2;
case '!':
return 3;
case '(':
case '\0':
default:
return 0; //定义在栈中的左括号和栈底字符的优先级为0
}
}
void tonibolan(char *s1,char *s2)
{
stack<char> s;
s.push('\0');
int i=0,j=0;
char ch=s1[i];
while (ch != '\0'){
if (ch == '('){
s.push('(');
ch = s1[++i];
}
else if (ch == ')'){
while (s.top() != '('){
s2[j++] = s.top();
s.pop();
}
s.pop();
ch = s1[++i];
}
else if (ch=='!' || ch=='&' || ch=='|'){
char w=s.top();
while (Precedence(w) >= Precedence(ch)){
s2[j++] = w;
s.pop();
w = s.top();
}
s.push(ch);
ch = s1[++i];
}
else {
if (ch=='0' || ch=='1'){
s2[j++] = ch;
ch = s1[++i];
}
s2[j++] = ' ';
}
}
ch = s.top();
s.pop();
while (ch != '\0'){
s2[j++] = ch;
ch = s.top();
s.pop();
}
s2[j++] = '\0';
cout<<s2<<endl;
}
int nibolan(char *s)
{
stack<int> sd;
int i=0,num1,num2,n1,n2,n3;
while (s[i] != '\0'){
num1 = 0;
num2 = 1;
if (s[i]=='0' || s[i]=='1'){
num1 = s[i]-'0';
i++;
sd.push(num1);
}
else if (s[i]==' ')
i++;
else if (s[i]=='!'){
n1 = sd.top();
sd.pop();
n2 = !n1;
sd.push(n2);
i++;
}
else if (s[i]=='&'){
n1 = sd.top();
sd.pop();
n2 = sd.top();
sd.pop();
n3 = n1&n2;
sd.push(n3);
i++;
}
else if (s[i]=='|'){
n1 = sd.top();
sd.pop();
n2 = sd.top();
sd.pop();
n3 = n1|n2;
sd.push(n3);
i++;
}
}
return sd.top();
}
int main()
{
cin>>ss;
tonibolan(ss,ss2);
cout<<nibolan(ss2)<<endl;
return 0;
}