icoding复习3
icoding復(fù)習(xí)3
1. 不調(diào)用庫函數(shù),自己實(shí)現(xiàn)字符串的比較操作:該操作當(dāng)比較的兩個(gè)字符是都是字母,且兩個(gè)字符互為大小寫
 (如a和A、e和E)時(shí)認(rèn)為兩個(gè)字符相同,否則不同,其比較結(jié)果按這兩個(gè)字符的原值確定。函數(shù)的返回值規(guī)定如下:
 返回值 < 0:第一個(gè)不匹配的字符在 ptr1 中的值低于 ptr2 中的值
 返回值 == 0:兩個(gè)字符串的內(nèi)容相等
 返回值 > 0:第一個(gè)不匹配的字符在 ptr1 中的值大于在 ptr2 中的值
int str_compare(const char* ptr1, const char* ptr2);
 #include 
 #include 
 #include "dsstring.h" //請不要?jiǎng)h除,否則檢查不通過
 //又是字符串操作!!!!?
 int str_compare(const char* ptr1, const char* ptr2){
 ?? ?int i;
 ?? ?// a == 97 A == 65?
 ?? ?for(i = 0; ptr1[i] && ptr2[i]; i++){
 ?? ??? ?if(ptr1[i] != ptr2[i]){//字符相等就繼續(xù),不等判斷大小寫關(guān)系?
 ?? ??? ??? ?if(ptr1[i] + 'a' - 'A' == ptr2[i] || ptr2[i]+'a'-'A' == ptr1[i])
 ?? ??? ??? ??? ?continue;//這一步可以分開寫,沒有判斷是否ptr1[i]和ptr2[i]為字母,但是icoding監(jiān)測可以通過
 ?? ??? ??? ??? ?//其實(shí)當(dāng)兩個(gè)字符恰好相差32就不行了?
 ?? ??? ??? ?else
 ?? ??? ??? ??? ?return ptr1[i]-ptr2[i];
 ?? ??? ?}
 ?? ?}
 ?? ?//后面的代碼可以略掉?
 ?? ?if(ptr1[i])
 ?? ??? ?return (int)ptr1[i];
 ?? ?else
 ?? ??? ?return (int)ptr2[i];
 ?? ??
 }
 //解法2 icoding檢測數(shù)據(jù)不全 ! 100
 int str_compare(const char* ptr1, const char* ptr2)
 {
 ?? ?// a == 97 A == 65?
 ? ? int i;
 ? ? for (i = 0; ptr1[i] != '\0' || ptr2[i] != '\0';) {
 ? ? ? ? if (ptr1[i] == ptr2[i] ) ?//判斷字符是否相等?
 ? ? ? ? ? ? i++;
 ? ? ? ? else if(ptr1[i] <= 'z' && ptr1[i] >= 'a'&& ptr1[i] - 32 == ptr2[i])
 ? ? ? ? //判斷是否為大小寫不同的相同字母, (如果同為相同的大寫或者相同的小寫之前檢測了),?
 ? ? ? ? ?? ?i++;
 ? ? ? ? else if(ptr2[i] <= 'z' && ptr2[i] >= 'a'&& ptr2[i] - 32 == ptr1[i])
 ? ? ? ? ?? ?i++;
 ? ? ? ? else
 ? ? ? ? ? ? return ptr1[i] - ptr2[i];//可以自動轉(zhuǎn)換為int
 ?? ??? ?//注意點(diǎn)第二三個(gè)if是必要的, 不能直接判斷ptr1[1] -ptr2[i] == +-32 , 也有可能有ASC碼正好相差32的非字母字符?
 ? ? }
 ? ? return 0;
 }
