洛谷P3809 【模板】后缀排序

洛谷P3809 【模板】后缀排序

 

这里,仅仅介绍一下如何进行字符串的后缀排序

$STL$ 中的 $sort$ ? 想得美 $!$

由于 $sort$ 函数在比较字符串大小时会将字符串的每一个字

符逐一比较,整体复杂度便是 $O(n^2logn)$ .

我们需要一个更快的方法来对后缀排序.

由于不太好讲,我就不讲啦QAQ...

 

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 1000013
using namespace std;
char str[maxn];
int a[maxn],rk[maxn],sa[maxn],tp[maxn],tax[maxn],n,m;

void read(){
    scanf("%s",str);
    n=strlen(str);
    for(int i=0;i<n;++i) a[i+1]=str[i]; 
}
void qsort(){
    for(int i=0;i<=m;++i) tax[i]=0;
    for(int i=1;i<=n;++i) ++tax[rk[tp[i]]]; 
    for(int i=1;i<=m;++i) tax[i]+=tax[i-1];
    for(int i=n;i>=1;--i) sa[tax[rk[tp[i]]]--]=tp[i]; 
}
void suffix(){
    for(int i=1;i<=n;++i) rk[i]=a[i],tp[i]=i; 
    qsort(); 
    for(int k=1;k<=n;k<<=1){
        int num=0;
        for(int i=n-k+1;i<=n;++i)tp[++num]=i;
        for(int i=1;i<=n;++i) if(sa[i]>k) tp[++num]=sa[i]-k; 
        qsort();
        swap(rk,tp);
        rk[sa[1]]=1;
        num=1;
        for(int i=2;i<=n;++i) 
            rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+k]&&tp[sa[i]+k]==tp[sa[i-1]+k])?num:++num;
        if(num==n) break;
        m=num;  
    }
    return; 
}
int main(){
    //setIO("input"); 
    read();
    m=122; 
    suffix(); 
    for(int i=1;i<=n;++i) printf("%d ",sa[i]);
    return 0; 
}

  

posted @ 2019-01-14 14:57 EM-LGH 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷p1449是一个C语言题目,要求实现一个后缀表达式的计算器。后缀表达式是一种不使用括号,将运算符号放在运算对象之后的表达式。计算后缀表达式的方法是从左到右遍历表达式,遇到操作数就入栈,遇到运算符就从栈中弹出两个操作数进行运算,然后将结果再次入栈,直到遍历完整个表达式,最后栈中的唯一元素就是计算结果。 以下是一个C语言的示例代码,用于实现后缀表达式的计算器: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int top; } Stack; void initStack(Stack *s) { s->top = -1; } void push(Stack *s, int value) { if (s->top == MAX_SIZE - 1) { printf("Stack is full.\n"); exit(1); } s->data[++(s->top)] = value; } int pop(Stack *s) { if (s->top == -1) { printf("Stack is empty.\n"); exit(1); } return s->data[(s->top)--]; } int calculate(int operand1, int operand2, char operator) { switch (operator) { case '+': return operand1 + operand2; case '-': return operand1 - operand2; case '*': return operand1 * operand2; case '/': return operand1 / operand2; default: printf("Invalid operator.\n"); exit(1); } } int evaluatePostfixExpression(char *expression) { Stack stack; initStack(&stack); int i = 0; while (expression[i] != '@') { if (isdigit(expression[i])) { push(&stack, expression[i] - '0'); } else if (expression[i] == '.') { int operand2 = pop(&stack); int operand1 = pop(&stack); int result = calculate(operand1, operand2, expression[++i]); push(&stack, result); } i++; } return pop(&stack); } int main() { char expression[] = "3.5.2.-*7.+@"; int result = evaluatePostfixExpression(expression); printf("Result: %d\n", result); return 0; } ``` 这段代码实现了一个后缀表达式的计算器,可以计算给定后缀表达式的结果。在示例代码中,后缀表达式"3.5.2.-*7.+"被转换为中缀表达式"3*(5-2)+7",最终计算结果为16。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值