C語言——第三次作業(2)


#作業要求一 ##PTA作業的提交列表 ###第一次作業 ###第二次作業

##一道編程題: ###有一個axb的數組,該數組里面順序存放了從1到a*b的數字。其中a是你大學號的前三位數字,b是你大學號的后四位數字,比如你的學號是2017023936,那么數組大小是201 x 3936,數組中順序存放了1到791136(201和3936的積)的整數. 要求用篩選法,把該數組里的質數找出並打印出來,打印格式為5個質數一行,數字間用空格隔開。

###篩選法具體做法是:先把N個自然數按次序排列起來。1不是質數,也不是合數,要划去。第二個數2是質數留下來,而把2后面所有能被2整除的數都划去。2后面第一個沒划去的數是3,把3留下,再把3后面所有能被3整除的數都划去。3后面第一個沒划去的數是5,把5留下,再把5后面所有能被5整除的數都划去。這樣一直做下去,就會把不超過N的全部合數都篩掉,留下的就是不超過N的全部質數。 ###實驗代碼

#include <stdio.h> 
#include<malloc.h>
int main(void) 
{ 
	int a, b;
	scanf("%d %d", &a, &b);        //我的學號輸入201和3969
	int i, j;
    int *as=(int *)malloc(1000000*sizeof(int));
	for(i = 2; i <= a * b; i++)
   		as[i] = i;
   		
	for(i = 2; i <= (a * b) / i; i++) 
      	for(j = i + i; j <= a * b; j = i + j)
        	as[j] = NULL; 

	for(i = 2, j = 0; i <= a * b; i++)
   		if(as[i] != NULL)
   		{
		   	printf("%7d", as[i]);
		   	j++;
		   	if(j % 5 == 0)
				printf("\n");
		} 
	return 0; 
}

###輸出結果

#作業要求二 ##題目1.輸出月份英文名(函數題) ###1.設計思路 ###- (1)算法 ####第一步:定義二維字符數組為全局變量。 ####第二步:調用定義的函數。 ####第三步:判斷n是否為月份數值,若是,返回對應字符串地址;若不是,使地址為空,返回。 ###- (2)流程圖:略。

###2.實驗代碼

char s[12][10]={"January","February","March","April","May","June","July","August","September","October","November","December"};

char *getmonth( int n )
{
	char *month;
	if(n > 0 && n <= 12)
	{
		month = s[n-1];
		return month;
	}
	month = NULL;
	return month; 
}

###完整代碼

#include <stdio.h>

char *getmonth( int n );

int main()
{
    int n;
    char *s;

    scanf("%d", &n);
    s = getmonth(n);
    if ( s==NULL ) printf("wrong input!\n");
    else printf("%s\n", s);

    return 0;
}

char s[12][10]={"January","February","March","April","May","June","July","August","September","October","November","December"};

char *getmonth( int n )
{
	char *month;
	if(n > 0 && n <= 12)
	{
		month = s[n-1];
		return month;
	}
	month = NULL;
	return month; 
}

###3.本題調試過程碰到問題及解決辦法 ####本題出現了較大的問題。 ####我做這道題目時,是先使用switch語句做的,簡單易行不易出錯。但是做完以后覺得switch語句和我們最近練習的知識點關系不大,就換了一種方式重寫,也因此出現了問題。改正錯誤其實很容易,但是我卻遲遲無法理解錯誤原因。經過數日的探討交流和之后老師的講解,終於明白了錯誤是內存分配導致的。

##題目2.查找星期(函數題) ###1.設計思路 ###- (1)算法 ####第一步:調用定義的函數。 ####第二步:定義表示星期的二維數組。 ####第三步:使用循環語句判斷是否存在同輸入字符串相同的字符數組,若存在跳出循環,結束調用;否則,返回-1。 ###- (2)流程圖

###2.實驗代碼

int getindex( char *s )
{
    int i;
    char day[7][10]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
    for(i = 0; i < 7; i++)
        if(strcmp(s,day[i]) == 0) 
			break;
    if(i == 7) 
		i = -1;
    return i;
}

###完整代碼

#include <stdio.h>
#include <string.h>
#define MAXS 80

int getindex( char *s );

int main()
{
    int n;
    char s[MAXS];

    scanf("%s", s);
    n = getindex(s);
    if ( n==-1 ) printf("wrong input!\n");
    else printf("%d\n", n);

    return 0;
}

int getindex( char *s )
{
    int i;
    char day[7][10]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
    for(i = 0; i < 7; i++)
        if(strcmp(s,day[i]) == 0) 
			break;
    if(i == 7) 
		i = -1;
    return i;
}

###3.本題調試過程碰到問題及解決辦法 ####無。

##題目3.計算最長的字符串長度(函數題) ###1.設計思路 ###- (1)算法 ####第一步:調用定義的函數。 ####第二步:使用選擇排序法判斷字符串長度。 ####第三步:返回最長的字符串地址。 ###- (2)流程圖:略。

###2.實驗代碼