//90+問題代碼
 int str_compare(const char* ptr1, const char* ptr2)
 {
 ? ? char a, b;
 ? ? int i;
 ? ? for (i = 0; ptr1[i] != '\0' && ptr2[i] != '\0'; i++) {
 ? ? ? ? a = ptr1[i];
 ? ? ? ? b = ptr2[i];
 ? ? ? ? if (a <= 'Z' && a >= 'A' && b <= 'z' && b >= 'a')
 ? ? ? ? ? ? a = a - 'A' + 'a';//有問題, 這部分的意思是a為大寫, b同時(shí)也為字母并且為小寫 , 那么
 ?? ??? ??? ?//a轉(zhuǎn)化為小寫并且與b比較, 但是如果值不等的話會改變返回值大小?
 ? ? ? ? if (b <= 'Z' && b >= 'A' && a <= 'z' && a >= 'a')
 ? ? ? ? ? ? b = b - 'A' + 'a';
 ? ? ? ? if (a == b)
 ? ? ? ? ? ? continue;
 ? ? ? ? else
 ? ? ? ? ? ? return a - b;
 ? ? }
 ? ? return ptr1[i] - ptr2[i];
 }?
2.串替換
in,原始字符串,保持不變; out, 存放替換結(jié)果的字符串; outlen,out空間的大小
 oldstr,要替換的舊字符串; newstr,替換成的新字符串
 函數(shù)返回成功替換的次數(shù),即有多少個(gè)子串被成功替換
 在替換過程中,任何情況下所得字符串(及結(jié)束符)不應(yīng)該超過 outlen,
 如果某次替換所得字符串的長度超過 outlen,則不進(jìn)行這次替換操作,整個(gè)替換操作結(jié)束。如:
 原始串為 "aaabbbccc",outlen 為14, oldstr 為 "c",newstr 為 "333" 時(shí),
 兩次替換后得 "aaabbb333333c",此時(shí)字符串占用空間為14字節(jié)。
 如果再進(jìn)行替換,則會超出 out 所占用的空間,所以停止替換操作。
 此時(shí)函數(shù)應(yīng)該返回 2, out指向的串為 "aaabbb333333c"
 再如:原始串為 "aaabbbccc",outlen 為10, oldstr 為 "bb",
 newstr 為 "123456",進(jìn)行替換后所得的串應(yīng)該為 "aaa123456"?
 (長度為9)與結(jié)束符一共占 10 個(gè)字節(jié),此時(shí)函數(shù)應(yīng)該返回 1
#include "dsstring.h"
 #include 
 #include 
int get_len(const char *str){
 ?? ?int i;
 ?? ?for(i = 0; str[i]; i++)
 ?? ??? ?;
 ?? ?return i;
 }
 //另一種寫法
 int get_len(const char* s)
 {
 ? ? int i = 0;
 ? ? while (*(s + i)) {
 ? ? ? ? i++;
 ? ? }
 ? ? return i;
 ? ? //返回值是實(shí)際長度, 不包括空字符
 }?
