2019春第十一週做業

2019春第十一週做業

這個做業屬於哪一個課程 C語言程序設計Ⅱ
這個做業要求在哪裏 第十一週做業
我在這個課程的目標是 可以使用c語言實現基本的程序設計,以致最後可以設計出較大的項目
這個做業在哪一個具體方面幫助我實現目標 學習遞歸程序設計,宏的基本定義以及文件包含等內容
參考文獻 C語言程序設計(第3版); C Primer Plus (第6版)

1、本週完成的做業

第一部分. 選擇題








第二部分.編程題

題目1. 7-1 漢諾塔問題* (10 分)

漢諾塔是一個源於印度古老傳說的益智玩具。聽說大梵天創造世界的時候作了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤,大梵天命令僧侶把圓盤移到另外一根柱子上,而且規定:在小圓盤上不能放大圓盤,每次只能移動一個圓盤。當全部圓盤都移到另外一根柱子上時,世界就會毀滅。

請編寫程序,輸入漢諾塔圓片的數量,輸出移動漢諾塔的步驟。
輸入格式
圓盤數 起始柱 目的柱 過分柱
輸出格式
移動漢諾塔的步驟
每行顯示一步操做,具體格式爲:
盤片號: 起始柱 -> 目的柱
其中盤片號從 1 開始由小到大順序編號。
輸入樣例html

3
a c b

輸出樣例c++

1: a -> c
2: a -> b
1: c -> b
3: a -> c
1: b -> a
2: b -> c
1: a -> c

1)、實驗代碼

#include<stdio.h>
void hanio (int n, char op1, char op2, char op3);
int main ()
{
    int n;
    char op1,op2,op3; 
    char p,q;
    scanf ("%d%c",&n,&p);
    scanf ("%c%c%c%c%c",&op1,&q,&op2,&q,&op3);
    hanio (n,op1,op2,op3);
    
    return 0;
}
void hanio (int n, char op1, char op2, char op3)
{
    if (n==1)
        printf ("%d: %c -> %c\n",n,op1,op2);
    else
    {
        hanio (n-1,op1,op3,op2);
        printf ("%d: %c -> %c\n",n,op1,op2);
        hanio (n-1,op3,op2,op1);
    }
}

2)、設計思路

3)、本題調試過程碰到的問題及解決方法

如圖,在最開始寫的時候,程序中第21行 printf 語句後面輸出的是n-1的值,致使結果中全部圓盤編號都小了一,再仔細讀了一遍程序後,發現問題,將n-1改成n便可。編程

4)、運行結果圖

題目2. 7-2 估值一億的AI核心代碼 (20 分)


以上圖片來自新浪微博。
本題要求你實現一個稍微更值錢一點的 AI 英文問答程序,規則是:
不管用戶說什麼,首先把對方說的話在一行中原樣打印出來;
消除原文中多餘空格:把相鄰單詞間的多個空格換成 1 個空格,把行首尾的空格所有刪掉,把標點符號前面的空格刪掉;
把原文中全部大寫英文字母變成小寫,除了 I
把原文中全部獨立的 can youcould you 對應地換成 I canI could—— 這裏「獨立」是指被空格或標點符號分隔開的單詞;
把原文中全部獨立的 Ime 換成 you
把原文中全部的問號 ? 換成驚歎號 !
在一行中輸出替換後的句子做爲 AI 的回答。
輸入格式:
輸入首先在第一行給出不超過 10 的正整數 N,隨後 N 行,每行給出一句不超過 1000 個字符的、以回車結尾的用戶的對話,對話爲非空字符串,僅包括字母、數字、空格、可見的半角標點符號。
輸出格式:
按題面要求輸出,每一個 AI 的回答前要加上AI: 和一個空格。
輸入樣例:數組

6
Hello ?
 Good to chat   with you
can   you speak Chinese?
Really?
Could you show me 5
What Is this prime? I,don 't know

輸出樣例:markdown

Hello ?
AI: hello!
 Good to chat   with you
AI: good to chat with you
can   you speak Chinese?
AI: I can speak chinese!
Really?
AI: really!
Could you show me 5
AI: I could show you 5
What Is this prime? I,don 't know
AI: what Is this prime! you,don't know

1)、實驗代碼

代碼參考博客數據結構

#include<stdio.h>
#include<string.h>
char a[1050];
char b[1050];
int ac(char t)
{
    if((t-'a')>=0&&(t-'a')<26||(t-'A')>=0&&(t-'A')<26||(t-'0')>=0&&(t-'0')<=9)
        return 1;
        return 0;
}

