第4章学习小结

第四章讲的是串,数组和广义表,在做题过程中,逐渐发现STL中string的强大(下一个目标,熟悉string的函数)。

天梯赛L1-8 估值一亿的AI核心代码

这题也终于打出来了,心得是要尽量划分层次,思路要清晰,严谨,多写几个判断函数是完全没问题的(努力习惯中...)

AC代码:(原题)

#include <iostream>
#include <string.h>
using namespace std;
char map[1005];
char a[1005],b[1005],c[1005];
int alen=0,blen=0,clen=0;
bool vis[1005];
bool isbiao(char a)
{
    if(a>='a'&&a<='z'||a>='A'&&a<='Z'||a>='0'&&a<='9'||a==' ') return false ;
    else return true;
}
bool isspace(char a)
{
    return a==' ';
}
bool isalone(char a)
{
    return isbiao(a)||isspace(a)||a=='\0';
}
bool iscan(char a[])
{
    return !strcmp(a,"can you");
}
bool iscould(char a[])
{
    return !strcmp(a,"could you");
}
void solve_kong_big_wen()
{
    alen=0;
    int len=strlen(map),i=0;
    if(map[i]==' '){//处理前空格 
        while(map[i]==' '){
            ++i;
        }
    }
    for(;i<len;++i){
        if(map[i]==' '){
            if(i+1<len && !isspace(map[i+1]) && !isbiao(map[i+1])) a[alen++]=map[i];
        }
        else if(map[i]=='?') a[alen++]='!';
        else if(map[i]>='A'&&map[i]<='Z'&&map[i]!='I') a[alen++]=char(map[i]+32);
        else a[alen++]=map[i];
    }
    a[alen]='\0';
}
void solve_can()
{
    memset(vis,0,sizeof(vis));
    blen=0;
    for(int i=0;i<alen;++i){
        if(a[i]=='c'){
            int flag=0;
            if(i+6<alen) {
                if(!((i-1>=0&&isalone(a[i-1])||i-1==-1)&&(i+7<=alen&&isalone(a[i+7])))) ;    
                else {
                    char m[10];
                    strncpy(m,a+i,7);
                    m[7]='\0';
                    if(iscan(m)) {
                        vis[blen]=1;b[blen++]='I';b[blen++]=' ';b[blen++]='c';b[blen++]='a';b[blen++]='n';i+=6;
                        continue;
                    }
                }
                
            }        
            if(i+8<alen){
                if(!((i-1>=0&&isalone(a[i-1])||i-1==-1)&&(i+9<=alen&&isalone(a[i+9])))) {
                    b[blen++]=a[i];continue;
                }
                char m[15];
                strncpy(m,a+i,9);
                m[9]='\0';
                if(iscould(m)) {
                    vis[blen]=1;b[blen++]='I';b[blen++]=' ';b[blen++]='c';b[blen++]='o';b[blen++]='u';b[blen++]='l';b[blen++]='d';i+=8;
                }
                else b[blen++]=a[i];
            }
            else b[blen++]=a[i];
        }
        else b[blen++]=a[i];
    }
    b[blen]='\0';
}
void solve_I()
{
    clen=0;
    for(int i=0;i<blen;++i){
        if(b[i]=='I'&&!vis[i]){
            if(!((i-1>=0&&isalone(b[i-1])||i-1==-1)&&(i+1<=blen&&isalone(b[i+1])))) c[clen++]=b[i];
            else {
                c[clen++]='y';c[clen++]='o';c[clen++]='u';
            }
        }
        else if(b[i]=='m'&&i+1<blen&&b[i+1]=='e'){
            if(!((i-1>=0&&isalone(b[i-1])||i-1==-1)&&(i+2<=blen&&isalone(b[i+2])))) c[clen++]=b[i];
            else {
                c[clen++]='y';c[clen++]='o';c[clen++]='u';i++;
            }
        }
        else c[clen++]=b[i];    
    }
    c[clen]='\0';
}
int main()
{
    int N;
    cin>>N;
    getchar();
    while(N--){
        cin.getline(map,1004);
        solve_kong_big_wen();
        solve_can();
        solve_I();
        cout<<map<<endl;
        cout<<"AI: "<<c<<endl;
    }
    return 0;
}
View Code

我想讨论的题目是 7-1 稀疏矩阵 

这题没有删除增加,只有查询,感觉上开一个结构体数组存数据 + 一个for循环遍历就能解决了,但我还是去试着琢磨一下十字链表

(图片来源网络)

上图就是稀疏矩阵的样子,它有每一行的头指针,每一列的头指针,以及n个节点;

节点的图:

