0

所以我的程序的截止日期已经过去了,我留下了很多(re:all)失败的测试和一些我不熟悉的其他错误。我真的不在乎等级。如果我不理解内容,那无论如何都是徒劳的。如果您有时间并想与我一起完成一些调试,我会全神贯注,并且真的很想找出我做错了什么。我将在下面发布所有代码和头文件。

#ifndef BIGNUM_H_INCLUDED
#define BIGNUM_H_INCLUDED

#include <string>
#include <iostream>
using namespace std;

class bignum
{
public:
// Constructors.
bignum();
bignum(int num_digits);
bignum(const string &digits);
bignum(const bignum &other);

// Destructors.
~bignum();

// Assignment operator.
bignum &operator=(const bignum &other);

// Accessors
int digits() const;
int as_int() const;
void bignum::setdigits(const int data[])const;
string as_string() const;
void print(ostream &out) const;
bignum add(const bignum &other) const;
bignum multiply(const bignum &other) const;
bool equals(const bignum &other) const;
int PublicNumberTest;

private:
// Pointer to a dynamically-allocated array of integers.  The last
// digit (ones place) is stored in digit[0], the next-to last (tens
// place) in digit[1], and so on.
int *digit;
// Number of digits in the array, not counting leading zeros.
// Should be less than or equal to the allocated size of digit.
int ndigits;
};
#endif




here is the cpp:


#include <iostream>
#include <string>
#include <math.h>
using namespace std;
#include "bignum.h"
void pause_215(bool have_newline);
bool test_bignum();

// Method implementations here.
bignum::bignum(){
digit[0];
}

bignum::~bignum(){
delete[] digit;
}

bignum::bignum(int num_digits)
{
digit = new int[];
for (int i = 0; i < num_digits; i++)
    digit[i] = 9;
}

bignum::bignum(const string &digits){
bool start = false;
int NumofDigits = 0;
int *digit = new int[digits.size()];
for (int i = 0; i < digits.size(); i++){ //will determine if the char at ith slot                                                can be converted
    if (!isdigit(digits[i])){
        break; //if you can't convert, break
    }
    else{
        int number = digits[i] - '0'; //converts char to #
        if ((number == 0) && (start = false)) //if the digit is a zero and the sequence has yet to start, do not enter the value
            continue;
        digit[NumofDigits] = number;
        start = true;
        NumofDigits++;
    }
}
if (NumofDigits == 0)
    digit[0] = 0;
}

bignum::bignum(const bignum &other){

ndigits = other.ndigits;
digit = new int[];
for (int i = 0; i < ndigits; i++)
    digit[i] = other.digit[i];
}

bignum& bignum::operator = (const bignum & other){

if (this == &other)
    return *this;
delete[] digit;
ndigits = other.ndigits;
digit = new int[];
for (int i = 0; i < ndigits; i++)
    digit[i] = other.digit[i];

return *this;
}

int bignum::digits() const {

return ndigits;
}

int bignum::as_int() const {  //I was using math.h and pow here, but it was giving a
                              //warning about conflicted data types so I did it the 
int as_int = 0;           //long way. I haven't tested this yet. Just wrote it. 
int pow_of_ten = 1;
for (int i = 0; i < ndigits; i++)
{   
    as_int = as_int + digit[i] * pow_of_ten;
    for (int k = 0; k == i; k++)
        pow_of_ten = 10 * pow_of_ten;
}
return as_int;
}
string bignum::as_string() const{


char *digit_char = new char[];
for (int i = 0; i < ndigits; i++){
    digit_char[i] = digit[i];
}
string str(digit_char);
return str;        //this isn't working because I just got this thing to compile at     11:25 and I've had 20 minutes to debug it. ndigits is not getting
}                       //initialized, which is why the first set         of tests is failing. 

void bignum::print(ostream &out) const{
    for (int i = 0; i < ndigits; i++)
    {
        if (i > 0)
        out << digit[i];
    }
    out << endl;
}
bignum bignum::add(const bignum& other) const{

int carry = 0;
int larger = 0;
int numofdigits = 0;
int currentDigit = 0;
int size_other = other.ndigits;
int *b = new int[];
int *total = new int[];
int temp_sum = 0;
if (size_other > ndigits)
    larger = size_other;
else
    larger = ndigits;
for (int i = 0; i < larger + 1; i++){
    int aa = 0;
    int bb = 0;
    if (i < ndigits)
        aa = digit[i];
    if (i < other.ndigits)
        bb = b[i];
    temp_sum = aa + bb + carry;
    currentDigit = temp_sum % 10;
    total[numofdigits] = currentDigit;
    numofdigits++;
    carry = temp_sum / 10;
}
bignum sum(numofdigits);
for (int j = 0; j < numofdigits; j++)
    sum.digit[j] = total[j];
return sum;
}

//void bignum::setdigits(const int *temp_row) const{
//  digit = temp_row; 
//}