//理解:舊串換新串,每一個(gè)新串要求能夠全部放下并且不忽略尾部空字符, 操作的是字符指針...!?
 int str_replace(const char* in, char* out, int outlen, const char* oldstr, const char* newstr)
 {
 ?? ?int i, j = 0, ostr, nstr = 0;//i 指示in, j指示out.?
 ?? ?int n = 0;
 ?? ?
 ?? ?if(outlen <= 0) return false;?
 ?? ?
 ?? ?//out需要分配空間??? 不需要.....?
 ?? ?//下面思路整理:
 ?? ?//in的字符不與oldstr第一個(gè)字符匹配,直接復(fù)制, 進(jìn)入下一輪循環(huán)?
 ?? ?//判斷剩余空間是否足夠, 一種溢出是新串字符加out內(nèi)已有字符長度溢出,一種是in剩余字符加out已有字符溢出,直接剩余全部復(fù)制
 ?? ?//空間足夠,判斷字符是否匹配,判斷匹配成功,那么ostr指向oldstr最后一個(gè)'\0'?
 ?? ?//執(zhí)行換串操作 ,n++?
 ?? ?//最后如果串換完并且in中字符全部復(fù)制完但是j沒有達(dá)到outlen-2,放空字符?
 ?? ?for(i = 0; i < get_len(in) && j < outlen - 1;){
 ?? ?//對于j,總長度為outlen, 最后一個(gè)下標(biāo)為outlen-1,最后一個(gè)位置放'\0' ,所以j最大取outlen-2?
 ?? ?
 ?? ??? ?if(in[i] != oldstr[0]){
 ?? ??? ??? ?out[j++] = in[i++];
 ?? ??? ??? ?continue;?
 ?? ??? ?}
 ?? ??? ??? ?
 ?? ??? ?if(j + get_len(newstr) >= outlen - 1 || get_len(in) - i + j >= outlen - 1)
 ?? ??? ?{//先看剩余空間可以換串嗎 ,如果不能就剩余全部復(fù)制?
 ?? ??? ??? ?for(; j < outlen;)
 ?? ??? ??? ??? ?out[j++] = in[i++];l
 ?? ??? ??? ?return n;
 ?? ??? ?}
 ?? ??? ?
 ?? ??? ?for(ostr = 0; otsr < get_len(oldstr); ostr++)
 ?? ??? ??? ?if(oldstr[ostr] != in[i+ostr])
 ?? ??? ??? ??? ?break;
 ?? ??? ??? ??? ?
 ?? ??? ?if(ostr == get_len(oldstr) - 1){//if(!(oldstr[ostr]))等價(jià)?
 ?? ??? ??? ?for(nstr = 0; j < get_len(newstr); j++)
 ?? ??? ??? ??? ?out[j] = newstr[nstr++];
 ?? ??? ??? ?n++;
 ?? ??? ??? ?i += get_len(oldstr);
 ?? ??? ?}
 ?? ??? ?else
 ?? ??? ??? ?out[j++] = in[i++];?
 ?? ?}
 ?? ?
 ?? ?for(; j < outlen - 1; j++)
 ? ? ? ? out[j] = '\0';
 ? ? out[j] = '\0';
? ? return n;
 }
 3. 塊鏈串?
 #include 
 #include 
 #define BLOCK_SIZE 4 ? ?// 可由用戶定義的塊大小
 #define BLS_BLANK '#' ? // 用于空白處的補(bǔ)齊字符
typedef struct _block {
 ? ? char ch[BLOCK_SIZE]; ? ?//塊的數(shù)據(jù)域
 ? ? struct _block *next; ? ?//塊的指針域
 } Block;
typedef struct {
 ? ? Block *head; ? ? ? ?// 串的頭指針
 ? ? Block *tail; ? ? ? ?// 串的尾指針
 ? ? int len; ? ? ? ? ? ?// 串的當(dāng)前長度
 } BLString;
//字符串初始化函數(shù):
 void blstr_init(BLString *T) {
 ? ? T->len = 0;
 ? ? T->head = NULL;
 ? ? T->tail = NULL;
 }
 這些定義已包含在頭文件 dsstring.h 中,請實(shí)現(xiàn)塊鏈串的子串查找操作:
bool blstr_substr(BLString src, int pos, int len, BLString *sub);
 src為要查找的字符串
 pos為子串開始的下標(biāo)
 len為子串的長度
 sub在函數(shù)調(diào)用運(yùn)行前指向一個(gè)已經(jīng)初始化好的空串,在函數(shù)返回時(shí),sub指向串src從第pos個(gè)字符起長度為len的子串
 函數(shù)查找成功返回true,參數(shù)不正確返回 false
 #include 
 #include 
 #include "dsstring.h" // 請不要?jiǎng)h除,否則檢查不通過
 //滿分代碼
!!!!操作字符串長度?
 int len(const char* s)
 {
 ? ? int q = 0;
 ? ? while (*s != '\0') {//可以簡化while(*s++) q++;
 ? ? ? ? q++;
 ? ? ? ? s++;//!!!
 ? ? }
 ? ? return q;
 }
 //易錯(cuò)點(diǎn)分析:
 //1. 對于字符指針的操作, len函數(shù)書寫
 //2. 對于塊的個(gè)數(shù)邊界條件判定
 //3. 對于塊指針操作,分類討論
 //4. 尾指針置空,空白地方用'#'填充?
