代码块 10.05 和 12.11、13.12 使用相同的代码返回不同的结果

Code Blocks 10.05 and 12.11, 13.12 returns different results with same code

本文关键字:代码 结果 返回      更新时间:2023-10-16

我写了下面的代码来查找一个数字是否是回文。但是当我编译并运行代码时,它会在代码块 10.05 和 12.11、13.12 中返回不同的结果。

我尝试了数字为 12321 的代码。代码块 10.05 返回"数字 12321 有 5 位数字,是一个回文数字"。代码块 12.11 和 13.12 返回"数字 12321 有 5 位数字,不是回文数字"。

这是代码。

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int num, tmp, tmp2, i, k, last_num=0, check_num;
    cout<<"Enter a number : ";
    cin>>num;
    tmp=num;
    check_num=num;
    for(i=1; tmp>=10; ++i)
    {
        tmp=(tmp-(tmp%10))/10;
    }
    cout<<"The number "<<num<<" has "<<i<< " digits ";
    for(k=i-1; k>=0; k--)
    {
        tmp2 = num%10;
        last_num+=tmp2*pow(10,k);
        num=(num-(num%10))/10;
    }
    if(check_num == last_num)
    {
        cout<<"and is a palindrome number"<<endl<<endl;
    }
    else
    {
        cout<<"and is NOT a palindrome number"<<endl<<endl;
    }
    return 0;
}

你的代码过于复杂,不必要,而且不正确(因为我已经提到过浮点数的问题,即pow()返回的值可能不精确)。

你可以用一种更简单、更简洁的方式实现这一点:以相反的顺序从其数字开始构建数字,然后检查以这种方式获得的数字是否与原始数字匹配:

int ispal(unsigned long long n)
{
    unsigned long o = n;
    unsigned long long k = 0;
    while (n) {
        k *= 10;
        k += n % 10;
        n /= 10;
    }
    return o == k;
}

unsigned long long仅用于代替普通int,以使此函数适用于尽可能大的数字。

继我和 H2CO3 之间的评论线程之后,我在这里提供检查回文的字符串方法和数字方法之间的比较:

#include <iostream>
#include <string>
#include <ctime>
int ispal(unsigned long long n)
{
    unsigned long long o = n;
    unsigned long long k = 0;
    while (n) {
        k *= 10;
        k += n % 10;
        n /= 10;
    }
    return o == k;
}
int ispalc(char* s)
{
    char *e;
    e = s + strlen(s) - 1;
    while(s < e)
    {
      if( *s++ != *e-- ) return 0;
    }
    return 1;
}
int main(void) {
    unsigned long long num;
    int ii;
    time_t startT, endT, diff1, diff2;
    char nums[128];
    std::cout<<"Enter a number : ";
    std::cin>>num;
    if (ispal(num) != 0) std::cout << "It is a palindrome" << std::endl;
    else std::cout << "It is not a palindrome" << std::endl;
    sprintf(nums, "%lld", num);
    if (ispalc(nums) != 0) std::cout << "It is a palindrome" << std::endl;
    else std::cout << "It is not a palindrome" << std::endl;
    startT = clock();
    for(ii = 0; ii < 1000000; ii++) ispal(num);
    endT = clock();
    diff1 = (endT - startT);
    startT = clock();
    for(ii = 0; ii < 1000000; ii++) ispalc(num);
    endT = clock();
    diff2 = (endT - startT);
    printf("using numbers: %.2lf usn", diff1 * 1000.0 / CLOCKS_PER_SEC );
    printf("using strings: %.2lf usn", diff2 * 1000.0 / CLOCKS_PER_SEC );
    return 0;
}

需要注意的几点:

    我将字符串到数字
  1. 和数字到字符串的转换留在了计时循环之外。由于用户输入实际上是一个字符串(转换为数字),因此 number 方法具有优势。在"现实生活"中,将字符串转换为数字将是整个事情中较慢的操作之一。
  2. 我也在主级别上制作了数字unsigned long long的类型;以及函数内部的o类型(unsigned long)。这使得代码稍微快一点,因为它没有花时间进行转换。

鼓卷...在上述警告下,时序性能为:

Enter a number : 123454321
It is a palindrome
It is a palindrome
using numbers: 68.51 us
using strings: 26.27 us
Enter a number : 1234567
It is not a palindrome
It is not a palindrome
using numbers: 53.03 us
using strings: 11.78 us

获胜者对我来说似乎很清楚——"琴弦有它"。