bignum bignum::multiply(const bignum& other) const{
bignum product;
int carry = 0;
int sum = 0;
int j = 0;
int *temp_row = new int[];
int count = 0;
for (int i = 0; i < ndigits-1; i++){
    carry = 0;
    temp_row[i] = 0;
    for (j; j < other.ndigits - 1; j++){
        sum = digit[i] * other.digit[j] + carry;
        temp_row[i + j] = sum % 10;
        carry = sum / 10;
        count++;
    }
    if (carry>0){
        temp_row[i + j] = carry;
        count++;
    }
    bignum row(count);
    for (int k = 0; k < count; k++){
        row.digit[i] = temp_row[i];
    }

        product = product.add(row);
} return product;
}

bool bignum::equals(const bignum& other) const{
bool equal = true;
if (ndigits != other.ndigits)
    return false;
for (int i = 0; i < ndigits; i++){
    if (digit[i] != other.digit[i])
        return false;
    else;
}
}

// Ordinary (nonmember) functions here.
int main()
{
bool success = test_bignum();
if (success) {
    cout << "All tests succeeded, good job!" << endl;
} else {
    cout << "Some tests failed, keep trying!" << endl;
}

pause_215(false);
return 0;
}


bool test_bignum()
{
// Current test number.  Be sure to increment this before each test!
int curr_test = 0;
// Number of failed tests.
int failed = 0;

// Test 1: do the default constructor and as_string work?
curr_test++;
bignum simple;
if (simple.as_string() != "0") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 2: does the integer constructor work?
curr_test++;
bignum nines(9);
if (nines.as_string() != "999999999") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 3: does the string constructor work (correct input)?
curr_test++;
bignum hundred("100");
if (hundred.as_string() != "100") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 4: does the string constructor work (bad input)?
curr_test++;
bignum sixtyfive("65abcd");
if (sixtyfive.as_string() != "65") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 5: does the string constructor work (all bad input)?
curr_test++;
bignum zero("not a number");
if (zero.as_string() != "0") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 6: does the string constructor work (long input)?
curr_test++;
bignum huge("123456789123456789");
if (huge.as_string() != "123456789123456789") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 7: does the copy constructor work?
curr_test++;
bignum copy(sixtyfive);
if (copy.as_string() != "65") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 8: does the assignment operator work?
curr_test++;
simple = hundred;
if (simple.as_string() != "100") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 9: does the destructor work, and do the copy constructor
// and assignment operator make deep copies?  A failure is likely
// to crash the program.
curr_test++;
{
    bignum secondcopy(copy);
    bignum thirdcopy(secondcopy);
    bignum newcopy("175");
    thirdcopy = hundred;
    copy = newcopy;
    newcopy = bignum("42");
}
if (copy.as_string() != "175" || hundred.as_string() != "100") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 10: does digits() work?
curr_test++;
if (hundred.digits() != 3) {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 11: does digits() work (zero)?
curr_test++;
if (zero.digits() != 1) {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 12: does multiply() work (no carry)?
curr_test++;
bignum multiplicand("123");
bignum multiplier("12");
bignum product = multiplicand.multiply(multiplier);

if (product.as_string() != "1476") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 13: does multiply() work (with carry)?
curr_test++;
bignum mc1("963");
bignum mc2("82");
bignum mcp = mc1.multiply(mc2);

if (mcp.as_string() != "78966") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// Test 14: does multiply() work (large numbers)?
curr_test++;
bignum mh1("12345678900");
bignum mh2("98765432100");
bignum mhp = mh1.multiply(mh2);

if (mhp.as_string() != "1219326311126352690000") {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

// TODO: add two more tests for multiply()
// TODO: add four tests each for add(), as_int(), and equals()

return (failed == 0);
}


{
if (have_newline) {
    // Ignore the newline after the user's previous input.
    cin.ignore(200, '\n');
}

// Prompt for the user to press ENTER, then wait for a newline.
cout << endl << "Press ENTER to continue." << endl;
cin.ignore(200, '\n');
}

当我尝试在 (!! [copy constructor (deep copy)]中使用 delete [] 时出现错误这是错误的 - 它在赋值运算符中,而不是复制constr。!!)我不确定这是否是由于泄漏(没有在我应该拥有的其他地方实现析构函数)或者它只是语法,或者什么,但这真的很困扰我。这真的是我首先想看的。但是,我知道这种方法可能不实用,因为最好一次过滤一个测试用例,以便将难题放在一起。这是我感兴趣的另一件事。当您遇到此类问题时,调试的最佳方法是什么?如果你提供修复,我真的更感兴趣的是你如何以及为什么做你所做的,而不是你所做的。如果你能找到时间,请提供做事的理由。

最后,我在这里和那里直接从这个论坛获得了一些帮助,但通过寻找语法之类的东西间接地获得了很多帮助。感谢大家投入时间和精力来帮助人们学习一门不一定是地球上对用户最友好的语言。似乎有很多关于 C++ 的知识只是为了让它首先运行,这很浪费时间,但是当你这样做时是值得的。再次感谢,一切。

布拉德

4

1 回答 1

0

代码很多,但默认构造函数不是问题吗?

bignum::bignum(){
digit[0];
}

您有可能会删除不是用 new 创建的东西。

另一个提示:

digit = new int[];

应该声明大小。

于 2013-10-19T21:19:55.880 回答