int main()
{
    int i,t,n,m;
    scanf("%d",&t);
    getchar();
    while(t--)
    {
        gets(a);
        printf("%s\n",a);
        memset(b, 0, sizeof b);  
        n=strlen(a);
        printf("AI:");
        m=0;
        int o=0;
        for(i=0;i<n;i++)
        {
            if(a[i]==' ')
            {
                o=1;
            }
            else
            {
                if(o==1||i==0)
                {
                    b[m++]=' ';
                    o=0;
                }
                if((a[i]-'A')<26&&(a[i]-'A')>=0)
                {
                    if(a[i]!='I')
                    {
                        b[m++]=a[i]+32;
                    }
                    else
                    {
                        b[m++]=a[i];
                    }
                }
                else if(a[i]=='?')
                {
                    if(b[m-1]!=' ')
                    {
                        b[m++]=' ';
                    }
                    b[m++]='!';
                }
                else if(ac(a[i])==1)
                {
                    b[m++]=a[i];
                }
                else
                {
                    if(b[m-1]!=' ')
                    {
                        b[m++]=' ';
                    }
                    b[m++]=a[i];
                }
            }
        }
        b[m++]=' ';
        printf(" ");
        for(i=1;i<m-1;i++)
        {
            if(b[i]==' ')
            {
                if(ac(b[i+1])==1)
                {
                    printf(" ");
                }
                else
                {
                }
            }
            else if((b[i]-'a')>=0&&(b[i]-'a')<26)
            {
                if(b[i]=='c'&&b[i-1]==' '&&b[i+1]=='a'&&b[i+2]=='n'&&b[i+3]==' '&&b[i+4]=='y'&&b[i+5]=='o'&&b[i+6]=='u'&&b[i+7]==' ')
                {
                    printf("I can");
                    i+=6;
                }
                else if(b[i]=='c'&&b[i-1]==' '&&b[i+1]=='o'&&b[i+2]=='u'&&b[i+3]=='l'&&b[i+4]=='d'&&b[i+5]==' '&&b[i+6]=='y'&&b[i+7]=='o'&&b[i+8]=='u'&&b[i+9]==' ')
                {
                    printf("I could");
                    i+=8;
                }
                else if(b[i]=='m'&&b[i-1]==' '&&b[i+1]=='e'&&b[i+2]==' ')
                {
                    printf("you");
                    i+=1;
                }
                else
                {
                    printf("%c",b[i]);
                }
            }
            else if(b[i]=='I'&&b[i-1]==' '&&b[i+1]==' ')
            {
                printf("you");
            }
            else 
            {
                printf("%c",b[i]);
            }
        }
        printf("\n");
    }
    
    return 0;
}

2)、設計思路


3)、本題調試過程碰到的問題及解決方法

查的這個答案還算看得懂一點點,其餘的要麼是用c++,要麼是用Java,要麼是Python......其實原理就是按照題目要求去實現就行,只是很繁瑣,很麻煩。雖然我如今也不是很懂(由於這段代碼中還有部分代碼看不懂)。除此以外,在這道題的代碼中,我認識了一個新函數,之後可能會用上。0.0函數

memset()函數

memset()的函數,它能夠一字節一字節地把整個數組設置爲一個指定的值。 memset()函數在mem.h頭文件中聲明,它把數組的起始地址做爲其第一個參數,第二個參數是設置數組每一個字節的值,第三個參數是數組的長度(字節數,不是元素個數)。其函數原型爲:void memset(void,int,unsigned);學習

詳情參考:CSDN博客memset()函數

題目3. 7-3 八皇后問題 (20 分)

在國際象棋中,皇后是最厲害的棋子,能夠橫走、直走,還能夠斜走。棋手馬克斯·貝瑟爾 1848 年提出著名的八皇后問題:即在 8 × 8 的棋盤上擺放八個皇后,使其不能互相攻擊 —— 即任意兩個皇后都不能處於同一行、同一列或同一條斜線上。
如今咱們把棋盤擴展到 n × n 的棋盤上擺放 n 個皇后,請問該怎麼擺?請編寫程序,輸入正整數 n,輸出所有擺法(棋盤格子空白處顯示句點「.」,皇后處顯示字母「Q」,每兩格之間空一格)。
輸入格式
正整數 n (0 < n ≤ 12)
輸出格式
若問題有解,則輸出所有擺法(兩種擺法之間空一行),不然輸出 None。
要求:試探的順序逐行從左往右的順序進行,請參看輸出樣例2。
輸入樣例1ui

3

輸出樣例1this

None

輸入樣例2