int StrAssign(BLString* S, const char* cstr)
 {//將cstr復(fù)制到塊鏈串S中
 ?
 ? ? int i, j, k, len;
 ? ? Block *p, *q;
 ? ? len = strlen(cstr); //len為鏈串的長度
 ? ? if (len == 0)
 ? ? ? ? return 0;
 ? ? S->len = len;
 ? ??
 ? ? j = len / BLOCK_SIZE; //j為鏈串的結(jié)點(diǎn)數(shù) ,也就是塊個(gè)數(shù)`?
 ? ? if (len % BLOCK_SIZE)
 ? ? ? ? j++;
 ? ? ? ??
 ? ? for (i = 0; i < j; i++) {
 ? ? ? ? p = (Block*)malloc(sizeof(Block));
 ? ? ? ? if (!p)
 ? ? ? ? ? ? return 0;//可以簡化
 ? ? ? ? ? ??
 ?? ??? ?//k指示每一個(gè)塊內(nèi)部字符ch[]下標(biāo)
 ? ? ? ? for (k = 0; k < BLOCK_SIZE && *cstr; k++) //將字符串ctrs中的字符賦值給鏈串的數(shù)據(jù)域
 ? ? ? ? ? ? *(p->ch + k) = *cstr++;//!!!!!!
 ? ? ? ? ? ??
 ? ? ? ? if (i == 0) //如果是第一個(gè)結(jié)點(diǎn)
 ? ? ? ? ? ? S->head = q = p; //頭指針指向第一個(gè)結(jié)點(diǎn)
 ? ? ? ? else {//q為跟蹤指針?
 ? ? ? ? ? ? q->next = p;
 ? ? ? ? ? ? q = p;
 ? ? ? ? }
 ? ? ? ? if (!*cstr) //如果是最后一個(gè)鏈結(jié)點(diǎn)
 ? ? ? ? {
 ? ? ? ? ? ? S->tail = q; //將尾指針指向最后一個(gè)結(jié)點(diǎn)
 ? ? ? ? ? ? q->next = NULL; //將尾指針的指針域置為空
 ? ? ? ? ? ? for (; k < BLOCK_SIZE; k++) //最后一個(gè)結(jié)點(diǎn)用'#'填充
 ? ? ? ? ? ? ? ? *(q->ch + k) = BLS_BLANK;
 ? ? ? ? }
 ? ? }
 ? ? return 1;
 }
 bool blstr_substr(BLString src, int pos, int len, BLString* sub)
 {
 ? ? char* t;
 ? ? if (pos < 0 || pos >= src.len || len < 1)
 ? ? ? ? return false;
 ? ? int n = pos / BLOCK_SIZE, h = pos % BLOCK_SIZE;
 ? ? Block* temp = src.head;
 ? ??
 ? ? for (int i = 0; i < n; i++)
 ? ? ? ? temp = temp->next;//temp直接指向pos位置那個(gè)塊?
 ? ??
 ? ? char str[100];
 ? ? int i = 0;
 ? ? while (i < len) {
 ? ? ? ? if (h >= BLOCK_SIZE) {
 ? ? ? ? ? ? temp = temp->next;
 ? ? ? ? ? ? h = 0;
 ? ? ? ? }?
 ?? ??? ?else {
 ? ? ? ? ? ? if (!temp || temp->ch[h] == BLS_BLANK)
 ? ? ? ? ? ? ? ? break;
 ? ? ? ? ? ? str[i++] = temp->ch[h++];
 ?? ??? ?}
 ? ? }
 ? ? str[i] = '\0';
 ? ? StrAssign(sub, str);
 ? ? return true;
 }
 ?
 ?
總結(jié)
以上是生活随笔為你收集整理的icoding复习3的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: icoding复习6 图
- 下一篇: 捆鸡是什么做的 捆鸡的简介