(图片来源网络)

 一个节点代表矩阵中一个非零数字的信息

包括行(row),列(col),数值(value),指向右边的指针(right),指向下面的指针(down)

下面分享我开创一个十字链表的步骤:

一:定义(节点+链表)

int n,m,t;//待输入的信息,第二步用

定义节点:

typedef struct node{
    int x,y,w; //x代表行,y代表列,w代表数值
    node *down,*right;
}node;
定义链表:
struct crosslist{
    node *rhead[505],*chead[505];//每一行指针,每一列指针
    int hang,lie,num;//突出我英语不好
}M;
 
二:输入稀疏矩阵的行数、列数和矩阵中非零元素的个数初始化指针
cin>>n>>m>>t;
for(int i=1;i<=n+5;++i){  //习惯多开一点空间
        M.rhead[i]=NULL;
    }
for(int i=1;i<=m+5;++i){
        M.chead[i]=NULL;
   }
 
三:输入每一个点的信息
for(int k=1;k<=t;++k){
//输入行,列,数值
        cin>>i>>j>>w;
//开一个节点,并赋值
        p=new node;
        p->x =i;
        p->y =j;
        p->w =w;
//对该行处理,判断该行有没有元素,或者该行的第一个元素在准备插入的元素的右边,则直接插入
        if(M.rhead[i]==NULL || M.rhead[i]->y>j ){
            p->right =M.rhead[i];
            M.rhead[i]=p;
        }
//否则,找到应该插入的位置并插入
        else {
            for(q=M.rhead[i];q->right!=NULL&&q->right->y < j;q=q->right);//注意这个分号,for循环只是为了移动指针到合适的位置,没有对元素进行处理
                p->right=q->right;
                q->right=p;
        }
 //对该列处理,与行道理相同      
        if(M.chead[j]==NULL || M.chead[j]->x >i ){
            p->down=M.chead[j];
            M.chead[j]=p;
        }
        else {
            for(q=M.chead[j];q->down!=NULL&&q->down->x<i ;q=q->down );
            p->down=q->down;
            q->down=p;
        }
    }
}
 
这样,十字链表就建好了,再写一个查询函数就可以了解决问题了(简单问题复杂化)
注意:这份代码仅仅是为了做题,针对性很强,漏洞很多。写出来主要是为了分享思想。
附上AC代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stack>
#include <stdio.h>
#include <cmath>
using namespace std;
#define maxn 1000010
int n,m,t;

typedef struct node{
    int x,y,w;
    node *down,*right;
}node;
struct crosslist{
    node *rhead[505],*chead[505];//行,列 
    int hang,lie,num;
}M;

void create()
{
    node *p,*q;
    cin>>n>>m>>t;
    M.hang=n;
    M.lie=m;
    M.num=t;  
    for(int i=1;i<=n+5;++i){
        M.rhead[i]=NULL; 
    }
    for(int i=1;i<=m+5;++i){
        M.chead[i]=NULL; 
    }
    int i,j,w;
    for(int k=1;k<=t;++k){
        cin>>i>>j>>w;
        p=new node;
        p->x =i;
        p->y =j;
        p->w =w;
        if(M.rhead[i]==NULL || M.rhead[i]->y>j ){
            p->right =M.rhead[i];
            M.rhead[i]=p;
        }
        else {
            for(q=M.rhead[i];q->right!=NULL&&q->right->y < j;q=q->right);
                p->right=q->right; 
                q->right=p;
        }
        
        if(M.chead[j]==NULL || M.chead[j]->x >i ){
            p->down=M.chead[j]; 
            M.chead[j]=p; 
        }
        else {
            for(q=M.chead[j];q->down!=NULL&&q->down->x<i ;q=q->down  );
            p->down=q->down;
            q->down=p;
        }
    }
}
void query(int k)
{
    int flag=0,i=0;
    while(flag==0&&i<=n)
    {
        ++i;
        node *p;
        p=M.rhead[i]; 
        while(p!=NULL)
        {
            if(p->w==k){
                flag=1;
                cout<<p->x<<" "<<p->y;
                break;  
            }
            else p=p->right; 
        }
    }
    if(flag==1) ;
    else cout<<"ERROR";
}
int main()
{
    create();
    int n;
    cin>>n;
    query(n);
    
    return 0;
}
View Code

 

上次博客定下的目标没有完成(做完线段树专题),原因是讲课好快啊都来不及做+思想理解了但代码敲不出来

接下来目标是熟悉string的函数,敲出主席树。

 

posted @ 2019-04-13 13:45  丿不落良辰  阅读(336)  评论(1编辑  收藏  举报