【问题标题】:Adding 3 Polynomials via Linked lists通过链表添加 3 个多项式
【发布时间】:2021-09-18 18:01:04
【问题描述】:

我试图通过链表添加 3 个多项式并设法在 C++ 中创建以下程序,该程序适用于某些情况,但不适用于所有情况。 问题是,我无法弄清楚程序为哪些测试用例提供了错误的输出(因为所有用例在hackerrank 上都不可见)。 任何有关错误来源的更正或帮助将不胜感激。

我基本上将 3 个链表作为输入,并添加了它们对应于从 0 到 100 的每个幂的系数(幂范围的限制为 0 到 100)并将它们放入一个新的链表中(带有头节点 head_node_final)和然后输出。

我得到正确答案的标准案例:

输入:

2      //2 terms in 1st linked list
1 1    // 1*x  
2 10   // 10x^2
2      //2 terms in 2nd linked list
1 0    //1
10 2   // 10x^2
2      //2 terms in 3rd linked list
10 2   //10x^2
1 3    // 1x^3

输出:

(1,3)+(30,2)+(1,1)+(1,0)    // x^3+30x^2+x+1

代码:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class node
{
public:
    int power;
    int coefficient;
    node *next;
};

int main()

{

int n1;
cin >> n1;

node *head_node1 = new node();

int inp_coefficient1;
cin >> inp_coefficient1;
head_node1->coefficient = inp_coefficient1;
int inp_power1;
cin >> inp_power1;
head_node1->power = inp_power1;
node *value = head_node1;

for (int i1 = 1; i1 <= n1; i1++)
{

    if (i1 != n1)
    {

        cin >> inp_coefficient1;
        cin >> inp_power1;
        node *value_new = new node();
        value_new->coefficient = inp_coefficient1;
        value_new->power = inp_power1;

        value->next = value_new;
        value = value->next;
    }
    else
    {
        value->next = NULL;
    }
}

int n2;
cin >> n2;

node *head_node2 = new node();

int inp_coefficient2;
cin >> inp_coefficient2;
head_node2->coefficient = inp_coefficient2;
int inp_power2;
cin >> inp_power2;
head_node2->power = inp_power2;
value = head_node2;

for (int i2 = 1; i2 <= n2; i2++)
{

    if (i2 != n2)
    {

        cin >> inp_coefficient2;
        cin >> inp_power2;
        node *value_new = new node();
        value_new->coefficient = inp_coefficient2;
        value_new->power = inp_power2;

        value->next = value_new;
        value = value->next;
    }
    else
    {
        value->next = NULL;
    }
}

int n3;
cin >> n3;

node *head_node3 = new node();

int inp_coefficient3;
cin >> inp_coefficient3;
head_node3->coefficient = inp_coefficient3;
int inp_power3;
cin >> inp_power3;
head_node3->power = inp_power3;
value = head_node3;

for (int i3 = 1; i3 <= n3; i3++)
{

    if (i3 != n3)
    {

        cin >> inp_coefficient3;
        cin >> inp_power3;
        node *value_new = new node();
        value_new->coefficient = inp_coefficient3;
        value_new->power = inp_power3;

        value->next = value_new;
        value = value->next;
    }
    else
    {
        value->next = NULL;
    }
}

node *head_node_final = new node();
node *value_final = head_node_final;

for (int power_counter = 100; power_counter >= 0; power_counter--)
{

    node *node_value1 = head_node1;
    while (node_value1 != NULL && node_value1->power != power_counter)
    {
        node_value1 = node_value1->next;
    }
    int node_1_return;
    if (node_value1 == NULL)
    {
        node_1_return = 0;
    }
    if (node_value1 != NULL)
    {
        node_1_return = node_value1->coefficient;
    }

    node *node_value2 = head_node2;
    while (node_value2 != NULL && node_value2->power != power_counter)
    {
        node_value2 = node_value2->next;
    }
    int node_2_return;
    if (node_value2 == NULL)
    {
        node_2_return = 0;
    }
    if (node_value2 != NULL)
    {
        node_2_return = node_value2->coefficient;
    }

    node *node_value3 = head_node3;
    while (node_value3 != NULL && node_value3->power != power_counter)
    {
        node_value3 = node_value3->next;
    }
    int node_3_return;
    if (node_value3 == NULL)
    {
        node_3_return = 0;
    }
    if (node_value3 != NULL)
    {
        node_3_return = node_value3->coefficient;
    }

    if ((node_1_return + node_2_return + node_3_return) != 0)
    {
        value_final->power = power_counter;
        value_final->coefficient = (node_1_return + node_2_return + node_3_return);
        value_final->next = new node();
        value_final = value_final->next;
    }
    if (power_counter == 0)
    {
        value_final = NULL;
    }
}

node *new_value_final = head_node_final;
while (new_value_final->next != NULL)
{
    cout << "(" << new_value_final->coefficient << "," << new_value_final->power << ")";
    if (new_value_final->next->next != NULL)
    {
        cout << "+";
    }
    new_value_final = new_value_final->next;
}

return 0;
}