int max_len( char *s[], int n )
{
	int i,t,k,j;
	for(i=0;i<(n-1);i++)
	{
		k=i;
		for(j=i+1;j<n;j++)
		{
			if(strlen(*(s+j))>strlen(*(s+k)))
			{
				k=j;
			}
		}
		if(i!=k)
		{
			t=*(s+i); *(s+i)=*(s+k); *(s+k)=t;
		}
	 }
	return strlen(*s);
}

###完整代碼

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXN 10
#define MAXS 20

int max_len( char *s[], int n );

int main()
{
    int i, n;
    char *string[MAXN] = {NULL};

    scanf("%d", &n);
    for(i = 0; i < n; i++) {
        string[i] = (char *)malloc(sizeof(char)*MAXS);
        scanf("%s", string[i]);
    }
    printf("%d\n", max_len(string, n));

    return 0;
}

int max_len( char *s[], int n )
{
	int i,t,k,j;
	for(i=0;i<(n-1);i++)
	{
		k=i;
		for(j=i+1;j<n;j++)
		{
			if(strlen(*(s+j))>strlen(*(s+k)))
			{
				k=j;
			}
		}
		if(i!=k)
		{
			t=*(s+i); *(s+i)=*(s+k); *(s+k)=t;
		}
	 }
	return strlen(*s);
}

###3.本題調試過程碰到問題及解決辦法 ####無。

##題目4.指定位置輸出字符串(函數題) ###1.設計思路 ###- (1)算法 ####第一步:調用定義的函數,定義指針,使其指向為空。 ####第二步:使用雙重循環結構,在外循環內判斷輸入字符串中是否存在與ch1匹配的字符,如存在,指針指向s[i];再次使用循環結構,內循環內判斷輸入字符串中是否存在與ch2匹配的字符,如存在,返回指針p,若不存在,內循環結束后返回指針p。 ####第三步:若外循環內在輸入字符串中無法查找到與ch1匹配的字符,使指針指向 '\0' ,返回指針p。 ###- (2)流程圖:略。

###2.實驗代碼

char *match( char *s, char ch1, char ch2 )
{
	int i, j;
	char *p = NULL;
	for(i = 0; s[i] != '\0'; i++)
	{
		if(s[i] == ch1)
		{
			p = &s[i];
			for(j = i; s[j] != '\0'; j++)
			{
				if(s[j] != ch2)
					printf("%c",s[j]);
				else
				{
					printf("%c\n",s[j]);
					return p;
				}
			}
			printf("\n");
			return p;
		}
	}
	if(s[i] == '\0')
		p = &s[i];
	printf("\n");
	return p;
}

###完整代碼

#include <stdio.h>

#define MAXS 10

char *match( char *s, char ch1, char ch2 );

int main()
{
    char str[MAXS], ch_start, ch_end, *p;

    scanf("%s\n", str);
    scanf("%c %c", &ch_start, &ch_end);
    p = match(str, ch_start, ch_end);
    printf("%s\n", p);

    return 0;
}

char *match( char *s, char ch1, char ch2 )
{
	int i, j;
	char *p = NULL;
	for(i = 0; s[i] != '\0'; i++)
	{
		if(s[i] == ch1)
		{
			p = &s[i];
			for(j = i; s[j] != '\0'; j++)
			{
				if(s[j] != ch2)
					printf("%c",s[j]);
				else
				{
					printf("%c\n",s[j]);
					return p;
				}
			}
			printf("\n");
			return p;
		}
	}
	if(s[i] == '\0')
		p = &s[i];
	printf("\n");
	return p;
}

###3.本題調試過程碰到問題及解決辦法 ####本題測試點1出現多次答案錯誤。 ####錯誤原因:當ch1找不到, ch2找到時,主函數需要輸出空行,但是由於初始代碼定義指針指向為空,無法輸出空行。 ####解決辦法:使指針指向字符串結束字符即可輸出空行。

##題目5. 奇數值結點鏈表(函數題) ###實驗代碼

#include <stdio.h>
#include <stdlib.h>

struct ListNode 
{
    int data;
    struct ListNode *next;
};

struct ListNode *readlist();
struct ListNode *getodd( struct ListNode **L );
void printlist( struct ListNode *L )
{
     struct ListNode *p = L;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode *L, *Odd;
    L = readlist();
    Odd = getodd(&L);
    printlist(Odd);
    printlist(L);

    return 0;
}

struct ListNode *readlist()
{
    struct ListNode *head=NULL,*tail=NULL,*p=NULL;
    int data;
    scanf("%d",&data);
    while(data!=-1)
    {
    	p=(struct ListNode *)malloc(sizeof(struct ListNode));    //動態內存分配
		p->data = data;    //賦值
		p->next = NULL;
		if(head == NULL)    //判斷是否為頭指針
			head=p;
		else
			tail->next=p;
		tail=p;    //使尾指針指向p所指向
		scanf("%d",&data);
	}
	return head;    //返回頭指針
}

struct ListNode *getodd( struct ListNode **L )
{
	struct ListNode *head=NULL,*head1=NULL,*p=NULL,*str=NULL,*str1=NULL;    //動態內存分配
	p=*L;    //使p指針指向L的地址
	if(p == NULL)    //p指向為空時,返回0
		return 0;
	for(; p!=NULL; p=p->next)  
	{
		if(p->data % 2 == 0)    //判斷變量p->data是否為奇數,將不是奇數的連接起來,形成鏈表
		{
			if(head == NULL)
				head = p;
			else
				str->next = p;
			str = p;
		}
		else    //將是奇數的連接起來,形成新的鏈表
		{
			if(head1 == NULL)
				head1 = p;
			else
			   str1->next = p;
			str1 = p;
		}
		
	}
	if(str1 != NULL)     //使鏈表最后指向空
		str1->next = NULL;
	if(str != NULL)     //使鏈表最后指向空
		str->next = NULL;
	*L = head;    
	return head1;
}

###本題調試過程碰到問題及解決辦法 ####問題:鏈表題目每道都存在相同的問題,就是看到題目有一種無從下手的感覺。 ####待解決方法:查找鏈表相關資料,查閱老師PPT,多加練習。

##題目6. 學生成績鏈表處理(函數題) ###實驗代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
struct stud_node 
{
    int    num;
    char   name[20];
    int    score;
    struct stud_node *next;
};

struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );

int main()
{
    int min_score;
    struct stud_node *p, *head = NULL;

    head = createlist();
    scanf("%d", &min_score);
    head = deletelist(head, min_score);
    for ( p = head; p != NULL; p = p->next )
        printf("%d %s %d\n", p->num, p->name, p->score);
    return 0;
}

struct stud_node *createlist()
{
	struct stud_node *head=NULL,*tail=NULL,*p=NULL;    //動態分配空間
	int num=0;    
	char name[20];
	int score;
	scanf("%d %s %d",&num,name,&score);
	while(num!=0)
	{
		p=(struct stud_node *)malloc(sizeof(struct stud_node));    //動態分配空間
		p->num=num;    //賦值
		strcpy(p->name,name);
		p->score=score;
		p->next = NULL;
		if(head == NULL)    //判斷是否為頭指針
			head=p;
		else
			tail->next=p;
		tail=p;
		scanf("%d",&num);
		if(num==0)    //當輸入num輸入為0時,跳出,循環結束
			break;
		else    //否則,輸入,循環繼續
			scanf("%s %d",name,&score);	
	}
	return head;
}

struct stud_node *deletelist( struct stud_node *head, int min_score )
{
	struct stud_node *ptr = head, *ptr1=head;    //動態分配內存
    if(head==NULL)    //p指向為空時,返回NULL
        return NULL;
    for(; ptr!=NULL; ptr=ptr->next)
    {
        if(ptr->score < min_score)    //判斷學生成績是否小於設置的最低成績
        {
            if(ptr==head)    ////判斷是否為頭指針
                head = ptr->next;
            else
                ptr1->next = ptr->next;
            free(ptr);    //動態分配釋放
            ptr=ptr1; 
        }
        ptr1 = ptr;
    }
    return head;
}

###本題調試過程碰到問題及解決辦法 ####問題:如圖 ####解決辦法:當學生成績小於設置的最低成績時,未設置ptr=ptr1,添加即可。 ##題目7. 鏈表拼接(函數題) ###實驗代碼


###本題調試過程碰到問題及解決辦法 ####本題在PTA時間結束時並未書寫正確,存在超時錯誤。

struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2)
{
    struct ListNode *head1=list1, *head2=list2, *p1=head1, *p2=head2, *str1=NULL, *str2=NULL,*q=NULL;
    if(p1==NULL)
		return head2;
	if(p2==NULL)
		return head1;
	for(;p2!=NULL;p2=str2)
	{  
		str2=p2->next;
		q=p2;
		for(; p1!=NULL;p1=str1->next)
    	{
          	if(p2->data <= p1->data)
          	{
			  	p2->next = p1;
                if(p1==head1)
                    head1 = p2;
                else
                    str1->next = p2;
                str1=q;
                break;
          	}
			str1 = p1;
    	}
    	if(p1==NULL)
    		str1->next = head2;
	}
	return head1; 
}

#作業要求三 ##1、學習總結 ###(1)如何理解指針數組,它與指針、數組有何關系?為何可以用二級指針對指針數組進行操作? ####答:指針數組是數組元素為指針的數組,此數組內每個元素都為指向地址的指針。二級指針可以對指針數組的地址進行操作。

###(2)將C高級第三次PTA作業(1)任何一個題目改為使用二級指針對指針數組進行操作。 ####輸出月份英文名

char *getmonth( int n ) {
   	char *s[12] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
   	char **p = &s, *q = '\0'; 
   	if(n  > 0 && n <= 12)
   		q = *(p+n-1);
   	return q;
}

###(3)用指針數組處理多個字符串有何優勢?可以直接輸入多個字符串給未初始化的指針數組嗎?為什么? ####答:當每個字符串長度不同時,可以節省空間,而且不易出現內存分配問題。 ####不可以。因為未初始化的指針可能會指向一些不確定的地址。

##2、我的Git地址

##3、點評鏈接 ###鏈接一 ###鏈接二 ###鏈接三

##4、圖表


免責聲明!

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



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