C语言计算分数之和(支持负数)(字符串解析)

头文件

//
//		comp_score_value.h
//
#pragma once

#define COMP_MAX_LENG 1000

typedef struct
{
	int sign;//<0负数,>0正数
	long mol; // 分子
	long den; // 分母
}score;

//解析字符串,返回所有分数的和
score count_str_score(const char *str);

源文件

//
//		comp_score_value.c
//

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

int IsNumber(char ch)
{
	if (ch >= '0' && ch <= '9')
	{
		return 1;
	}
	return 0;
}

//计算最小公倍数
long CommonMultiple(long num1, long num2)
{
	int m = num1 > num2 ? num1 : num2;

	if (num1 == 0 || num2 == 0)
	{
		return m;
	}

	while (m)
	{
		if (m % num1 == 0 && m % num2 == 0)
		{
			break;
		}
		m++;
	}
	return m;
}

int GetNumberLen(const char *str)
{
	int ret_count = 0;

	while (1)
	{
		if (*str == 0)
		{
			break;
		}

		if (IsNumber(*str))
		{
			ret_count++;
		}
		else
		{
			break;
		}

		str++;
	}

	return ret_count;
}

score count_score(score n1, score n2)
{
	score res = { 0 };
	long ComMultNum = CommonMultiple(n1.den, n2.den);
	if (ComMultNum == 0)
	{
		return res;
	}
	if (n1.den == 0)
	{
		return n2;
	}
	if (n2.den == 0)
	{
		return n1;
	}

	n1.mol = n1.mol * (ComMultNum / n1.den);
	n2.mol = n2.mol * (ComMultNum / n2.den);

	if (n1.sign < 0 && n2.sign < 0)
	{
		res.sign = -1;
		res.mol = n1.mol + n2.mol;
	}
	else if (n1.sign >= 0 && n2.sign >= 0)
	{
		res.sign = 1;
		res.mol = n1.mol + n2.mol;
	}
	else
	{
		if (n1.sign < 0)
		{
			if (n1.mol < n2.mol)
			{
				res.sign = 1;
				res.mol = n2.mol - n1.mol;
			}
			else
			{
				res.sign = -1;
				res.mol = n2.mol + n1.mol;
			}
		}
		else
		{
			if (n1.mol < n2.mol)
			{
				res.sign = -1;
				res.mol = n2.mol - n1.mol;
			}
			else
			{
				res.sign = 1;
				res.mol = n1.mol - n2.mol;
			}
		}
		
	}

	res.den = ComMultNum;
	return res;
}

score count_str_score(const char *str)
{
	score res = { 0 };
	score get = { 0 };

	for (int i = 0; i < strlen(str); i++)
	{
		if (str[i] == '-')
		{
			get.sign = -1;
		}
		else if (IsNumber(str[i]) && get.mol == 0)
		{
			get.mol = atoi(&str[i]);
			i += GetNumberLen(&str[i]) - 1;
		}
		else if (IsNumber(str[i]) && get.mol)
		{
			get.den = atoi(&str[i]);
			i += GetNumberLen(&str[i]) - 1;
			res = count_score(res, get);
			get.den = 0;
			get.mol = 0;
			get.sign = 0;
		}
	}

	return res;
}

示例

int main()
{
	//str指要进行处理的字符串
	//分配的长度可以更改,这里默认为 1000个字节
	char str[COMP_MAX_LENG] = { 0 };
	//接受输入的字符串,包含空格
	//输入的格式为: 分子/分母, 分数前面可以加'-'但不可以加'+',分数之间用空格隔开
	fgets(str, COMP_MAX_LENG, stdin);
	//去除换行
	str[strlen(str) - 1] = 0;
	//解析字符串,返回所有分数的和
	score res = count_str_score(str);

	//判断结果是否为整数,为整数输出整数,否则输出分数
	if (res.mol % res.den == 0)
	{
		if (res.sign < 0)
		{
			printf("-");
		}

		printf("%d", res.mol / res.den);
	}
	else
	{
		if (res.sign < 0)
		{
			printf("-");
		}

		printf("%d/%d", res.mol, res.den);
	}

	return 0;
}
样例输入:
1/10 2/10 3/10 8/9
样例输出:
134/90

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值