用栈来实现回文数的时候测试数字13时出现异常(其余好像没问题)

**感谢您来帮忙。。。
**


题目描述

我们把从左往右和从右往左念起来相同的数字叫做回文数。
某个数用某个进制表示不是回文数,但是用别的进制表示可能就是回文数。
例如,17是用十进制表示的数,显然它不是一个回文数,但是将17用二进制表示出来是10001。
现在给一个用十进制表示的数,请判断它在2~16进制下是否是回文数。

输入

输入包含多组测试数据。每组输入一个用十进制表示的正整数n(0 < n< 50000),当n=0时结束。

输出

对于每组输入,如果n在2~16进制中的某些进制表示下是回文数,则输出“Number i is palindrom in basis ”,在后面接着输出那些进制。其中i用n的值代替,后面输出的进制中,每两个数字之间空一个。
如果n在2~16进制的表示下都不为回文数,则输出“Number i is not a palindrom”,其中i用n的值代替。


想法是:

在转换进制的时候由于要反序,所以用栈来实现,在判断回文数的时候也是用栈来实现。

状况

在测试大的数的时候都没有问题,但是当数(num)改为13,14一类的时候,输出出现问题。然后检查,测试,也没发现问题。。。就很有问题。。

代码如下:

#include<iostream>
using namespace std;
struct Node
{
    int data;
    Node* link;
    Node()
    {
        data = 0;
        link = NULL;
    }
    Node(int d)
    {
        data = d;
        link = NULL;
    }
};
class LinkStack
{
private:
    Node* first;  //头结点存储输入判断的数据,其余结点存储权位的值
    Node* Locate(int i);  //定位,返回地址,仅仅是给公有成员用
public:
    LinkStack();  //构造函数
    LinkStack(int num);  //构造函数
    int Lenth();  //计算长度
    int GetNum() { return first->data; }
    void Push(int num);  //压栈
    void Clear();  //清空栈
    int Pop();  //弹出
};

LinkStack::LinkStack()
{
    first = new Node;
}
LinkStack::LinkStack(int num)
{
    first = new Node(num);
}

int LinkStack::Lenth()
{
    Node* current = first;
    int count = 0;
    while (current->link != NULL)
    {
        current = current->link;
        count++;
    }
    return count;
}

Node* LinkStack::Locate(int i)
{
    int count = 0;
    Node* current = first;
    for (count; count < i; count++)
    {
        current = current->link;
    }
    return current;
}

void LinkStack::Push(int num)
{
    int x = this->Lenth();
    Node* current = this->Locate(x);
    Node* newnode = new Node(num);
    if (newnode == NULL)
    {
        cerr << "error !" << endl;
        exit(1);
    }
    current->link = newnode;
}

void LinkStack::Clear()
{
    int len = this->Lenth();
    for (int i = 0; i < len; i++)
    {
        this->Pop();
    }
    first->link = NULL;
}
int LinkStack::Pop()
{
    int x = this->Lenth() - 1;  //定位到栈顶前一个
    Node* current = this->Locate(x);
    int value = current->link->data;
    delete current->link;
    current->link = NULL;
    return value;
}
void radix(LinkStack& a, int m)  //转换进制
{
    int num = a.GetNum();  
    int x;  //记录余数
    do   //由于进制转换的时候要反序,所以考虑压栈
    {
        x = num % m;
        num = num / m;
        a.Push(x);  //进制压栈
    } while (num / m);
    a.Push(num);
}

bool judge(LinkStack& a)  //判断是否为回文数
{
    LinkStack b;  //回文数判断时需要压栈,所以新建一个栈
    int x = a.Lenth() % 2;  //需要判断长度的奇偶
    for (int i = 0; i < a.Lenth()/2; i++)
    {
        b.Push(a.Pop());  //将转换为进制的一半压到b栈,并且弹出a栈的一半
    }
    if (x==1)  //为奇数
    {
        int y = a.Pop();  //去掉a栈里面原来中间的元素(现在栈顶的元素)
    }
    for (int i = 0; i <= a.Lenth(); i++)
    {
        int x = a.Pop(); 
        int y = b.Pop();
        if (x!=y) return false;  //判断回文
    }
    return true;
}

int main()
{
    while (1)
    {
        int num;  //判断的数据
        int count = 0;  //用于计数
        int x[50];  //用于记录是回文数的进制
        cin >> num;
        if (num == 0) break;
        LinkStack a(num);
        for (int i = 2; i < 17; i++)  //判断各种进制的可能,并将是回文数的进制记入数组
        {
            radix(a, i);
            if (judge(a))
            {
                x[count] = i;
                count++;
            }
            a.Clear();
        }
        if (count == 0)
        {
            cout << "Number " << a.GetNum() << " is not a palindrom" << endl;
        }
        else
        {
            cout << "Number " << a.GetNum() << " is palindrom in basis ";
            for (int i = 0; i < count; i++)
            {
                cout << x[i] << ' ';
            }
            cout << endl;
        }
    }
    return 0;
}
c++

1个回答

在你的judge函数里面,有两个循环体。

for (int i = 0; i < a.Lenth()/2; i++)
    {
        b.Push(a.Pop());  //将转换为进制的一半压到b栈,并且弹出a栈的一半
    }
for (int i = 0; i <= a.Lenth(); i++)
    {
        int x = a.Pop(); 
        int y = b.Pop();
        if (x!=y) return false;  //判断回文
    }

每个循环体内都在从a里面往外pop元素,导致a的长度一直在变,而你循环体的判断条件内a.length()又每次都在重新计算length,导致异常。

解决方法,把a.length()存到一个变量里面。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问