串:串的基本定義及簡單應用魔王語言
串
串,於我的理解就是字串
一般認為有三種儲存方式:定長順序串,堆串,塊鏈串(個人認為比較雞肋)。定長順序串類似於普通字串,同陣列的大小一樣最長長度固定。堆串儲存在堆中,空間大小可重新分配。塊鏈串類似於連結串列,是極端節省空間的堆串。
定長順序串與堆串應用較多,定長順序串的一些操作存在截斷問題
ADT String{
資料物件:串與字串長度及當前串的最大長度
結構關係:串中的字元間存線上性關係
基本運算
initString(S) //初始化一個空串
StringCat(S,T) //將串T連線至串S末尾
StringIndexOf(S,T) //返回串S中第一次出現串T的位置
StringLastIndexOf(S,T) //返回串S中最後一次出現串T的位置
StringInsert(S,pos,T) //在串S的pos位置插入串T
StringReplace(S,from,to) //將串S中的第一個from子串替換為to
StringReplaceAll(S,from,to) //將串S中的所有子串from替換為to
StringReserve(S) //將串S翻轉
SubString(S,begin,end,T) //從串S中begin至end取子串T
}ADT String
串的一些基本概念
- 空串 S ="",串中沒有字元,strlen(S) = 0
- 空格串 " ",串中的字元全為空格
- 子串 串的一部分,設串T,串S,StringIndexOf(S,T)結果不為-1,則T為主串S的子串
- 字首 對於"abcde",“a”,“ab”,“abc”,“abcd”,“abcde”都是字首
- 字尾 對於"abcde",“e”,“de”,“cde”,“bcde”,“abcde”都是字尾
- 字首子串 從主串左側第一個字元開始的所有子串
- 字尾子串 在主串右側最後一個字元結束的所有子串
- 串相等 串長相同,串中每一個位置的字元相同
- 模式匹配 在主串中尋找子串首次出現位置的運算
- 真前/字尾(子串) 與主串不相等
堆串的一些基本運算的實現
typedef struct{
char *str;
int maxlen;
}String;
void initString(String *s) {
s->str = (char *)malloc(sizeof(char)*STR);
s->maxlen = 100;
}
int StringIndexOf(String *s, char sub[]) {//返回子串開始的下標,無則返回-1
char *str = s->str;
int i, j;
for (i = 0; i < strlen(str); i++) {
j = 0;
for (j = 0; j < strlen(sub); j++) {
if (str[i + j] != sub[j])
break;
}
if (j == strlen(sub)) {
return i;
}
}
return -1;
}
int StringIndexOf(String *s, char c) {
char *str = s->str;
for (int i = 0; i < strlen(str); i++) {
if (str[i] == c)
return i;
}
return -1;
}
int StringLastIndexOf(String *s, char c) {
char *str = s->str;
for (int i = strlen(str) - 1; i >=0; i--) {
if (str[i] == c)
return i;
}
return -1;
}
void StringCat(String *s , char sub[]) {
char *str = s->str;
char *re = NULL;
int len = strlen(str) + strlen(sub);
if ( len <= s->maxlen) {
strcat(str,sub);
}
else {
re = (char *)malloc(sizeof(char)*len + 25);
strcpy(re, str);
strcat(re, sub);
free(str);
s->str = re;
s->maxlen = len + 24;
}
}
void StringReplace(String *s, char sub[], char obj[]) {//
int pos = StringIndexOf(s, sub);
if (pos == -1)
return;
char *str = s->str;
int subLen = strlen(sub), objLen = strlen(obj);
char tem[125], *re = NULL;
strcpy(tem, &str[pos + subLen]);
int len = strlen(str) - subLen + objLen;
if (len <= s->maxlen) {
strcpy(str + pos, obj);
strcpy(&str[strlen(str)], tem);
}
else {
re = (char *)malloc(sizeof(char)*len + 25);
strncpy(re, str, pos);
strcpy(&re[pos],obj);
strcpy(&re[pos+objLen], tem);
free(str);
s->str = re;
s->maxlen = len + 24;
}
}
void StringReplace(String *s, int pos, int subLen, char obj[]) {//
char *str = s->str;
int objLen = strlen(obj);
char tem[125], *re = NULL;
strcpy(tem, &str[pos + subLen]);
int len = strlen(str) - subLen + objLen;
if (len <= s->maxlen) {
strcpy(str + pos, obj);
strcpy(&str[strlen(str)], tem);
}
else {
re = (char *)malloc(sizeof(char)*len + 25);
strncpy(re, str, pos);
strcpy(&re[pos], obj);
strcpy(&re[pos + objLen], tem);
free(str);
s->str = re;
s->maxlen = len + 24;
}
}
void StringReplaceAll(String *s, char sub[], char obj[]) {
int pos;
int subLen = strlen(sub);
while ((pos = StringIndexOf(s, sub)) != -1) {
StringReplace(s, pos, subLen, obj);
}
}
void StringInsert(String *s , int pos, char in[]) {//從指定位置開始插入字串
char *str = s->str;
char *re = NULL;
char tem[125];
strcpy(tem, &str[pos]);
int requirement = strlen(s->str) + strlen(in);
if ( requirement <= s->maxlen) {//空間足夠
strcpy(&str[pos], in);
strcpy(&str[strlen(str)], tem);
}
else {
re = (char *)malloc(sizeof(char)*(requirement + 25));
strncpy(re, str, pos);
strcpy(&(re[pos]), in);
strcpy(&re[strlen(re)], tem);
free(str);
s->str = re;
s->maxlen = requirement + 24;
}
}
char *SubString(String *s, int begin, int end, char *des) {
strncpy(des, &(s->str)[begin], end - begin + 1);
des[end - begin + 1] = 0;
return des;
}
char *StringReverse(char *str) {
int i, len = strlen(str);
char c;
for (i = 0; i < len / 2; i++) {
c = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = c;
}
return str;
}
魔王語言直譯器基於串的實現
兩條規則
(1)α->β1β2…βn
(2)(θδ1δ2…δn)->θδnθδn-1…θδ1θ
總覺得跟語法直譯器有一點點相似
但是想不到方法去自定義與上述兩條規則這種層次的規則
只實現了基於規則(1)的自定義規則,任意字串可替換為任意字串
帶括號的按規則(2)去解釋 可巢狀括號
解釋括號的演算法
void EliminateBracket(String *s, int left, int right) {//left、right 左右括號的位置
if (right <= left)
return;
char *str = s->str;
char sub[NUM];
SubString(s, left+2, right-1, sub);
char re = str[left + 1];
StringReverse(sub);
char resub[NUM*2+1];
int i, j;
for (i = 0, j = 0; i < strlen(sub); i++) {
resub[j++] = re;
resub[j++] = sub[i];
}
resub[j++] = re;
resub[j] = 0;
StringReplace(s, left, right-left+1, resub);//int pos, int subLen 這個方法的第三個引數為被替換串的串長
left = StringLastIndexOf(s, '('), right = StringIndexOf(s, ')');
EliminateBracket(s, left, right);//遞迴消除括號
}
總體實現
//全域性變數
int amount = 0;//規則條數
char source[NUM][LEN], object[NUM][LEN];//字串陣列,相同下標的兩個source串和object串分別表示一條規則中的被替換串與用來替換的串
void check_rule() {//列印規則
system("cls");
printf("\t\t高等規則\n");
printf("\tα → β1β2…βm\n");
printf("\t(θδ1δ2…δn) → θδnθδn-1… θδ1θ\n\n");
printf("\t\t當前規則\n");
int i = 0;
while (i < amount) {
printf("\t%d、\t%s → %s\n", i + 1, source[i], object[i]);
i++;
}
}
int import_rule() {//從檔案中讀入規則
int i = 0, j = 0;
FILE *fp = fopen("TheLanguageOftheKingOftheDevil.rule", "r");
if (fp == NULL) { printf("檔案丟失!\n"); return 0; }
while (fscanf(fp,"%s → %s", source[i++], object[j++]) != EOF);
if (i != j) {
printf("檔案損壞!");
}
fclose(fp);
return i-1;
}
void write_rule() {//將規則寫入檔案
int i;
FILE *fp = fopen("TheLanguageOftheKingOftheDevil.rule", "w");
for (i = 0; i < amount; i++) {
fprintf(fp, "%s → %s\n", source[i], object[i]);
}
fclose(fp);
}
void use_rule(String *s) {//使用規則
int i;
for (i = 0; i < amount;i++) {
StringReplaceAll(s, source[i], object[i]);
}
EliminateBracket(s, StringLastIndexOf(s, '('), StringIndexOf(s, ')'));
}
void add_rule() {
char from[NUM], to[NUM];
printf("請輸入要轉換的魔王詞彙:");
scanf("%s", from);
printf("請輸入該詞彙對應的內容:");
scanf("%s", to);
if (confirm()) {
strcpy(source[amount], from);
strcpy(object[amount++], to);
//儲存到檔案
write_rule();
}
else {//取消
printf("本次修改已取消");
}
}
void sort_rule() {
printf("現在一共有%d條規則,如下所示:\n", amount);
int i = 0, j;
while (i < amount) {
printf("\t%d、\t%s → %s\n", i + 1, source[i], object[i]);
i++;
}
printf("輸入%d個數表示當前規則的新序號,新序號-1則表示刪除該條規則\n,保留的規則序號按先後順序從小到大\n請輸入:",amount);
int order[NUM], cnt = 0;
char Tsource[NUM][LEN], Tobject[NUM][LEN];
for (i = 0; i < amount; i++) {
scanf("%d", &order[i]);
if (order[i] != -1)
cnt++;
strcpy(Tsource[i], source[i]);
strcpy(Tobject[i], object[i]);
}
for (i = 1; i < cnt; i++) {//根據order排序
for (j = 0; j < amount; j++) {
if (order[j] == i)
break;
}
strcpy(source[i - 1], Tsource[j]);
strcpy(object[i - 1], Tobject[j]);
}
amount = cnt;
write_rule();
printf("修改已完成\n");
}
void go_on() {
printf("按任意鍵繼續");
getch();
//getch();VS下可能需要兩個getch()
}
int confirm() {
char choice[25] , flag
相關推薦
串:串的基本定義及簡單應用魔王語言
串
串,於我的理解就是字串 一般認為有三種儲存方式:定長順序串,堆串,塊鏈串(個人認為比較雞肋)。定長順序串類似於普通字串,同陣列的大小一樣最長長度固定。堆串儲存在堆中,空間大小可重新分配。塊鏈串類似於連結串列,是極端節省空間的堆串。 定長順序串與堆串應用較多,定長順序串的一些操作存
LTE關鍵技術之一:OFDMA(OFDM基本原理及簡單例項應用)
OFDM即正交頻分複用(Orthogonal Frequency Division Multiplexing),是多載波調製的一種,通俗來說就是通過多條互相沒有關係的通道傳輸不同的資訊。OFDM現在主要用於4G通訊上
達內科技NTD1712華為vlan定義,及簡單應用
system blog interface config ethernet 地址 col tag efault Vlan的定義:是物理設備上連接的不受物理限制的用戶的一個邏輯組。
Vlan的作用:交換機可以分割沖突域,但不能分割廣播域,為了解決這個問題,
泛型的基本定義及使用
turn test 出現 span color nts extend 參數類型 子類 泛型
1、 基本概念:
範例:
class Point<T>{//T的類型未知
T x;
T y;
P
SpringMVC配置及簡單應用
新的 bat pan start rop jstl cast 版本 ans 1.在web.xml中配置前端控制器
<servlet>
<servlet-name>springmvc</servlet-name>
<servl
Django:popup彈出框簡單應用實例
type 正在 elif sta alert cte cti cnblogs sha 效果:在p1.html頁面點擊,彈出p2的彈出框,填寫數據,在 popup_response頁面處理數據
1、視圖函數:views.py
from django.shortcuts im
網絡啟動一:之IPXE初識及其簡單應用
releases 依賴包 放置 art 配置 ces sdi ftw bootsect IPXE初識及其簡單應用 最近迷上了網絡啟動這回事,查詢了部分文檔,做了基本測試和總結,以供以後參考。 概述:PXE(preboot execute environm
Tesseract 在 windows 下的安裝及簡單應用
打開 版本信息 文本 否則 選擇 分享 16px alt 運行 Tesseract 是一個開源的 OCR 引擎,可以識別多種格式的圖像文件並將其轉換成文本,最初由 HP 公司開發,後來由 Google 維護。下載地址:https://digi.bib.uni-mannhei
爬蟲基本知識及簡單生成爬蟲
(1)爬蟲是什麼:一段自動抓取網際網路資訊的程式,網際網路是URL的互相連線,爬蟲就是從一個URL出發然後走到與它相關的所有URL並且提取需要的資料;價值:獲得更多網際網路資料,得到自己想用的資料;
(2)簡單爬蟲構架:爬蟲排程端:URL管理器,包括已經爬取的URL和未訪問的URL,把待爬取的U
ETCD叢集安裝配置及簡單應用
環境配置
CentOS Linux release 7.3.1611 (Core)
etcd-v3.2.6
192.168.108.128 節點1
192.168.108.129 節點2
192.168.108.130 節點3
ETCD
陣列定義及基礎應用
java語言中,陣列是一種最簡單的複合資料型別。陣列是有序資料的集合,陣列中的每個元素具有相同的資料型別,可以用一個統一的陣列名和下標來唯一地確定陣列中的元素。陣列有一維陣列和多維陣列。
1.一維陣列的定義 type arrayName[ ]; 型別(type)可以為Java中任意的資料
Eureka概念及簡單應用
1、為什麼使用Eureka?
在Spring Cloud中我們經常使用Eureka,是因為SpringCloud對Eureka支援力度非常大 ,Eureka的社群活躍多較高,版本更新的速度快。
Eureka簡介:
Eureka是Netflix開發的服務發現元件,
06: awk基本用法 awk高階應用 總結和答疑
Top
NSD SHELL DAY06
案例1:使用awk提取文字
案例2:awk處理條件
案例3:awk綜合指令碼應用
案例4:awk流程控制
案例5:awk擴充套件應用
1 案例1:使用awk提取文字
1.1 問題
本案例要求使用awk
分享知識-快樂自己:Oracle中定義及使用同義詞
Oracle 同義詞概念:
Oracle的同義詞(synonyms)從字面上理解就是別名的意思,和檢視的功能類似,就是一種對映關係。
它可以節省大量的資料庫空間,對不同使用者的操作同一張表沒有多少差別;它擴充套件了資料庫的使用範圍,能夠在不同的資料庫使用者之間實現無縫交互;Oracle資料庫中提供
建立型:單例模式及相關應用
文章目錄
單例模式(Singleton)
優缺點
重點
懶漢式實現
執行緒不安全
synchronized關鍵字
雙重校驗鎖
靜態內部類
餓漢式實現
單例模式
結構型:裝飾者模式及相關應用
文章目錄
裝飾者(Decorator)
優缺點
應用場景
Java I/O中的應用
Spring中的應用
MyBatis中的應用
參考資料
裝飾者(Decorator)
在不
結構型:橋接模式及相關應用
文章目錄
橋接(Bridge)
優缺點
應用場景
JDBC的應用
參考資料
橋接(Bridge)
將抽象部分與它的具體實現部分分離,使它們都可以獨立地變化。
通過組合的方式建立兩個類之間
使用python操作redis及簡單應用
redis 連線例項是執行緒安全的,可以直接將redis連線例項設定為一個全域性變數,直接使用.
pip install redis
import redis
>> r = redis.Redis(host='localhost',port=6379,password='', db=0
MySQL:安裝mysqld系統及基礎應用
MySQL篇
第一章、安裝mysqld系統及基礎應用
一、安裝
注意:mysql的標點符號只能是英文的標點符號。
1、設定配置檔案。
檔案格式:文字格式
檔案位置:Mysql的主目錄下
檔名稱:my.ini
檔案內容:
[mysqld]
port=3306(port表
在Windows下Kafka的基本配置及簡單使用
首先下載zookeeper(版本zookeeper-3.4.13)和kafka(版本kafka_2.12-2.0.0),解壓就可以使用了。
1、zookeeper:在config目錄下,有zoo.conf這個配置檔案,可以配置埠和日誌儲存的位置,可以根據自己習慣更改。首先啟動zookeeper,如果環境變數