7-27表达式求值
给定一个中缀表达式,请编写程序计算该表达式的值。表达式包含+、-、*、\、(、),所有运算均为二元运算,操作数均为正整数,但可能不止一位,不超过5位。运算结果为整数,值域为[−231,231)。除法运算结果若为小数则进行截尾取整。若除法运算中除数为0,则输出ILLEGAL。
输入格式:
输入为一个字符串,表示中缀表达式。
输出格式:
输出为一个整数,为表达式的值;或者为一个字符串ILLEGAL。
输入样例1:
5+(10*2)-6
输出样例1:
19
输入样例2:
8*(999+1)
输出样例2:
8000
输入样例3:
1+5/(1-1)
输出样例3:
ILLEGAL
答
#include<stdio.h>
#include<string.h>
int in(char ch)
{
if (ch <= '9' && ch >= '0')
return 1;
return 0;
}
int A(int a, char c, int b, int* flag)
{
if (c == '*')
return a * b;
else if (c == '/') {
if (b == 0)
*flag = 1;
else
return a / b;
}
else if (c == '-')
return a - b;
else if (c == '+')
return a + b;
}
int B(char a, char b)
{
int x = 0;
int y = 0;
if (a == '+' || a == '-')
x = 1;
else if (a == '*' || a == '/')
x = 2;
else if (a == '(')
x = 3;
if (b == '+' || b == '-')
y = 1;
else if (b == '*' || b == '/')
y = 2;
else if (b == '(')
y = 3;
if (x > y)return 1;
return 0;
}
int main()
{
char s[1000];
int num[1000];
char ch[1000];
int flag = 0;
fgets(s, 990, stdin);
int a = 0, b = 0;
for (int i = 0; i < 1000; i++)
{
num[i] = 0;
ch[i] = '0';
}
int i = 0;
while (i < strlen(s))
{
if (in(s[i]))//如果是数字则入num
{
while (in(s[i]))
num[a] = num[a] * 10 + s[i++] - '0';//多位数的情况
a++;
continue;
}
else//不是数字
{
if (s[i] == '(') //遇到左括号直接入ch【】
ch[b++] = s[i];
else if (s[i] == ')')//遇到右括号计算
{
while (ch[b - 1] != '(')
{
num[a - 2] = A(num[a - 2], ch[b - 1], num[a - 1], &flag);
num[a - 1] = 0;
b--;//改变符号栈栈顶
a--;//改变数字栈栈顶
}
b--;
}
else {//遇到运算符
if (b == 0) //符号栈为空,直接入
ch[b++] = s[i];
else if (B(s[i], ch[b - 1]))//判断当前符号与符号栈栈顶元素的优先级,如果当前元素优先级大直接入
ch[b++] = s[i];
else //栈顶元素优先级小,进行计算
{
while (!B(s[i], ch[b - 1])) {
if (ch[b - 1] == '(')//多重括号的情况
break;
num[a - 2] = A(num[a - 2], ch[b - 1], num[a - 1], &flag);
num[a - 1] = 0;
b--;
a--;
if (b == 0)break;
}
ch[b++] = s[i];//计算完后将此符号入ch【】
}
}
}
i++;
}
while (a != 1 && b > 0)//数字栈数组中剩余两位,符号剩余一位
{
num[a - 2] = A(num[a - 2], ch[b - 1], num[a - 1], &flag);
a--;
b--;
}
if (flag == 1)
printf("ILLEGAL");
else
printf("%d", num[0]);
}
7-28 贝蒂买桔子
贝蒂去超市买桔子,超市有n个桔子,每个桔子都有唯一的英文字母标号,贝蒂打算从所有桔子中挑选出若干个桔子买(也可能一个都不买),请编写程序帮助贝蒂求出所有可能的挑法。每种挑法按字典序给出各桔子的标号。
字典序,即字符串在字典中的顺序。对于两个字符串,从第一个字符开始比较,当某一个位置的字符不同时,该位置字符较小的串,字典序较小,例如abc比abd小。
输入格式:
输入为一个正整数n,表示超市里的桔子个数,n不超过15。桔子的标号为a, b, c, d…。若n=1,桔子为a;若n=3,桔子为a, b, c;若n=4,桔子为a, b, c, d;以此类推。
输出格式:
输出为若干行字符串,每行表示贝蒂的一种挑法。每种挑法用{}包含,每个桔子的标号用西文逗号间隔,例如{a,b,c},标号须按字典序排列。“什么也不买”对应的挑法最先输出,为{},中间无空格。
输入样例:
3
输出样例:
{}
{a}
{a,b}
{a,b,c}
{a,c}
{b}
{b,c}
{c}
答
#include <stdio.h>
// n不超过15
int ans[20];
int used[20]; // 记录每个数是否被用
int n;
void dfs(int u){
printf("{");
if(1!=u) printf("%c", 'a'-1+ans[1]);
for(int i=2; i<u; i++)
printf(",%c", 'a'-1+ans[i]);
printf("}\n");
for(int i=u; i<=n; i++)
if(used[i]) continue;
else if(i>ans[u-1]){
ans[u]=i;
used[i]=1;
dfs(u+1);
used[i]=0;
}
}
int main(){
scanf("%d",&n);
dfs(1);
return 0;
}
7-29 好中缀
我们称一个字符串S的子串T为好中缀,如果T是去除S中满足如下条件的两个子串p和q后剩余的字符串。
(1)p是S的前缀,q是S的后缀;
(2)p=q;
(3)p和q是满足条件(1)(2)的所有子串中的第二长者。
注意一个字符串不能称为自己的前缀或后缀。好中缀至少为空串,其长度大于等于0,不能为负数。
输入格式:
输入为一个字符串S,包含不超过100000个字母。
输出格式:
输出为一个整数,表示好中缀的长度。
输入样例1:
abcabcxxxabcabc
输出样例1:
9
输入样例2:
xacbacba
输出样例2:
8
输入样例3:
aaa
输出样例3:
1
答
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10000010
int next[N],ans[N];
char s[N];
int ls;
void Next(){
int j=0;
for(int i=2;i<=ls;i++){
while(j>0&&s[j+1]!=s[i]){
j=next[j];
}
if(s[j+1]==s[i]){
j++;
}
next[i]=j;
}
}
int main()
{
scanf("%s",s+1);
ls=strlen(s+1);
Next();
int t=ls;
int c=0;
while(t>0){
t=next[t]; // 递推求得 相同前后缀 的子串 的长度
ans[++c]=t; // 并逐个存到数组中,数组下标从1到cnt
}
if(c==0){ // 说明没有相同前后缀,输出原长度
printf("%d\n",ls);
}
else{
int n=ls-2*ans[2];
if(n<0) n=0; // 比如s = "aaaa"
printf("%d\n",n);
}
return 0;
}
7-30 破译报文
小明接到一个破解报文的任务:该报文是一串文本,破解出的密文应是在报文串中出现次数大于1的所有子串中的最长者。规定报文本身不能称为自己的子串。请编写效率尽可能高的程序帮小明完成这个棘手的任务。
输入格式:
输入为一个字符串,表示报文,包含不超过10000个字母。
输出格式:
输出为一个整数,表示破解出的密文串的长度。
输入样例1:
xabceabcf
输出样例1:
3
输入样例2:
xyabcabcayx
输出样例2:
4
答
#include <iostream>
#include <cstring>
using namespace std;
const int N=1e4+10;
string s;
int n;
int a[N];
void quick_sort(int q[], int l, int r){
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
string sx=s.substr(x, n-x);
// s.substr(q[i], n-q[i])
while (i < j){
do i ++ ; while (s.substr(q[i], n-q[i]) < sx);
do j -- ; while (s.substr(q[j], n-q[j]) > sx);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
int main(){
cin>>s;
int n=s.size();
for(int i=0; i<n; i++) a[i]=i; // 截取
quick_sort(a, 1, n-1);
//for(int i=0; i<n; i++)
// cout<<s.substr(i, n-i)<<endl;
int ans=0;
for(int i=0; i<n; i++){
string x=s.substr(a[i], n-a[i]);
string y=s.substr(a[i+1], n-a[i+1]);
int res=0;
for(int j=0; j<x.size() && j<y.size(); j++)
if(x[j]==y[j]) res++;
else break;
ans=max(ans, res);
}
cout<<ans<<endl;
return 0;
}
在此还是感谢戴老大的帮助~~~~~~~~你是我的神!!!!!!!!!!