线性表题解

用链表实现分数到小数的转换 N/M(N<M)用链表实现到小数的转换,若为循环小数,则用环链表表示 立即下载

NO.3:求循环小数

题目要求

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

输入: N M k

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

要求: 仅编写将分数转换为小数的函数 change( int n, int m, NODE * head ) 。

下面给出输入输出样例:

测试输入期待的输出
测试用例 1以文本方式显示
  1. 1 8 50↵
以文本方式显示
  1. 0.125↵
测试用例 2以文本方式显示
  1. 29 33 10↵
以文本方式显示
  1. 0.8787878787↵
测试用例 3以文本方式显示
  1. 7 18 52↵
以文本方式显示
  1. 0.3888888888888888888888888888888888888888888888888888↵
测试用例 4以文本方式显示
  1. 2 7 50↵
以文本方式显示
  1. 0.28571428571428571428571428571428571428571428571428↵

 预设代码

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct node  
{   int         data;  
    struct node * next;  
} NODE;  
  
void output( NODE *, int );  
void change( int, int, NODE * );  
  
void output( NODE * head, int kk )  
{   int k=0;  
  
    printf("0.");  
    while ( head->next != NULL && k<kk )  
    {   printf("%d", head->next->data );  
        head = head->next;  
        k ++;  
    }  
    printf("\n");  
}  
  
int main()  
{   int n, m,k;  
    NODE * head;  
  
    scanf("%d %d %d", &n, &m, &k);  
    head = (NODE *)malloc( sizeof(NODE) );  
    head->next = NULL;  
    head->data = -1;  
    change( n, m, head );  
    output( head,k );  
    return 0;  
}  

信息梳理

我们先来看一下预设代码中的信息:

先是结构体NODE,包含两个元素int data以及NODE *next:

typedef struct node  
{   int  data;  
    struct node * next;  
} NODE;

然后两个基本操作,output(NODE *, int)已经给出,需要完成change(int, int, NODE * ):

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

我们想想该怎么做,根据题目意思我需要将一个真分数转化成小数,而这个小数可以是有限的,也可以是循环小数(这里注意,不用担心没有循环的情况,因为真分数都是有理数,而有理数都能转化成有限或者循环小数)。并且要求我们用链表表示小数部分,循环小数要求使用循环链表。

我们先来举个例子模拟一下(1/8):

不难发现第一位小数是,1借了一位变成10,然后10/8=1(商),第二位小数是10%8(余数),

后面以此类推。这里面涉及到三个关键步骤,乘10、取商、取余数。

代码实现

其实题目并不难,我们只要按照逻辑一步一步写就行了:为了方便直接先开两个数组来存放商和余数:

int shang[10010], yu[10010];
memset(shang, 0, sizeof(shang));

memset(yu, 0, sizeof(yu));

// memset初始化数组的操作(全部赋0)

然后就是不断地取商,取余数。那么循环什么时候停止呢?

前面已经说了,真分数是一定可以转化成一个有限小数或者循环小数的,所以能够停止循环的条件有两个:

  1. 有一次的商为0,也就是被整除了
  2. 有一次的商和余数,与之前某一次的商和余数相等,那么将会循环

那么这个循环体,我们可以这样写:

int p1 = 0, p2 = 0;     //p1、p2用来记录出现商、余数相同时的两个位置
int flag = 0;               //flag是一个标志,用来标记是不是存在循环部分
int num = n * 10;      //因为是个真分数,所以第一步就要*10操作

for (int i = 0; ; i++)    //这是默认循环条件一直为真的意思,因为循环体中有终止条件
{
    shang[i] = num / m;
    yu[i] = num % m;

    for (int j = 0; j < i; j++)
    {
        /* 当商和余数与之前相同时,即标志着出现循环
        用p1、p2记录位置,flag=1表示存在循环 */            
        if(shang[j] == shang[i] && yu[j] == yu[i])
        {
            p1 = j;
            p2 = i;

            flag = 1;
            break;
        }
    }
    num = yu[i] * 10;

    if(!num)           //如果num被除尽,变为0,则没有循环
    {
        p1 = i + 1;
        break;
    }
    
    if(flag == 1)
        break;
}

然后跳出循环后,我们就应该将之前存好的商(也就是小数部分)依次存入链表:

NODE *r = head;

