C博客作業--指針


C博客作業--指針

一、PTA實驗作業

題目1:判斷回文字符串

1. 本題PTA提交列表(要提交列表,不是結果)

2. 設計思路(偽代碼或流程圖)

偽代碼:

函數傳入數組名即地址,給形參s
定義ij為循環變量
for i=0 to s【i】!='\0'
end
i--
j=0
while (1)
    如果s【i】==s【j】首尾字符相等
        如果比較的字符相遇則停止循環
        i--
        j++
    否則 返回0 結束循環
end
返回1

流程圖:

3.代碼截圖(注意,截圖,截圖,截圖。不要粘貼博客上。不用用···語法去渲染)

4.本題調試過程碰到問題及PTA提交列表情況說明。

答案錯誤
第一次沒有考慮到奇數和偶數字符串的關系,結束循環的條件只寫了ij時的情況,導致答案錯誤
解決方法:加了j
i+1的結束條件就可以了

題目2:求子串在母串中最后一次出現的地址

1. 本題PTA提交列表(要提交列表,不是結果)

2. 設計思路(偽代碼或流程圖)

傳入數組s
定義循環變量i,j,mark用於比較子串,mark2記錄地址,flag判斷是否為子串
for i=0 to s【i】!=‘\0’
    mark=i記錄比較開始的位置
    for j=0 to s【j】!=‘\0’
        如果該位置的字符與子串第一個相同比較下一個字符,都相同flag=0
        如果不相同flag=1
    如果flag==0,mark2記錄i
end
如果mark2沒有變化返回null
否則返回s【mark2】的地址

3.代碼截圖(注意,截圖,截圖,截圖。不要粘貼博客上。不用用···語法去渲染)

4.本題調試過程碰到問題及PTA提交列表情況說明。

答案錯誤
1.剛開始未有設計返回空指針,導致答案一直錯誤
解決方法:如果mark2沒有被改變,表明沒有找到過子串,所以這個時候就要返回空指針
2.只找到第一個出現子串的地址
解決方法:將程序設為反復查找,並寫再一次找到的地址會覆蓋掉第一次查找的地址,最后的結果就是最后的地址
3.返回地址的問題:剛開始習慣直接返回數組名,但是顯然不行
解決方法:用&,取出s【mark】的地址

題目3:字符串串動變化

1. 本題PTA提交列表(要提交列表,不是結果)

2. 設計思路(偽代碼或流程圖)

傳入數組p
定義循環變量i,max存最大ASCII碼最大的字符,t由於交換,code存最大碼的下標
max先取p【0】code取0
for i=1 to p【i】!=‘\0’
    if p【i】>max 將p【i】寫入max,code保存i
end
先用t存p【code】即找到最大的字符
for i=code to 1
    code的字符右移
end
t存的字符給第一個字符

3.代碼截圖(注意,截圖,截圖,截圖。不要粘貼博客上。不用用···語法去渲染)

4.本題調試過程碰到問題及PTA提交列表情況說明。


問題如圖,字符e消失,而A多了一個,明顯是交換時發生的錯誤
解決方法:最后t的值不應該給p【i-1】,因為上一輪循環,i最后跳出時有發生了遞減,所以,我的做法是直接交給p【0】

二、截圖本周題目集的PTA最后排名。

三、閱讀代碼

  • 猴子選大王
    讓N只候選猴子圍成一圈,從某位置起順序編號為1~N號。從第1號開始報數,每輪從1報到3,凡報到3的猴子即退出圈子,接着又從緊鄰的下一只猴子開始同樣的報數。如此不斷循環,最后剩下的一只猴子就選為猴王。
#include<stdio.h>  
int main()  
{  
    int i, j, k, temp;  
    int monkey[1001];//總數不能大於1000  
    unsigned int n;  
    scanf("%d", &n);//輸入猴子總數  
    for (i = 0; i < n; i++){  
        monkey[i] = i + 1;//給猴子排序,站成一排  
    }  
    for (i = n - 1; i >= 0; i--){  
        for (k = 1; k <= 3; k++){  
            temp = monkey[0];  
            for (j = 0; j < i; j++){  
                monkey[j] = monkey[j + 1];  
            }  
            monkey[i] = temp;  
        }  
    }  
    printf("%d", monkey[0]);//數組頭就是猴王  
    return 0;  
}  

