• 学大伟业 Day 3 培训总结


    今天讲的字符串:

    不多说,直接看题

    一.表达式求值

    题目大意:

    输入一行一个表达式,计算其答案 表达式包含非负整数、加减乘除、括号

    两种做法

    ·栈

    ·表达式树

    这里更推荐表达式树,因为栈是先压进去,逆序操作。在进行逆序操作时即从右往左计算,实际应该是从左往右计算,所以会出现计算不符合顺序的问题。从而出现错误。

    而表达式树则又称为“表达式目录树”,以数据形式表示语言级代码,它是一种抽象语法树或者说是一种数据结构。——摘自百度百科

    可见,每个父节点都是一种运算符,子节点为数字。运算时从底层向上层依次按父节点符号操作子节点即可。

    先贴的代码:

     1 /*
     2 1+(2+3)*4
     3 21
     4 */
     5 
     6 #include <iostream>
     7 #include <stack>
     8 using namespace std;
     9 
    10 const int MAXN = 10000 + 10;
    11 char str[MAXN];
    12 stack<int> nums;
    13 stack<char> symbol;
    14 
    15 void pop()
    16 {
    17     int a = nums.top();nums.pop();
    18     int b = nums.top();nums.pop();
    19     char s = symbol.top();symbol.pop();
    20     int ans;
    21     switch(s)
    22     {
    23         case '+':ans=a+b;break;
    24         case '-':ans=b-a;break;
    25         case '*':ans=a*b;break;
    26         case '/':ans=b/a;break;
    27     }
    28     nums.push(ans);
    29 }
    30 int main()
    31 {
    32     cin >> (str+1);
    33     for(int i=1;str[i]!=0;i++)
    34     {
    35         char c=str[i];
    36         if('0'<=c&&c<='9')
    37         {
    38             nums.push(c-'0');
    39         } else {
    40             if(c==')')
    41             {
    42                 while(symbol.top() != '(') pop();
    43                 symbol.pop();
    44             } else if (c=='+' || c=='-')
    45             {
    46                 while(!symbol.empty()
    47                     &&symbol.top()!='+'
    48                     &&symbol.top()!='-'
    49                     &&symbol.top()!='(') pop();
    50                 symbol.push(c);
    51             } else symbol.push(c);
    52         }
    53     }
    54     while(!symbol.empty())pop();
    55     cout<<nums.top()<<endl;
    56     
    57     return 0;
    58 }

    在计算上面图中的例子时,栈会出错。

    下面给出表达式树的代码:

     1 /*
     2 10+(2+3)*4
     3 30
     4 */
     5 
     6 #include <iostream>
     7 #include <stack>
     8 #include <cstring>
     9 using namespace std;
    10 
    11 const int MAXN = 10000 + 10;
    12 char str[MAXN];
    13 
    14 int solve(int l, int r) 
    15 {
    16     
    17     int pos=-1;
    18     int flag=0;
    19     int level=2; // 0:+- 1:*/
    20     for(int i=l;i<=r;i++)
    21     {
    22         if(str[i]=='(')flag++;
    23         if(str[i]==')')flag--;
    24         if(flag == 0 && (str[i]<'0'||str[i]>'9'||str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')&&str[i]!=')')
    25         {
    26             int l=-1;
    27             switch(str[i])
    28             {
    29                 case '+':case '-':l=0;break;
    30                 case '*':case '/':l=1;break;
    31             }
    32             if(level >= l)
    33             {
    34                 level=l;
    35                 pos=i;
    36             }
    37         }
    38     }
    39     if(pos==-1)
    40     {
    41         if(str[l]=='('&&str[r]==')') return solve(l+1,r-1);
    42         int x=0;
    43         for(int i=l;i<=r;i++)
    44             x=x*10+str[i]-'0';
    45         return x;
    46     }
    47     int a = solve(l, pos-1);
    48     int b = solve(pos+1, r);
    49     int ans;
    50     switch(str[pos])
    51     {
    52         case '+':ans=a+b;break;
    53         case '-':ans=a-b;break;
    54         case '*':ans=a*b;break;
    55         case '/':ans=a/b;break; // 3*2/3
    56     }
    57     return ans;
    58 }
    59 int main()
    60 {
    61     cin >> (str+1);
    62     cout << solve(1, strlen(str+1)) << endl;
    63 
    64     return 0;
    65 }

    二.字符串统计

    题目大意:给定N个字符串,判断不同的字符串有多少个。

    做法:hash

    所谓hash就是把每个字符串设成一个值,每个字符串的值要不同,所以操作的时候只要弄的奇奇怪怪就好啦(个人理解,不喜勿喷)

    这样比较字符串就成了比较数值的问题。

    哈希碰撞:所谓哈希碰撞是指在哈希时难免会遇到有重复的数值,解决方案可以为双哈希。

    例如:在哈希时会模一个很大的质数,假设这个质数为mod,当遇到某个数m时(m<mod)m % mod = m

    但是当遇到另一个数n时,n恰巧为 m + mod 那么 n % mod = m 两串字符对应值都为m,产生了碰撞。

    在洛谷有道模板题,链接:https://www.luogu.org/problemnew/show/P3370

    hash代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 long n;
     7 char s[10001];
     8 long long ms[10101]={0};
     9 long long ans=1;
    10 
    11 int main()
    12 {
    13     scanf("%d",&n);
    14     for(int i=1;i<=n;i++)
    15     {
    16         cin>>s;
    17         
    18         int len=strlen(s);
    19         for(int j=0;j<len;j++)
    20         ms[i]=(ms[i]*131+(long long)s[j])%233333333333+233317;
    21         
    22     }
    23         sort(ms+1,ms+n+1);
    24     for(int i=1;i<n;i++)
    25     {
    26         if(ms[i]!=ms[i+1])
    27         ans++;
    28     }
    29     printf("%d",ans);
    30     
    31    
    32 }

    隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。

    隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。

  • 相关阅读:
    Sensor Fusion-based Exploration in Home Environments using Information, Driving and Localization Gains(基于传感器融合的使用信息、驾驶和定位增益在家庭环境中的探索)
    Git中从远程的分支获取最新的版本到本地
    git拉取远程分支到本地分支或者创建本地新分支
    win7下使用git
    ADAS

    struct对齐
    STL容器
    智能指针
    c++中的基本知识点
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/8470377.html
Copyright © 2020-2023  润新知