用getchar()和putchar()加速IO(含整型快速IO和浮点型快速IO)

****转载请注明http://blog.csdn.net/synapse7/article/details/19096049****

概述:使用getchar()和putchar(),以及math.h头文件中的一些函数,基本实现了以下函数

scanf("%u",&x)

scanf("%d",&x)

scanf("%lf",&x)

printf("%u",x)

printf("%d",x)

printf("%f",x)

printf("%*f",precision,x)

printf("%s",str)


PS:输入函数在读取输入时要多读一个字符(比如数字后面的空格或换行)以便判断是否读完字符。

但scanf没有多读一个字符(把那个字符返回到输入流了),所以若想再实现的与scanf更像的话,可在函数返回前加上

ungetc(c, stdin); ///把字符c放回到标准输入流(键盘)  

PS2:函数实现我用的引用,可以把函数参数改为int *x,同时使用函数时传入的参数为&x,这样便与scanf更近了一步。

PS3:由于在实际使用中只在读取整数时用到了返回值,可根据需要在函数中添加返回值 (-1,0,1) 。


完整代码:

#include <stdio.h>
#include <ctype.h>
#include <math.h>
const double dten[10] = {0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9};
///一般题目至多要求输出小数点后6位,此数组足矣。

char outputbuf[15]; /// 声明成全局变量可以减小开销

/*
    读非负整数
    返回值:若成功读到一个整数返回true,若读到EOF返回false
*/
inline bool unsigned_input(int& x)
{
	char c;
	while (!isdigit(c = getchar()))
		if (c == EOF) return false;
	x = 0;
	while (isdigit(c))
	{
		x = x * 10 + (c & 15);
		c = getchar();
	}
	return true;
}

/*
    读整数
    注意-0的输出为0
    返回值:若成功读到一个整数返回true,若读到EOF返回false
*/
inline bool input(int& x)
{
	char c;
	while ((c = getchar()) != '-' && !isdigit(c))
		if (c == EOF) return false;
	bool neg = false;
	if (c == '-')
		x = 0, neg = true;
	else
		x = c & 15;
	while (isdigit(c = getchar()))
		x = x * 10 + (c & 15);
	if (neg) x = -x;
	return true;
}

/*
    读正负浮点、零(也可以读整数)
    注意无法判断".14"这样的输入
    注意-0.00这样的输入使得x=-0.000000
    返回值:none
*/
inline void input(double& x)
{
	char c;
	while ((c = getchar()) != '-' && !isdigit(c))
		;
	bool neg = false;
	if (c == '-')
		x = 0, neg = true;
	else
		x = c & 15;
	while (isdigit(c = getchar()))
		x = x * 10 + (c & 15);
	if (c == '.')
	{
		double ten = 1.0;
		while (isdigit(c = getchar()))
			x += (c & 15) * (ten /= 10);
	}
	if (neg) x = -x;
}

/*
    读正负浮点、零(也可以读整数)
    并且可以判断".14"这样的输入
    注意-0.00这样的输入使得x=-0.000000
    返回值:none
*/
inline void special_input(double& x)
{
	char c;
	while ((c = getchar()) != '-' && c != '.' && !isdigit(c))
		;
	bool neg = false;
	if (c == '-')
	{
		neg = true;
		c = getchar();
	}
	x = 0;
	if (c != '.')
	{
		// 整数部分
		x = c & 15;
		while (isdigit(c = getchar()))
			x = x * 10 + (c & 15);
	}
	if (c == '.')
	{
		// 小数部分
		double ten = 1.0;
		while (isdigit(c = getchar()))
			x += (c & 15) * (ten /= 10);
	}
	if (neg) x = -x;
}

/*
    输出非负整数
    返回值:none
*/
inline void unsigned_output(int x)
{
	if (x == 0)
		putchar('0');
	else
	{
		int p = 0;
		while (x)
		{
			outputbuf[p++] = x % 10;
			x /= 10;
		}
		for (int i = p - 1; i >= 0; i--)
			putchar('0' + outputbuf[i]); // 逆序输出
	}
}

/*
    输出整数
    返回值:none
*/
inline void output(int x)
{
	if (x == 0)
		putchar('0');
	else
	{
		if (x < 0)
		{
			x = -x;
			putchar('-');
		}
		int p = 0;
		while (x)
		{
			outputbuf[p++] = x % 10;
			x /= 10;
		}
		for (int i = p - 1; i >= 0; i--)
			putchar('0' + outputbuf[i]); // 逆序输出
	}
}

/*
    输出精度为precision的浮点数(四舍五入),对-0.0输出0.000000
    如果precision为0,则只输出离x最近的整数
    返回值:none
*/
inline void output(int precision, double x)
{
	if (x < 0)
	{
		x = -x;
		putchar('-');
	}
	if (precision)
	{
		// 整数部分
		double intpart;
		x = modf(x, &intpart); // from <math.h>
		unsigned_output((int)intpart);
		//小数部分
		putchar('.');
		for (int i = 1; i < precision && x < dten[i]; ++i)
			putchar('0');// 输出小数点后有多少0
		int ten = 1;
		while (precision--)
			ten *= 10;
		unsigned_output((int)round(x * ten));
	}
	else
		unsigned_output((int)round(x));
}

/*
    输出精度为precision的浮点数(四舍五入),对-0.0输出-0.000000
    如果precision为0,则只输出离x最近的整数
    返回值:none
*/
inline void exact_output(int precision, double x)
{
	if (signbit(x)) // from <math.h>, return true if the sign of x is negative(就相当于返回x的符号位)
	{
		x = -x;
		putchar('-');
	}
	if (precision)
	{
		// 整数部分
		double intpart;
		x = modf(x, &intpart); // from <math.h>
		unsigned_output((int)intpart);
		//小数部分
		putchar('.');
		for (int i = 1; i < precision && x < dten[i]; ++i)
			putchar('0');// 输出小数点后有多少0
		int ten = 1;
		while (precision--)
			ten *= 10;
		unsigned_output((int)round(x * ten));
	}
	else
		unsigned_output((int)round(x));
}

/*
    输出精度为6的浮点数(四舍五入),对-0.0输出0.000000
    返回值:none
*/
inline void output(double x)
{
	output(6, x);
}

/*
    输出精度为6的浮点数(四舍五入),并且对-0.0输出-0.000000
    注意:按IEEE 754标准,-0.0和0.0在输出上是有区别的,但是二者实际上是相等的
    返回值:none
*/
inline void exact_output(double x)
{
	exact_output(6, x);
}

/*
    打印字符串str
    返回值:none
*/
inline void output(char *str)
{
	while (*str) putchar(*str++);
}

int main(void)
{
	int t;
	double x;
	unsigned_input(t);
	while (t--)
	{
		input(x);
		output(x);
		putchar(10);
		exact_output(x);// same as printf("%f",x);
		putchar(10);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值