6

輸出樣例2

. Q . . . .
. . . Q . .
. . . . . Q
Q . . . . .
. . Q . . .
. . . . Q .

. . Q . . .
. . . . . Q
. Q . . . .
. . . . Q .
Q . . . . .
. . . Q . .

. . . Q . .
Q . . . . .
. . . . Q .
. Q . . . .
. . . . . Q
. . Q . . .

. . . . Q .
. . Q . . .
Q . . . . .
. . . . . Q
. . . Q . .
. Q . . . .

1)、實驗代碼

不會,看這裏

2)、設計思路

沒怎麼看懂,不會畫....

3)、本題調試過程碰到的問題及解決方法

該種解法是經過一個較簡單的例子:n個數的全排列,所造成的剪枝函數稍加修改(改爲判斷這一行,這一列,斜線有沒有皇后),就變成了八皇后問題。

預習做業

請舉實例解釋如下幾個概念:數組指針,指針數組,指針函數,函數指針,二級指針,單向鏈表。(無實例不給分)

請用本身的理解回答。若是有引用他人的文字,請必定要標出出處(使用Markdown的連接方式)。

數組指針:是一個指針,指向數組的指針。

例如,若是想將二維數組賦給指針,則能夠

int b[3][4];
int(*pp)[4]; //定義一個數組指針,指向含4個元素的一維數組
pp = b; //將該二維數組的首地址賦給pp,也就是b[0]或&b[0],二維數組中pp=b和pp=&b[0]是等價的
pp++; //pp=pp+1,該語句執行事後pp的指向從行b[0][]變爲了行b[1][],pp=&b[1]

來實現。
詳情參考:博客1,博客2

指針數組:是一個數組,裝着指針的數組。

例如,如要將二維數組賦給一指針數組,能夠

int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];

來實現,這裏int *p[3] 表示一個一維數組內存放着三個指針變量,分別是p[0]、p[1]、p[2],因此要分別賦值。
詳情參考:博客1,博客2

指針函數:是一個函數,不過返回時,返回值是一個指針(地址)。

例如,int *fun(int x,int y); 就是一個簡單的自定義的一個指針函數的聲明寫法。它的定義能夠根據本身的目的去定義。其返回值是一個 int 類型的指針,是一個地址。
詳情參考:博客1,博客2

函數指針:指向函數的指針。是一個指針變量,是一個指向函數的指針變量。

例如,int (fun)(int x,int y); 就是一個函數指針的聲明格式。函數指針是須要把一個函數的地址賦值給它,有兩種寫法:fun = &Function;fun = Function; 取地址運算符&不是必需的,由於一個函數標識符就表示了它的地址,若是是函數調用,還必須包含一個圓括號括起來的參數表。能夠用x = (fun)(); 的方式調用函數指針。
詳情參考:博客1,博客2

二級指針:指向指針的指針。當你想對一個地址作修改的時候,就要用到二級指針。

例如,

void buf ( int **a )
{
    (  *a) = ( int* )malloc ( sizeof ( int ) );
    ( **a )= 1;
    printf ( "%d",**a );
}
int main( int argc, char *argv[] )
{
    int  *a;
    buf ( &a );
       //printf ( "%d",*a );
}

當你要給*a賦值的時候,發現他是一個指針,沒有內存空間來存儲值,不能直接給他賦值,要給他先建立一個內存空間。固然你能夠直接的malloc ()在主函數裏。這個就不說了。可是,若是你想要在調用一個函數實現呢?你能夠這樣想,若是我有一個東西,能接受個人這個指針的地址,這樣就能夠在調用的函數裏面經過他的地址,就能夠在調用的函數裏面,進行malloc (),而這個能存儲地址的就是二級指針。
詳情參考:博客

單向鏈表:

單向鏈表鏈表是鏈表的一種。
鏈表是什麼? 鏈表是一種常見而重要的動態存儲分佈的數據結構。能夠將一條鏈表想象成環環相扣的結點,就如日常所見到的鎖鏈同樣。鏈表內包含不少結點(固然也能夠包含零個結點)。其中每一個結點的數據空間通常會包含一個數據結構(用於存放各類類型的數據)以及一個指針,該指針通常稱爲next,用來指向下一個結點的位置。因爲下一個結點也是鏈表類型,因此next的指針也要定義爲鏈表類型。
鏈表的結構

例如:

typedef struct LinkList                                                                                                                                     
{
         int Element;
         LinkList * next;
}LinkList;

就定義了一種鏈表的結構類型。
詳情參考:鏈表;C語言程序設計(第3版) P285 。
單向鏈表的組成以下圖,

