数据结构--循环小数

该博客讨论了如何将任意真分数 N/M (0 < N < M) 转换成小数,并采用链表来表示,特别是用循环链表表示循环节。文章提出了要求编写一个名为change的函数,该函数接受整数n, m和链表头指针,将分数转换为不超过50位小数的链表表示。" 139427405,7337247,自回归与无损压缩:深度学习应用解析,"['深度学习', '神经网络', '大数据', '人工智能', '大型语言模型']

对于任意的真分数 N/M ( 0 < N < M ),均可以求出对应的小数。如果采用链表表示各个小数,对于循环节采用循环链表表示,则所有分数均可以表示为如下链表形式。
这里写图片描述
循环节

输入: N M

输出: 转换后的小数(不超过 50 )

要求: 仅编写将分数转换为小数的函数 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;  

void output( NODE * );  
void change( int, int, NODE * );  

void output( NODE * head )  
{   int k=0;  

    printf("0.");  
    while ( head->next != NULL && k<50 )  
    {   printf("%d", head->next->data );  
        head = head->next;  
        k ++;  
    }  
    printf("\n");  
}  

int main()  
{   int n, m;  
    NODE * head;  

    scanf("%d%d", &n, &m);  
    head = (NODE *)malloc( sizeof(NODE) );  
    head->next = NULL;  
    head->data = -1;  
    change( n, m, head );  
    output( head );  
    return 0;  
}  

/* PRESET CODE END - NEVER TOUCH CODE ABOVE */ 
半循环链表的简单应用,这道题其实可以偷懒,直接保存50位就好。但不推荐那么做,如果题目改成利用输入来控制循环小数输出位数的话会好一些;需要注意边界条件的控制,防止引用空指针或引用无效指针。

当小数及余数都相等时开始循环;

#include <stdio.h>  
#include <stdlib.h>  
typedef struct node  
{   int         data;  
    struct node * next;  
} NODE;  

void output( NODE * );  
void change( int, int, NODE * );  

void output( NODE * head )  
{   int k=0;  

    printf("0.");  
    while ( head->next != NULL && k<50 )  
    {   printf("%d", head->next->data );  
        head = head->next;  
        k ++;  
    }  
    printf("\n");  
}

void change(int n, int m, NODE *head)
{
    int i, posl = -1, j, flag = 0, ff = 0, k, tem = n * 10,da[10], lo[60], data[10][60], loc[60], pos;
    NODE *pq, *cah, *q, *qqq;
    for(i = 0; i < 10; i++) for(j = 0; j < 10; j++) data[i][j] = 0;
    for(i = 0; i < 10; i++) da[i] = 0;
    pos = -1;
    for(i = 0; i < 50; i++)
    {
        k = tem / m;
        loc[i] = k;
        lo[i] = tem % m;
        if (k != 0) flag = 1;
        if (flag) data[k][da[k]++] = tem % m;
        for(int l = 0; l < da[k] - 1; l++)
            if (lo[i] == data[k][l])
            {
                if (k != 0)
                    loc[i] = 0x3f3f3f3f;
                if (k == 0)
                    loc[i - 1] = 0x3f3f3f3f;
                pos = k;
                posl = l;
                ff = 1;
                break;
            }
        if (k) tem = (tem % m);
        tem *= 10;
        if (ff) break;
    }
    head->next = pq = ( NODE*)malloc(sizeof( NODE));
    int fl = 0;
    if (pos != 0) fl = 1;

    for(i = 0; i < 50;i++)
    {
        pq->data = loc[i];
        if (pq->data == pos && data[pos][posl] == lo[i])
        {
            cah = pq;
        }       
        q = ( NODE*)malloc(sizeof( NODE));
        q->next = NULL;
        pq->next = q;   
        if (pq->data == 0x3f3f3f3f && fl)
        {
            qqq->next = cah;
            break;
        }
        if (pq->data == 0x3f3f3f3f)
        {
            qqq->next = NULL;
            break;
        }
        qqq= pq;
        pq = q;
    }
}

int main()  
{   int n, m;  
    NODE * head;  

    scanf("%d%d", &n, &m);  
    head = (NODE *)malloc( sizeof(NODE) );  
    head->next = NULL;  
    head->data = -1;  
    change( n, m, head );  
    output( head );  
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值