【问题讨论】:

  • 为什么要自己写链表来添加多项式? vector 的系数不是更容易且更不容易出错吗?
  • 如果你认为问题需要一个链表,你可以使用std::list,但对于大多数东西来说std::vector 更胜一筹
  • 您的代码可以从使用函数中受益匪浅。您可以调用相同的函数 3 次,而不是编写 3 次相同的代码来创建 3 个列表。更少的重复 = 更少的代码 = 更少的错误
  • 我无法重现您的示例案例:godbolt.org/z/1zTh8oYfK
  • 令人惊讶的是,您的程序有效。只是您的输入是错误的。您在第 3 输入行中交换了 2 和 10。但是,不幸的是,您的程序与体面的设计无关。 . .

标签: c++ object linked-list polynomials


【解决方案1】:

您的程序为给定的输入生成正确的输出。

但是您的输入中有错字。在第三行中,您将功率和系数混合在一起。见这里:

2      //2 terms in 1st linked list
1 1    // 1*x  
2 10   // 10x^2 ************ Error: Should be 10 2 ************
2      //2 terms in 2nd linked list
1 0    //1
10 2   // 10x^2
2      //2 terms in 3rd linked list
10 2   //10x^2
1 3    // 1x^3

如果你纠正了这个,那么你的程序就会显示

(1,3)+(30,2)+(1,1)+(1,0) 

也是。

所以,你的程序基本上可以工作了。

但是设计不好,代码质量低。大量的重复。一切都完全修复。没有灵活性。你应该写很多很多的cmets,然后你会自己看到问题。

列表实现似乎是错误的。对于这个问题,使用列表也是错误的设计。

但也许老师告诉你使用列表。甚至可以不使用现有的std::list,而是重新发明轮子并创建自己的列表实现。

我不会在这里展示列表实现。网络中有大量的实现。参见例如here。还有很多很多。

如果我们谈论的是设计,就没有必要存储所有给定的术语。一个幂应该只有一个条目,并且应该立即将系数相加。有了这样的设计,您会立即找到解决方案,std::map 会很有用。

我基于该方法使用更高级的 C++ 创建了一个示例(您不能使用它,因为它不包含列表)。你可以从中汲取一些想法。

生成的代码相当紧凑,易于使用。

#include <iostream>
#include <numeric>
#include <vector>
#include <map>
#include <functional>

// Any other number also possible, or event a number given by a user possible
constexpr unsigned int numberOfPolynomials = 3u;

// Here we store a polynomial, consisting of terms
struct Polynomial {

    // Powers and its coefficients sortet from large to small
    std::map<int,int,std::greater<int>> terms{};

    // Overwrite extractor operator. Read a complete polynomial from any stream
    friend std::istream& operator >> (std::istream& is, Polynomial& p) {

        // First read the number of terms in the polynomial
        size_t numberOfTerms{}; is >> numberOfTerms;

        p.terms.clear(); // Delete old data
        // Read all terms. As given by input
        for (size_t index{}; index < numberOfTerms; ++index) {
            // Read coefficiend and power from stream
            int coefficient{}; int power{}; is >> coefficient >> power;

            // Add new coefficient for this power
            p.terms[power] += coefficient;
        }
        return is;
    }
    // Output all terms in thsi polynomial in the required format
    friend std::ostream& operator << (std::ostream& os, const Polynomial& p) {
        bool printPlus{};
        for (const auto& [power, coefficent] : p.terms)
            std::cout << (std::exchange(printPlus, true) ? "+" : "") << '(' << coefficent << ',' << power << ')';
        return os;
    }
    // Add 2 polynomials. Just the coefficients for the relevant powers will be added
    Polynomial operator + (const Polynomial& other) const {
        Polynomial result{*this};
        for (const auto& [power, coefficient] : other.terms) result.terms[power] += coefficient;
        return result;
    }
};

// Some driver / test code
int main() {

    // Here we will store all polynomial that should be read. Anynumber ispossible.
    std::vector<Polynomial> polynomials(numberOfPolynomials);
   
    // Read polynomials from std::cin
    for (Polynomial& polynomial : polynomials) 
        std::cin >> polynomial;

    // Sum all up
    Polynomial sum = std::accumulate(polynomials.begin(), polynomials.end(), Polynomial{});

    // Show result of the addition
    std::cout << sum;

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 2021-05-18
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    相关资源
    最近更新 更多