把那些有公分母的分数加起来
Add up those fractions that have a common denominator
我有一个包含分数的文件。我必须将它的分数写成一个结构。然后我需要创建一个动态数据结构以添加那些具有共同分母的分数,但我不应该使用动态数组。你能帮我解决分数加法部分吗? (link 包含带分数的文件照片和我想要得到的结果,但现在我只能在屏幕上显示分数,但不能将它们相加)
enter image description here
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <string.h>
using namespace std;
struct fraction {
int numerator, denominator;
};
struct Node {
fraction fr;
Node* next;
};
Node* newNode(fraction fr) {
Node* p;
p = new Node;
p->fr.numerator = fr.numerator;
p->fr.denominator = fr.denominator;
p->next = NULL;
return p;
}
void addNode(Node* curr, Node** head, Node** tail) {
if (*head == NULL) {
*head = *tail = curr;
// *tail = curr;
}
else {
(*tail)->next = curr;
*tail = curr;
}
}
void outList(Node* head) {
Node* curr;
curr = head;
while (curr != NULL) {
cout << curr->fr.numerator << "/" << curr->fr.denominator << endl;;
curr = curr->next;
}
}
int main() {
fraction fr;
int n;
Node* curr = NULL;
Node* head = NULL;
Node* tail = NULL;
FILE* f;
fopen_s(&f, "testfile.txt", "r");
if (f) {
while (!feof(f)) {
fscanf_s(f, "%d", &n);
for (int i = 0; i < n; i++) {
fscanf_s(f, "%d", &fr.numerator);
fscanf_s(f, "%d", &fr.denominator);
curr = newNode(fr);
addNode(curr, &head, &tail);
}
}
fclose(f);
outList(head);
}
}
我建议先打基础,分数 class。如果你需要编写代码来访问成员,可能你违反了封装规则或紧耦合规则。
class Fraction
{
int m_numerator;
int m_denominator;
public:
Fraction(); // Default constructor, creates 0/1 fraction.
Fraction(int numerator, int denominator);
Fraction(const Fraction& f); // Copy constructor
bool Equal_Denominators(const Fraction& f);
friend std::ostream& operator<<(std::ostream& out, const Fraction& f);
};
Fraction::Fraction()
: m_numerator(0), m_denominator(1)
{ ; }
Fraction::Fraction(int numerator, int m_denominator)
: m_numerator(numerator), m_denominator(denominator)
{
if (m_denominator == 0)
{
// Throw an exception
}
}
Fraction::Fraction(const Fraction& f)
: m_numerator(f.m_numerator), m_denominator(f.m_denominator)
{ ; }
bool Fraction::Equal_Denominators(const Fraction& f)
{
return m_denomenator == f.m_denomenator;
}
std::ostream& operator<<(std::ostream& out, const Fraction& f)
{
out << "(" << f.m_numerator << "/" << "f.m_denominator" << ")";
return out;
}
以上代码片段给出了比较两个分母相等的分数、构造分数和打印分数的方法。
当您遍历列表时,您可以这样做:
if (p->fr.Equal_Denominators(fr))
{
// Add the fractions
}
您还可以通过这样做添加一些调试:
while (p != nullptr)
{
std::cout << p->fr << "\n";
}
O.P 的推荐任务:
- 重载
operator>>
以从 std::cin
或文件中读取分数。
- 重载
operator+=
以添加和分配分数。
- 超载
operator=
。
如果你从头开始构建它并使用构造函数和运算符,它可以变成这样:
#include <string>
#include <iostream>
#include <cassert>
struct Fraction {
// construct a Fraction from whole number or n, d
constexpr Fraction(int n, int d=1) noexcept : numerator(n), denominator(d) { }
// add other Fraction with matching denominator
constexpr Fraction operator +=(const Fraction &other) noexcept {
assert(denominator == other.denominator);
numerator += other.numerator;
return *this;
}
// denominator may not change but numerator does
int numerator;
const int denominator;
};
// print Fraction nicely
std::ostream & operator <<(std::ostream &out, const Fraction &fr) {
out << "(" << fr.numerator << " / " << fr.denominator << ")";
return out;
}
struct List {
struct Node {
// create Node containing fraction and attach to parent
constexpr Node(Node **parent, const Fraction &fr_) noexcept : next{*parent}, fr(fr_) {
*parent = this;
}
// printing node just prints fraction
std::ostream & print(std::ostream &out) const {
return out << fr;
}
// Nodes are always constructed as tail so initialize to nullptr
Node *next{nullptr};
Fraction fr;
};
// construct empty List
List() { }
// no copying List
List(const List &) = delete;
// no copy asignment
List & operator =(const List &) = delete;
// move construct List by taking over Nodes from other
List(List && other) : head(other.head) {
other.head = nullptr;
}
// move assign List by swapping Nodes with other
List & operator =(List &&other) {
std::swap(head, other.head);
return *this;
}
// deconstruct List by deleting all Nodes
~List() noexcept {
while(head) {
Node *t = head;
head = head->next;
delete t;
}
}
// print List as sum of fractions
std::ostream & print(std::ostream &out) const {
for (Node *node = head; node; node = node->next) {
node->print(out);
if (node->next) out << " + ";
}
return out;
}
// add Fraction to list: Either adds to existing Fraction or
// adds new Node. Fractions are sorted by denominator.
List & operator +=(const Fraction &fr) {
Node **tail;
for (tail = &head; *tail; tail = &((*tail)->next)) {
int d = (*tail)->fr.denominator;
if (d > fr.denominator) break; // denominator too large, insert Fraction before
if (d == fr.denominator) { // denominator matched, += Fraction
(*tail)->fr += fr;
return *this;
}
}
// no matching denominator, add new node
new Node(tail, fr);
return *this;
}
// add Fraction to List and move result to return value
List && operator +(const Fraction &other) && {
(*this) += other;
return std::move(*this);
}
// initialize as empty list
Node *head{nullptr};
};
// print list
std::ostream & operator <<(std::ostream &out, const List &list) {
return list.print(out);
}
// sum of 2 fraction gives a List
List operator +(const Fraction &lhs, const Fraction &rhs) {
return List{} + lhs + rhs;
}
// tired of typing so much, shorten name
using F = Fraction;
int main() {
// You can just print sums of fractions like this
// std::cout << F{1, 5} + F{4, 7} + F{3, 5} + F{1, 2} + F{2, 2} + F{2, 5} << std::endl;
// or read from stdin
List list;
int count;
std::cin >> count;
while(count-- > 0) {
int n, d;
std::cin >> n >> d;
list += F{n, d};
}
std::cout << list << std::endl;
}
我有一个包含分数的文件。我必须将它的分数写成一个结构。然后我需要创建一个动态数据结构以添加那些具有共同分母的分数,但我不应该使用动态数组。你能帮我解决分数加法部分吗? (link 包含带分数的文件照片和我想要得到的结果,但现在我只能在屏幕上显示分数,但不能将它们相加) enter image description here
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <string.h>
using namespace std;
struct fraction {
int numerator, denominator;
};
struct Node {
fraction fr;
Node* next;
};
Node* newNode(fraction fr) {
Node* p;
p = new Node;
p->fr.numerator = fr.numerator;
p->fr.denominator = fr.denominator;
p->next = NULL;
return p;
}
void addNode(Node* curr, Node** head, Node** tail) {
if (*head == NULL) {
*head = *tail = curr;
// *tail = curr;
}
else {
(*tail)->next = curr;
*tail = curr;
}
}
void outList(Node* head) {
Node* curr;
curr = head;
while (curr != NULL) {
cout << curr->fr.numerator << "/" << curr->fr.denominator << endl;;
curr = curr->next;
}
}
int main() {
fraction fr;
int n;
Node* curr = NULL;
Node* head = NULL;
Node* tail = NULL;
FILE* f;
fopen_s(&f, "testfile.txt", "r");
if (f) {
while (!feof(f)) {
fscanf_s(f, "%d", &n);
for (int i = 0; i < n; i++) {
fscanf_s(f, "%d", &fr.numerator);
fscanf_s(f, "%d", &fr.denominator);
curr = newNode(fr);
addNode(curr, &head, &tail);
}
}
fclose(f);
outList(head);
}
}
我建议先打基础,分数 class。如果你需要编写代码来访问成员,可能你违反了封装规则或紧耦合规则。
class Fraction
{
int m_numerator;
int m_denominator;
public:
Fraction(); // Default constructor, creates 0/1 fraction.
Fraction(int numerator, int denominator);
Fraction(const Fraction& f); // Copy constructor
bool Equal_Denominators(const Fraction& f);
friend std::ostream& operator<<(std::ostream& out, const Fraction& f);
};
Fraction::Fraction()
: m_numerator(0), m_denominator(1)
{ ; }
Fraction::Fraction(int numerator, int m_denominator)
: m_numerator(numerator), m_denominator(denominator)
{
if (m_denominator == 0)
{
// Throw an exception
}
}
Fraction::Fraction(const Fraction& f)
: m_numerator(f.m_numerator), m_denominator(f.m_denominator)
{ ; }
bool Fraction::Equal_Denominators(const Fraction& f)
{
return m_denomenator == f.m_denomenator;
}
std::ostream& operator<<(std::ostream& out, const Fraction& f)
{
out << "(" << f.m_numerator << "/" << "f.m_denominator" << ")";
return out;
}
以上代码片段给出了比较两个分母相等的分数、构造分数和打印分数的方法。
当您遍历列表时,您可以这样做:
if (p->fr.Equal_Denominators(fr))
{
// Add the fractions
}
您还可以通过这样做添加一些调试:
while (p != nullptr)
{
std::cout << p->fr << "\n";
}
O.P 的推荐任务:
- 重载
operator>>
以从std::cin
或文件中读取分数。 - 重载
operator+=
以添加和分配分数。 - 超载
operator=
。
如果你从头开始构建它并使用构造函数和运算符,它可以变成这样:
#include <string>
#include <iostream>
#include <cassert>
struct Fraction {
// construct a Fraction from whole number or n, d
constexpr Fraction(int n, int d=1) noexcept : numerator(n), denominator(d) { }
// add other Fraction with matching denominator
constexpr Fraction operator +=(const Fraction &other) noexcept {
assert(denominator == other.denominator);
numerator += other.numerator;
return *this;
}
// denominator may not change but numerator does
int numerator;
const int denominator;
};
// print Fraction nicely
std::ostream & operator <<(std::ostream &out, const Fraction &fr) {
out << "(" << fr.numerator << " / " << fr.denominator << ")";
return out;
}
struct List {
struct Node {
// create Node containing fraction and attach to parent
constexpr Node(Node **parent, const Fraction &fr_) noexcept : next{*parent}, fr(fr_) {
*parent = this;
}
// printing node just prints fraction
std::ostream & print(std::ostream &out) const {
return out << fr;
}
// Nodes are always constructed as tail so initialize to nullptr
Node *next{nullptr};
Fraction fr;
};
// construct empty List
List() { }
// no copying List
List(const List &) = delete;
// no copy asignment
List & operator =(const List &) = delete;
// move construct List by taking over Nodes from other
List(List && other) : head(other.head) {
other.head = nullptr;
}
// move assign List by swapping Nodes with other
List & operator =(List &&other) {
std::swap(head, other.head);
return *this;
}
// deconstruct List by deleting all Nodes
~List() noexcept {
while(head) {
Node *t = head;
head = head->next;
delete t;
}
}
// print List as sum of fractions
std::ostream & print(std::ostream &out) const {
for (Node *node = head; node; node = node->next) {
node->print(out);
if (node->next) out << " + ";
}
return out;
}
// add Fraction to list: Either adds to existing Fraction or
// adds new Node. Fractions are sorted by denominator.
List & operator +=(const Fraction &fr) {
Node **tail;
for (tail = &head; *tail; tail = &((*tail)->next)) {
int d = (*tail)->fr.denominator;
if (d > fr.denominator) break; // denominator too large, insert Fraction before
if (d == fr.denominator) { // denominator matched, += Fraction
(*tail)->fr += fr;
return *this;
}
}
// no matching denominator, add new node
new Node(tail, fr);
return *this;
}
// add Fraction to List and move result to return value
List && operator +(const Fraction &other) && {
(*this) += other;
return std::move(*this);
}
// initialize as empty list
Node *head{nullptr};
};
// print list
std::ostream & operator <<(std::ostream &out, const List &list) {
return list.print(out);
}
// sum of 2 fraction gives a List
List operator +(const Fraction &lhs, const Fraction &rhs) {
return List{} + lhs + rhs;
}
// tired of typing so much, shorten name
using F = Fraction;
int main() {
// You can just print sums of fractions like this
// std::cout << F{1, 5} + F{4, 7} + F{3, 5} + F{1, 2} + F{2, 2} + F{2, 5} << std::endl;
// or read from stdin
List list;
int count;
std::cin >> count;
while(count-- > 0) {
int n, d;
std::cin >> n >> d;
list += F{n, d};
}
std::cout << list << std::endl;
}