功能:選出猴王
優點:通常的思路是考慮下標移動和刪除第三個位置,但是改代碼思路新穎,不去考慮下標移動和刪除,而是簡單的做數組數字移動,巧妙的將數到3這個步驟替換成數組數據的移動3次,第3個數就會剛好排到數組尾,再在剩下的數之間移動,第3的數就會漸漸排到后面,最后數組頭就是“猴王”。當初做這道題時感覺題目會很復雜,想了好久,一點思路都沒有,關鍵是圍成一個圈,數到最后還要接到數組頭,然后上網查了很多很長的代碼,直到找到這個代碼,原來十幾行就可以了。

  • 最大公共子串
    求兩個串的所有子串中能夠匹配上的最大長度是多少。
    比如:"abcdkkk" 和 "baabcdadabc",
    可以找到的最長的公共子串是"abcd",所以最大公共子串長度為4。
    下面的程序是采用矩陣法進行求解的,這對串的規模不大的情況還是比較有效的解法。
#include <stdio.h>  
#include <string.h>  
  
#define N 256  
int f(const char* s1, const char* s2)  
{  
    int a[N][N];  
    int len1 = strlen(s1);  
    int len2 = strlen(s2);  
    int i,j;  
      
    memset(a,0,sizeof(int)*N*N);  
    int max = 0;  
    for(i=1; i<=len1; i++){  
        for(j=1; j<=len2; j++){  
            if(s1[i-1]==s2[j-1]) {  
                a[i][j] =a[i-1][j-1]+1; 
                if(a[i][j] > max) max = a[i][j];  
            }  
        }  
    }  
      
    return max;  
}  
  
int main()  
{  
    printf("%d\n", f("abcdkkk", "baabcdadabc"));  
    return 0;  
}

題目思路:
動態規划的思想,a[i][j]表示到字符串s1的i位置和s2的j位置的最大公共子串的長度 ,數組初始化為0。為了方便理解,我們這么想,如果s1的字符串的第一個字符和s2的第一個字符相同,那么a[1][1] = 1;如果兩個字符串的第二個字符也相同,那么,到第二個位置的最長公共子串就等於1+1 = 2,也就是到第一個字符的公共子串的個數+1。即a[i][j] = 1+ a[i-1][j-1]。因此,我們可以從第一個位置開始遞推求出到任意一個位置的公共子串,在遞推過程中記錄最大的結果即可。

優點:巧妙的運用二維數組,通過遍歷,對每個位置子串長度做了統計和比較,大大節省了時間,同時具有極高的效率。

四、本周學習總結

1.自己總結本周學習內容。

1.使用指針基本應用
利用指針的移動,代替數組下標法提高程序效率
例:
冒號排序函數用指針代替

void bubble(int *a,int n)
{
    int *i,*j,t;
    for(i=1+a;i<a+n;i++){
        for(j=a;j<a+n-1;j++){
            if(*j>*(j+1)){
                t=*j;*j=*(j+1);*(j+1)=t;
            }
        }
    }
}

數組名即地址,定義兩個指針,遍歷數組只需指針的移動即可,下標法需要交換數組的數,指針則只要交換地址即可,效率遠比下標法搞得多
2.數組與指針是相通的,數組就是const 類型的指針,不能隨意修改,但是指針就可以
3.字符型指針,指針類型都是指向變量的類型,所以字符指針指向字符,當字符指針指向字符數組時,指針名即數組的首字符的地址,即p【0】等價於*str,p【i】等價於*(str+i)
4.字符串再C語言中會自動生成地址保存它們,所以字符串可以直接賦值給指針變量,即char *p=“string”;這個字符串叫做字符串常量。

2.羅列本周一些錯題。

6-11 報數(20 分)
報數游戲是這樣的:有n個人圍成一圈,按順序從1到n編好號。從第一個人開始報數,報到m(<n)的人退出圈子;下一個人從1開始報數,報到m的人退出圈子。如此下去,直到留下最后一個人。
本題要求編寫函數,給出每個人的退出順序編號。

void CountOff( int n, int m, int out[] ){  
    int i=0,j=0,k=0,cnt=0,a[MAXN];  
    for(i=0;i<n;i++)  
        a[i] = i+1;
    i=0;  
    while(cnt < n){  
        if(a[i]!=0) k++;  
        if(k==m){  
            j++;  
            out[i]=j;  
            k=0;  
            cnt++;  
            a[i]=0;  
        }  
        i++;  
        if(i==n) i=0;  
    }  
} 

這道題想了很久都沒有思路,上網查了一下,居然只有這么短。后來理解了這題,通過in時,i0將數組連成一個圈,將數到的數變成0而做到可以跳過這個數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM