6.求循环节

该博客主要讨论如何高效地找到分数转换为小数后的循环节,并提供了两种不同的实现方法。其中,一种利用预设的变量记录循环节起始和结束位置,另一种通过重新遍历链表寻找循环节。代码示例展示了这两种方法,涉及数据结构和算法的应用。
摘要由CSDN通过智能技术生成

6.求循环节

成绩10开启时间2021年09月17日 星期五 11:25
折扣0.8折扣时间2021年09月30日 星期四 23:55
允许迟交关闭时间2021年10月17日 星期日 23:55

对于任意的真分数 N/M ( 0 < N < M ),均可以求出对应的小数。如果采用链表存储各位小数,对于循环节采用循环链表表示,则所有分数均可以表示为如下链表形式。

输入: N M

输出: 整个循环节

要求:
 编写一个尽可能高效的查找循环节起始点的函数: NODE * find( NODE * head, int * n ) 。函数的返回值为循环节的起点(即图中的指针p),n为循环节的长度。

说明:提交程序时请同时提交将分数转换为小数的函数 change( int n, int m, NODE * head ) (前面题目中已经编写)。

预设代码

前置代码

/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */  
 
#include <stdio.h>  
#include <stdlib.h>  
typedef struct node  
{   int         data;  
    struct node * next;  
} NODE;  
  
NODE * find( NODE * , int * );  
void outputring( NODE * );  
void change( int , int , NODE * );  
void outputring( NODE * pring )  
{   NODE * p;  
    p = pring;  
    if ( p == NULL )  
        printf("NULL");  
    else  
        do  {   printf("%d", p->data);  
            p = p->next;  
        } while ( p != pring );  
    printf("\n");  
    return;  
}  
  
int main()  
{   int n, m;  
    NODE * head, * pring;  
  
    scanf("%d%d", &n, &m);  
    head = (NODE *)malloc( sizeof(NODE) );  
    head->next = NULL;  
    head->data = -1;  
  
    change( n, m, head );  
    pring = find( head, &n );  
    printf("ring=%d\n", n);  
    outputring( pring );  
  
    return 0;  
}  
  
/* Here is waiting for you. 
void change( int n, int m, NODE * head ) 
{  
} 
 
NODE * find( NODE * head, int * n ) 
{ 
} 
*/  
  
/* PRESET CODE END - NEVER TOUCH CODE ABOVE */  
测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 1 3↵
以文本方式显示
  1. ring=1↵
  2. 3↵
1秒64M0
测试用例 2以文本方式显示
  1. 1 8↵
以文本方式显示
  1. ring=0↵
  2. NULL↵
1秒64M0
测试用例 3以文本方式显示
  1. 29 33↵
以文本方式显示
  1. ring=2↵
  2. 87↵
1秒64M0
测试用例 4以文本方式显示
  1. 2 7↵
以文本方式显示
  1. ring=6↵
  2. 285714↵
1秒64M0

代码

这一题延申自上一题,加了一个find函数,返回循环节的结点位置

还是分为学长代码和我的代码,学长代码比较方便, 因为他在change函数中就已经采用了p1和p2两个数表示循环节的起始位置和终止位置,因此他的find函数就很简单。而我之前没有设这俩参数,只能再从头遍历一遍找循环节了……

学长代码

#include <string.h>    
int p1 = 0, p2 = 0;    
void change(int n,int m,NODE *head)    
{   
    int shang[10010],yushu[10010];    
    memset(shang,0,sizeof(shang));    
    memset(yushu,0,sizeof(yushu));    
    p1=0,p2=0;    
    int flag=0;    
    int num=n*10;  
    for(int i=0;;i++)    
    {  
        shang[i]=num/m;    
        yushu[i]=num%m;  
        for(int j=0;j<i;j++)    
        {              
            if(shang[j]==shang[i]&&yushu[j]==yushu[i])    
            {  
                p1=j;    
                p2=i;    
                flag=1;    
                break;    
            }    
        }  
        num=yushu[i]*10;  
        if(!num)   
        {    
            p1=i+1;    
            break;    
        }   
        if(flag==1)    
        {    
            break;    
        }    
    }   
    NODE *r=head;  
    for(int i=0;i<p1;i++)    
    {    
        NODE *q=(NODE*)malloc(sizeof(NODE));    
        q->data=shang[i];    
        q->next=NULL;    
        r->next=q;    
        r=q;    
    }    
    if (flag == 1)    
    {    
        NODE *r1=r;    
        for (int i=p1;i<p2;i++)    
        {    
            NODE *q = (NODE*)malloc(sizeof(NODE));    
            q->data=shang[i];    
            q->next=NULL;    
            r->next=q;    
            r=q;    
        }    
        r->next=r1->next;    
    }   
}  
NODE *find(NODE *head,int *n)    
{    
    if(p2>p1)  
    {  
        NODE *p=head->next;   
        *n=p2-p1;  
        for(int i=0;i<p1;i++)    
        {    
            p=p->next;    
        }    
        return p;    
    }    
    else    
    {    
        *n=0;    
        return NULL;    
    }    
}

我的代码

void change(int n,int m,NODE *head){
	
	NODE *q=(NODE*)malloc(sizeof(NODE));
	q=head;
	NODE *o=(NODE*)malloc(sizeof(NODE));
	o=head;
	
	int yushu[100]={0};
	int shang[100]={0};
	int flag=0;
	
	int len=0;
	while(n*10/m>0){
		NODE *p=(NODE*)malloc(sizeof(NODE));
		p->data=n*10/m;
		q->next=p;
		q=q->next;
		
		shang[len]=n*10/m;
		yushu[len++]=n*10%m;
		n=n*10%m; 
		if(n==0){
			q->next=NULL;
			break;
		}
		for(int i=0;i<len-1;i++){
			if(shang[i]==shang[len-1]&&yushu[i]==yushu[len-1]){
 
				int idx=0;
				while(idx<=i){
					o=o->next;	
					idx++;
						 
				}
				int idx2=0;
				NODE *r=(NODE*)malloc(sizeof(NODE));
				r=head;
				while(idx2<len-1){
					r=r->next;
					idx2++;
				}
				r->next=o;	
				flag=1;
				break;		
			}
		}
		if(flag==1){
			break;
		}
	}
}
NODE *find(NODE *head,int *n){
	NODE *num[100];//指针数组 
	int len1=0;//总长度 
	int len2=0;//循环节长度
	int start=0;
	int flag=0; 
	NODE *p=(NODE*)malloc(sizeof(NODE));
	p=head;//不要直接用head,后面head还有用 
	while(p!=NULL){
		num[len1++]=p;
		p=p->next;
		for(int i=0;i<len1-1;i++){
			if(num[i]==num[len1-1]){//位置一样,注意不是数字一样,循环了 
				len1--;//最后一个数是循环的数,和循环节重复,要删掉 
				start=i;//循环开始的地方 
				len2=len1-start; 
				flag=1;
				break; 
			}
		}
		if(flag==1){//找到起点了 
			break;
		}
	}
	NODE *pring=(NODE*)malloc(sizeof(NODE));
	if(p!=NULL){//循环的情况 
		pring=head; 
		while(start--){
			pring=pring->next;//找到循环开始结点 
		}
		*n=len2;//注意主函数中pring = find( head, &n );
		//第二个参数是一个地址,因此第二个参数要作为指针指向len2 
		return pring;
	}
	else{
		pring=p;//若能整除,则p为NULL
		*n=0;
		return pring;
	}

}

这道题还是coding的问题,没什么好说的,注释写的很清楚了

写这种题先看一下主函数是怎么调用的

祝大家天天AC

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值