for (int i = 0; i < p1; i++)          //p1一定的是循环跳出时的位置
{
        //尾插法建立链表
        NODE *q = (NODE*)malloc(sizeof(NODE));
        q->data = shang[i];
        q->next = NULL;
        r->next = q;
        r = q;
}

注意:这里一定要使用尾插法建立链表,有人问为什么。因为预设代码中output时就是从head一直往后的!!!如果用头插的话,就全反了!!!

最后我们是不是要通过flag标志来判断是不是要加上循环部分啊:

//补上循环
if (flag == 1)
{
        NODE *r_save = r;
        for (int i = p1; i < p2; i++)         //因为p1、p2是两次商、余数相同的两个位置
        {                                                 //所以p2-p1就是循环部分的长度
            NODE *q = (NODE*)malloc(sizeof(NODE));
            q->data = shang[i];
            q->next = NULL;
            r->next = q;
            r = q;
        }
        r->next = r_save->next;            //注意题目要求是循环部分用循环链表
    }
}

运行一下:

 

AC!!!过啦!!!

NO.4:求循环节 

题目要求

这道题实在与上一道的题目背景一样:

输入: N M

输出: 整个循环节

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

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

下面是部分测试样例:

测试输入期待的输出时间限制内存限制
测试用例 1以文本方式显示
  1. 1 3↵
以文本方式显示
  1. ring=1↵
  2. 3↵
1秒64M
测试用例 2以文本方式显示
  1. 1 8↵
以文本方式显示
  1. ring=0↵
  2. NULL↵
1秒64M
测试用例 3以文本方式显示
  1. 29 33↵
以文本方式显示
  1. ring=2↵
  2. 87↵
1秒64M
测试用例 4以文本方式显示
  1. 2 7↵
以文本方式显示
  1. ring=6↵
  2. 285714↵
1秒64M

预设代码

#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 ) 
{ 
} 
*/ 

信息梳理

预设代码与上一题几乎完全一样,就不再赘述了,我们来想一想怎么去找这个循环节。其实这道题可以钻一个空子,因为在上一道题写的change()函数中,已经存过遇见商、余数相同的两个位置p1、p2(又因为当时从前往后遍历的),所以p1就是第一个循环节,而p2-p1就是循环节长度ring。但是因为之前的的p1、p2变量是局部变量,跳出函数change()就失效了,但是这根本难不倒想偷懒的我!!!我直接将p1、p2用全局变量定义,不就能保留下来了吗,我真是个小天才!!!

代码实现

#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++)
    	{
    		/* 当商和余数与之前相同时,即标志着出现循环
    		用p1、p2记录位置,flag=1表示存在循环 */    		
    		if(shang[j] == shang[i] && yushu[j] == yushu[i])
    		{
    			p1 = j;
    			p2 = i;

    			flag = 1;
    			break;
    		}
    	}
    	num = yushu[i] * 10;

    	if(!num)//如果num被除尽,变为0,则没有循环
    	{
    		p1 = i + 1;
    		break;
    	}
    	if(flag == 1)
    	{
    		break;
    	}
    }
    /*根据 p1 的位置,如果没有循环,则建立完整链表;
    	如果有循环,则建立的是前缀。 */
    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 *r_save = 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 = r_save->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;
	}
}

运行一下:

 

 哈哈哈哈!!!没有问题!!!

源码

求循环小数

求循环节