詳情參考:單向鏈表的創建,可參考:C語言程序設計(第3版) P286;博客
用鏈表代替數組進行數據的存儲與操做有兩優勢:1、不須要事先定義存儲空間大小,能夠實時動態分配,內存使用效率高;2、能夠方便地插入新元素(結點),是信息庫保持排序狀態,操做效率高。

學習進度條

周/日期 這周所花的時間 代碼行數 學到的知識點簡介 目前比較迷惑的問題
3/2-3/8 三天六小時 50 一、定義、運用文件指針;二、如何打開、關閉文件三、如何讀出指定文件中的數據;四、如何向指定文件中寫入數據; 字符、字符串有什麼區別?兩者輸入、輸出有沒有很大不一樣?什麼纔算字符串?什麼算字符?在文件中兩者有沒有差異?
3/9-3/15 四天三小時 180 一、運用二維數組解決問題,矩陣的判斷;二、對一組數的全部子數組求和 如何在輸出時利用數組的性質
3/16-3/22 三天八小時 210 一、二維數組加深理解,二維數組與矩陣;二、選擇排序法解決問題;三、二分查找法 二分查找法這周沒練習,只是看看書上例題大體懂了,不知道真正應用時可否掌握。
3/23-3/29 三天兩小時 120 一、判斷回;文二、字符數組的概念及其簡單運用;三、一些簡單的與字符數組相關的暫時沒接觸補充知識,一些函數,用法等。 在做業運用文件指針時,一開始老是出現從文件裏輸不出來結果,打印不出來,後來發現可能與本身輸入時格式未搞好,原本不該該出現的空格出現了,致使打印不出來結果。文件指針還不是很熟練
3/30-4/5 兩天 150 一、指針的含義,變量、地址、指針變量等間的關係;二、指針變量的初始化,運用指針作一些簡單運算;三、指針與數組之間的關係 在用指針處理字符串時,應怎樣定義指針變量
4/6-4/12 三天 200 一、更深一步掌握指針與數組間的關係;二、懂得指針能夠實現數組的一些功能;三、指針在碰到字符數組時的應用 在代碼中,若是遇到要輸出單個字符,%s與%c有什麼區別? scanf()與 getchar 兩種輸入方式有區別嗎?會不會在有些狀況下能影響到輸出結果?
4/13-4/19 兩天 170 一、學習了與字符串有關的一些字符串處理函數;二、學習了利用指針實現內存動態分配 究竟什麼狀況下采用內存動態分配?具體要採用哪種動態內存分配?
4/20-4/26 兩天 135 一、學習告終構及結構變量的定義與運用 若是運用遞歸函數解決問題,雖然使代碼簡化了,更美觀了。但會致使相同的運算重複進行,佔內存。感受遞歸弊大於利。
4/27-5/3 一天 一、複習告終構與數組、指針間的關係,二者之間是如何進行替換利用;
5/4-5/10 三天 165 一、學習了遞歸程序的設計;二、宏的基本定義;三、文件包含等內容; 鏈表知識點看了看,不是很懂

3、學習感悟

本週在作題時,剛看到選擇題都懵了。覺得是我上課錯過了什麼,不少題都不肯定答案,在翻過書後才發覺,原來是沒怎麼講。看過書後有了一點概念。關鍵仍是編程題,哇,感受編程題難度不小,不,是很大。第一題是在看了例題後,照葫蘆畫瓢勉強作出來的。後面兩道題,看過以後,第一反應是老師是否是出錯題目了。以後助教在羣裏喊話,意思是盡力寫,寫不出來也要有思路,瞬間就認爲本身不須要寫出來,寫思路就行,但我看了PTA裏的提交列表後,發現有很多人都作了出來,有用c++的,有用c的,而後就感受不能放棄啊,實在不行就搜啊,只要本身看懂了,理解了,記住了,掌握了,也行。最後也勉勉強強理解了第二道編程題,價值一億的代碼。

結對編程感想

結對時,隊友選擇題答案不肯定,互相之間討論了兩下。到編程題時,因爲題目較難,隊友也不肯直接跳過,兩我的上網搜答案,答案看不懂就互相說一說本身的想法,先將答案搞懂。

表格-折線圖

時間 累計代碼行數 累計博客字數
第一週 80 275
第二週 50 883
第三週 180 1303
第四周 210 1849
第五週 120 1988
第六週 150 2717
第七週 200 3000
第八週 170 2820
第九周 135 2855
第十週 3945
第十一週 165 4934

相關文章
相關標籤/搜索