你退學吧小明!
ps1:最近資料結構上機各種程式設計題太難頂了 為了總結一下自己犯的憨批錯誤以及方便以後複習 開了個資料結構專欄 準備把這幾次上機和平常寫程式碼的一些東西記錄下來 我的程式設計水平比CTF還菜 各位湊合看 (看吐了我也沒辦法
歡迎來到憨批小明系列 jlu的老師們就喜歡給一系列zz操作的主人公起名叫小明 就離譜
小明打字(實現insert delete home end)
先上題
題目分析
這個題的難點有二
1.insert鍵功能實現 鍵盤insert的功能是從當前游標的下一個字元開始,對字元逐一進行替換,當替換到隊尾後若繼續輸入則相當於在隊尾新增
2.執行時間限制25ms 其實還是挺短的 而保證不超時的方法 學名叫降低時間複雜度 如果僅僅從時間層面考慮的話,說白了就是 儘量減少遍歷,迴圈等操作,或者多考慮迴圈退出的條件,再或者儘量少在主函式外實現函式減少函式呼叫 總而言之耗時多的操作越少越好 所以這時候儲存字串的資料結構選擇就很關鍵 基本上就是陣列和連結串列 根據函式操作和功能實現確定合適的資料結構 比如此題 考慮到題目中有刪除字元的操作 正常的陣列刪除之後從下一項到結尾角標都會發生變化 相當於遍歷 因此陣列大概率超時 而單連結串列雖然縮短了刪除時的操作但是題目中還有將游標左移和右移的操作 單連結串列只有一個指標一般來說只能滿足左移或右移之中的一個 而要實現另一個操作也十分複雜 因此也不適合 所以對於這道題來說最合適的是雙向連結串列
我使用的是雙向迴圈連結串列 即將頭和尾連線起來
(其實是懶得寫尾指標)
演算法設計思路
上流程圖~
大體思路就是這樣 總的來說將操作符與字元分開識別然後對應進行相應操作
具體實現程式碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct hpxm{
char data;
struct hpxm *next;
struct hpxm *per;
};
struct hpxm *head,*now,*p;
int main(){
int change=0;//判斷是否為第一個資料
int flag=0;//判斷是插入還是替換
char xm[50050];
gets(xm);
int lenth=strlen(xm);
int i;
head=(struct hpxm*)malloc(sizeof(struct hpxm));
head->next=NULL;
head->per=NULL;
now=head;
for(i=0;i<lenth;i++){
if((xm[i]>='a'&&xm[i]<='z') || xm[i]==' '){
if(flag==0){//常規模式
if(change==0){//第一個節點
struct hpxm *insert=(struct hpxm*)malloc(sizeof(struct hpxm));
insert->data=xm[i];
insert->next=head;
head->per=insert;
now->next=insert;
insert->per=now;
now=insert;
change=1;
}
else{//插入節點
struct hpxm *insert=(struct hpxm*)malloc(sizeof(struct hpxm));
insert->data=xm[i];
insert->next=now->next;
now->next->per=insert;
now->next=insert;
insert->per=now;
now=insert;
}
}
else{
if(now->next==head){//替換模式但是在隊尾相當於加入新元素
struct hpxm *insert=(struct hpxm*)malloc(sizeof(struct hpxm));
insert->data=xm[i];
insert->next=head;
head->per=insert;
now->next=insert;
insert->per=now;
now=insert;
}
else{//加入新元素
now=now->next;
p=now;
struct hpxm *insert=(struct hpxm*)malloc(sizeof(struct hpxm));
insert->data=xm[i];
insert->next=now->next;
now->next->per=insert;
insert->per=now->per;
now->per->next=insert;
now=insert;
free(p);
}
}
}
else{
if(xm[i]=='['){//左側頭節點
now=head;
}
else{
if(xm[i]==']'){//右側頭結點[1]
if(now==head){
continue;
}
else{
now=head->per;
}
}
else{
if(xm[i]=='{'){//左移
if(now==head) continue;//頭部無法左移
else{
now=now->per;
}
}
else{
if(xm[i]=='}'){//右移
if(now->next==head) continue;//頭部無法右移
else{
now=now->next;
}
}
else{
if(xm[i]=='='){//刪除
p=now;
now->per->next=now->next;
now->next->per=now->per;
if(now->next==head){//已經到了隊尾
now=now->per;
}
else{
now=now->next;
}
free(p);
}
else{
if(xm[i]=='-'){//替換
flag=1-flag;
continue;
}
else{
continue;
}
}
}
}
}
}
}
}
p=head->next;
while(p!=head){
printf("%c",p->data);
p=p->next;
}
return 0;
}
說明:
[1] 由於我使用了雙向迴圈連結串列 所以無論是頭和尾都會和頭結點之間存在關係 因此需要對當前游標的位置進行判斷 如果只有一個頭結點的話head->per初始化為NULL 此時如果執行end操作相當於讓游標指向NULL 而呼叫或者使用不存在的東西pta會識別為段錯誤
相關文章
- "你們不要學python,python執行效率慢,去學XX吧"Python
- 今年你退稅了嗎?
- 隱藏你的 ID 吧!
- 小明上學(201812-1/CCF)———附帶思路和完整程式碼
- 如果你也剛入門React,來一起學習吧React
- 2020/12/27 G小明A+B
- DRS是啥你都不知道?不是吧,不是吧
- 我在美國退退退
- 程式設計師小明面試篇程式設計師面試
- 給你專案加個Mock吧Mock
- 為你的Laradock 裝個xdebug吧
- 【學習筆記】不會吧不會吧,不會有人還在手寫堆吧筆記
- 大學退學學信網結業怎麼辦?
- 1.想學Flutter?先學Dart吧FlutterDart
- 自我勸退式的學習方式
- 如何保證你的提案會被忽略/退件
- 不要再學 JSP 了,學 SpringBoot + Thymeleaf + Vue吧JSSpring BootVue
- 你說說對Java中SPI的理解吧Java
- 我的這套VuePress主題你熟悉吧Vue
- 使用 bearychat 通知你的系統異常吧
- “大小明”怕了沒!聽勸的《星球:重啟》預下載開啟,全宇宙為你閃爍
- 你領到國家的退稅“紅包”了嗎?
- 啊吧啊吧
- 新東方營收減少80%、辭退6萬員工、退學費200億營收
- Booom參賽作品《00後的小明》創作思路OOM
- 教你吧GV發簡訊充分VG不回你即可
- 給你的 VuePress 新增 Gitalk 評論外掛吧VueGit
- 這個需求不合理,你TM在YY吧?
- Laravel 使用 bearychat 通知你的系統異常吧Laravel
- python入門:進來吧,給自己10分鐘,這篇文章帶你直接學會pythonPython
- 面試官:你說你精通 Docker,那你來詳細說說 Dockerfile 吧面試Docker
- 來學習typescript 吧! --7 內建物件TypeScript物件
- 退網
- 退費
- 大領導給小明安排任務——Android觸控事件Android事件
- 給你的Swagger文件換套附魔皮膚吧Swagger
- 你還在這樣寫SQL嗎?趕緊改改吧SQL
- 上海某大公司:你是瞭解Redis對吧?Redis