加油!!!国庆不会断更的!!!(^///^)

循环小数-康明昌 讲解循环小数的数学规律 立即下载

相关推荐

用链表实现小数计算~

用单链表存储有理数N/M(N<M<100)的小数形式,若为无限循环小数,则用环链表表示;

求循环小数

对于任意的真分数 N/M ( 0 输入: N M 输出: 转换后的小数(不超过 50 ) 要求: 仅编写将分数转换为小数的函数 change( int n, int m, NODE * head ) 。 测试输入 1  8 测试输出 0.125 源代码‘ #include      #include           typedef struct node

野狼 2064

xiaoshu.rar_求循环节c_程序循环节

是一个用C语言编写的求解循环小数的循环节的程序

数据结构 3.求循环小数

数据结构 3.求循环小数

c_h_q_的博客 1596

Ubuntu下安装Hive3.1.2教程(附MySQL安装方法及安装包)

文章目录前言一、安装Hive1. 下载压缩包并解压2. 安装Hive3. 配置环境变量4. 修改配置文件二、MySQL安装与配置1. 安装MySQL2. 安装MySQL jdbc包3. 为Hive创建MySQL账号三、验证Hive安装及错误处理1. 启动Hadoop2. 启动hive3. 运行Hive实例总结 前言 Hive 的安装需要建立在 Hadoop 的之上(类似于Hbase),关于 Hadoop 的单机安装以及伪分布式安装可以参考作者的另两篇博客: Ubuntu下单机安装Hadoop详细教程(附

程序必须为人类阅读而编写,并且仅仅碰巧可以让机器执行 1万+

八、求循环节

八、求循环节 文章目录八、求循环节题目描述解题思路上机代码 题目描述 对于任意的真分数 N/M ( 0 < N < M ),均可以求出对应的小数。如果采用链表存储各位小数,对于循环节采用循环链表表示,则所有分数均可以表示为如下链表形式。 输入: N M 输出: 整个循环节 要求: 编写一个尽可能高效的查找循环节起始点的函数: NODE * find( NODE * head, int * n ) 。函数的返回值为循环节的起点(即图中的指针p),n为循环节的长度。 说明:提交程序时请同时提交将分

qq_42582489的博客 5238

YOLOv11改进入门篇 | 手把手讲解改进模块如何实现高效涨点,以SimAM注意力模块为例

本文记录的是基于SimAM注意力模块的YOLOv11目标检测方法研究。SimAM注意力模块通过优化能量函数来获得每个神经元的三维权重,而或增加计算复杂度。若是有轻量化需求的小伙伴,无参的注意力模块也许是一个不错的选择。

Limiiiing的博客 9044

icoding题解线性表

设计算法将其调整为左右两部分,左边的元素(即排在前面的)均为奇数,右边所有元素(即排在后面的)均为偶数,并要求算法的时间复杂度为O(n),空间复杂度为O(1)。试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度。设计一个高效的算法,从顺序表L中删除所有值介于x和y之间(包括x和y)的所有元素(假设y>=x),要求时间复杂度为O(n),空间复杂度为O(1)。,am),B=(b1, b2,…编写算法,在一非递减的顺序表L中,删除所有值相等的多余元素。

zxlzxl66的博客 673

【Android面试八股文】Android Application为什么是单例?

这道题相对简单,就是考察大家是否了解application的创建流程。的实例,它用来存储和处理整个全局变量的一些事情,它同时还是一个。为空的时候,才会创建,从而保证了它是一个单例对象。一样有自己的生命周期,但是它并没有那么复杂,因为。对象的创建过程,找出它为什么是单例的原因。全局进行一些配置,比如配置插件。的时候才会创建,所以说可以在。凭什么是单例,我们查看下。启动的时候都会创建一个。是怎么一步步创建的。是一个单例,即每一个。

字节卷动 532

深度学习流体力学:基于PyTorch的物理信息神经网络(PINN)完整实现

本文介绍了基于物理信息神经网络(PINN)的深度学习流体力学求解器实现。首先阐述了Navier-Stokes方程的理论基础,包括连续性方程和动量守恒方程,并解释了PINN的核心原理:将物理方程作为约束条件嵌入神经网络损失函数。以经典的lid-driven cavity流动为例,详细展示了使用PyTorch实现的全流程,包括神经网络架构设计、自动微分求解Navier-Stokes方程、多约束条件优化训练等关键环节。该求解器通过将物理方程、边界条件和初始条件整合到损失函数中,实现了对流体力学问题的端到端求解,为

源代码杀手的博客 9841

[题解]CSP-买菜(线性表)

文章目录算法思想结果分析 题目链接. 算法思想 利用线性表存储他们在装车的时间,题目要求计算他们共同在装车的时间,我就只需要求两个线性表的交集即可。同时注意,题目条件里有对于一个时间段[s, t]而言,是从时刻s到时刻t这段时间,时长为t-s,也就是说,是左开右闭区间,长下面这个样。 #include<iostream> #include<math.h> using namespace std; //买菜 int n = 0; int shopping_H[1000005] = {

东皇太一在此的博客 282

如何计算 R 中的基尼系数(附示例)

以意大利统计学家Corrado Gini命名,基尼系数是衡量人口收入分配的一种方法。基尼系数的值在 0 到 1 之间,值越高代表收入不平等越大,其中:0代表完全的收入平等(每个人的收入都一样) 1代表完全的收入不平等(一个人拥有所有收入) 您可以在此处找到按国家/地区列出的基尼系数列表。以下示例显示了使用DescTools包中的Gini()函数计算 R 中的基尼系数的两种方法。示例 1:使用个人收入计算基尼系数假设我们有以下 10 个人的年收入列表:收入:5 万美元、5 万美元、7 万美元、7 万美元、7

Mrrunsen的博客 2991

【算法题解】线性表相关

文章目录从尾到头打印链表排序链表的合并反转链表输出单链表倒数第 K 个节点两个链表的第一个公共节点删除链表中节点,要求时间复杂度为O(1) 从尾到头打印链表 来源:剑指offer 牛客网 有三种思路: 第一就是利用栈先入后出的特性完成; 第二就是将链表元素顺序存下来,然后进行数组翻转; 第三是利用递归。 1.栈思路: class Solution { public: vector<i...

qq_43145072的博客 366

【maven】maven 3.8.1 版本编译java 17的项目报错 java.lang.ExceptionInitializerError to make field private com.s

排查发现一切正常,但是内网就是不行,然后我就想把我的程序从java 11 改成java 17,然后执行编译的时候报错。这个问题是我们内网java代码升级,项目比较复杂,是从java 8 升级到java 17,然后报错。maven-compiler-plugin 3.8.1 版本编译java 17的项目,报错。然后查看一下这个项目的lombok,结果发现还是老的版本。怀疑是不是这个问题呢?使用最新的版本就可以了。

九师兄 781

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

[题解]CSP-火车购票(线性表)

文章目录算法思想结果分析 题目链接. 算法思想 使用线性表,这里用数组,因为第一次要判断同一排的座位,所以另外设置一个数组place来记录每一排剩余的座位数,这样就不需要遍历每一个座位即可得到结果。第二次判断得从头遍历,找到所需要的数量即可。 #include<iostream> using namespace std; //数组 int chair[21][6] = {};//座位编号,0 代表售出 int place[21] = {}; //每一排剩余座位数 int n, p, tic

东皇太一在此的博客 413

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

数据结构线性表选择题习题题解

数据结构线性表选择题题解

qq_64496118的博客 452

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

求链式线性表的倒数第K项——个人题解与总结

在解决此类问题时,应该注意对于K大于链表长度或者输入为空的边界情况的处理。利用队列数据结构的特性,只需要维护一个大小为K的队列,这种方法提醒我们要突破“必须要存储所有数据”的思维定式,能够想到若要确定倒数第K项元素,只需要知道最后K个元素即可。而队列的FIFO特性完美匹配了这个题目的需求。每当新元素加入时,如果A队列已满(size>K),就自动淘汰最早的元素,这种机制确保了A队列始终包含最新的也就是最后的K个元素。这种思维方式教会我们:有时候不需要掌握全部信息也能解决问题。

Daybreak_OvO的博客 433

opj线性表Placing apples 题解

4:Placing apples 总Time Limit: 1000msMemory Limit: 65536kB Description We are going to place M same apples into N same plates. There could be some empty plates. How many methods do we have? Whe

dreamjay1997的博客 864

数据结构题解:线性表的创建,插入数据,排序,合并。

#include &lt;cstdio&gt; #include &lt;cmath&gt; #include &lt;algorithm&gt; #include &lt;iostream&gt; #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define OK 1 #define ERROR 0 #define INFEASIBLR...

小宫主的博客 939

数据结构线性表题解

1,大整数加法: 链接:http://xmnd.openjudge.cn/ds201602/1/ 分析:题意很简单,给两个大整数,让你求出他们两的和 其实Java中就有专门用于大整数、大浮点数的运算,有兴趣的了解一下,用起来很方便 import java.math.BigInteger; import java.util.Scanner; public class Main { p...

swunHJ的博客 765

[题解]CSP-最小插值(线性表)

文章目录算法思想代码说明结果分析 题目链接. 算法思想 存储在线性表(数组)中之后,对它使用快排,使得数据按照升序排列,只需要从头遍历,计算相邻两个数之差,再找出所有插值的最小值即可。 代码说明 #include<algorithm>这个库函数里边有快速排序sort(),当第三个参数缺省时,默认按照升序排列,第一个和第二个参数为你需要排序的数组首地址和结束地址。 #include<iostream> #include<algorithm> using namespace

东皇太一在此的博客 395
上一篇: 线性表题解
下一篇: 程序设计方法与实践-减治法
小陈又菜
博客等级 码龄3年 680粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值