C语言 如何解决程序长时间运行的问题

xytpbqjk  于 9个月前  发布在  其他
关注(0)|答案(4)|浏览(97)

我被要求写一个代码来找到N位数(3<=N<=7)的自恋数字,但我总是在输入7时遇到超时问题。我该怎么办?
下面是我的代码:

#include<stdio.h>
#include<math.h>
int narcissistic(int num,int n);
int main(){
    int n;
    int i,min,max;
    scanf("%d",&n);
    max=pow(10,n)-1;
    min=pow(10,n-1);
    for(i=min;i<=max;i++){
        if(nacissistic(i,n)){
            printf("%d\n",i);
        }
    }
    return 0;
}
int narcissistic(int num,int n){
    int renum=num,sum=0;
    int digit;
    while(renum!=0){
        digit=renum%10;
        renum=renum/10;
        sum+=pow(digit,n);
        if(sum>num){
            break;
        }
    }
    return(sum==num);
}

字符串
我尝试将数据类型从int转换为double,但没有成功。

nuypyhwy

nuypyhwy1#

自恋数字

如果我们谈论n位数,那么k是一个自恋数,如果:

  • 它有n个数字
  • k = sum(digit^n)

最重要的是,让我们使用一个查找表,这样你就可以精确地计算数字的9次幂,而不是n *(10^(n+1)- 10^n)次。当然,我也修复了错别字:

#include<stdio.h>
#include<math.h>
int narcissistic(int num,int n, int *lookup);
int main(){
    int n;
    scanf("%d",&n);
    int lookup[10] = {
        0,
        (int)round(pow(1,n)),
        (int)round(pow(2,n)),
        (int)round(pow(3,n)),
        (int)round(pow(4,n)),
        (int)round(pow(5,n)),
        (int)round(pow(6,n)),
        (int)round(pow(7,n)),
        (int)round(pow(8,n)),
        (int)round(pow(9,n))
    };
    int i,min,max;
    max=pow(10,n)-1;
    min=pow(10,n-1);
    for(i=min;i<=max;i++){
        if(narcissistic(i,n, lookup)){
            printf("%d\n",i);
        }
    }
    return 0;
}
int narcissistic(int num,int n, int *lookup){
    int renum=num,sum=0;
    int digit;
    while(renum!=0){
        digit=renum%10;
        renum=renum/10;
        sum+=lookup[digit];
        //sum+=pow(digit,n);
        if(sum>num){
            break;
        }
    }
    return(sum==num);
}

字符串
我在初始实现和查找表改进之间做了一些基准测试,通过:

#include<stdio.h>
#include<math.h>
#include<time.h>
int narcissistic(int num,int n, int *lookup, int mode);
int main(){
    int n;
    scanf("%d",&n);
    clock_t powerTic = clock();
    int lookup[10] = {
        0,
        (int)round(pow(1,n)),
        (int)round(pow(2,n)),
        (int)round(pow(3,n)),
        (int)round(pow(4,n)),
        (int)round(pow(5,n)),
        (int)round(pow(6,n)),
        (int)round(pow(7,n)),
        (int)round(pow(8,n)),
        (int)round(pow(9,n))
    };
    clock_t powerToc = clock();
    int i,min,max;
    max=pow(10,n)-1;
    min=pow(10,n-1);
    printf("Without lookup:\n");
    clock_t tic = clock();
    for(i=min;i<=max;i++){
        if(narcissistic(i,n, lookup, 0)){
            printf("%d\n",i);
        }
    }
    clock_t toc = clock();
    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
    printf("With lookup:\n");
    tic = clock();
    for(i=min;i<=max;i++){
        if(narcissistic(i,n, lookup, 1)){
            printf("%d\n",i);
        }
    }
    toc = clock();
    printf("Elapsed: %f seconds\n", (double)((toc - tic) + (powerToc - powerTic)) / CLOCKS_PER_SEC);
    return 0;
}
int narcissistic(int num,int n, int *lookup, int mode){
    int renum=num,sum=0;
    int digit;
    while(renum!=0){
        digit=renum%10;
        renum=renum/10;
        if (mode) sum+=lookup[digit];
        else sum+=pow(digit,n);
        if(sum>num){
            break;
        }
    }
    return(sum==num);
}


差别很大。这是输出:

Without lookup:
1741725
4210818
9800817
9926315
Elapsed: 1.346095 seconds
With lookup:
1741725
4210818
9800817
9926315
Elapsed: 0.291491 seconds


注意,如果n = 1,那么0会丢失。你可能想科普这种情况,比如如果n为1,则将min设置为0。

erhoui1w

erhoui1w2#

这可能是更简单的代码,我试过了。

#include <iostream>
#include <cmath>

bool isNarcissistrc(int num) {
  int originalNum = num;
  int n = static_cast<int>(log10(num)) + 1;
  int sum = 0;

  while (num > 0) {
    int digit = num % 10;
    sum += pow(digit, n);
    num /= 10;
  }

  return sum == originalNum;
}

void findNarcissisticNumbers(int digits) {
  for (int i = pow(10, digits-1); i < pow(10, digits); ++i) {
    if (isNarcissistic(i)) {
      std::cout << i << " is a narcissistic number.\n";
    }
  }
}

int main() {
  int digits;
  std::cout << "Enter the digits: ";
  std::cin >> digits;

  findNarcissisticNumbers(digits);

  return 0;
}

字符串
如果您有任何问题,请随时添加评论。

fae0ux8s

fae0ux8s3#

好吧,尽管你没有说什么是自恋的数字(我不得不调试你的代码来猜测),但你的代码在我的系统中运行良好,产生正确的答案(尽管使用了数学pow()函数,它应该给出给予正确的结果-除非你超过了2^53的精度限制,这不是事实-)
我已经减少了你的代码,使它更容易阅读(编译器不会为你使用的空格数向你收费)我已经添加了一个快速的幂计算函数,使用long unsigned数字,以允许完全64位精度。结果是这样的(它产生的结果与其他答案中给出的结果相同):

#include<stdio.h>

unsigned long fast_pow(unsigned long num, unsigned n)
{
    unsigned long result = 1UL;
    unsigned mask = ~(~0U >> 1);  /* 0b100000...00000 */

    while (mask) {
        result *= result;
        if (n & mask) {
            result *= num;
        }
        mask >>= 1;
    }

    return result;
} /* fast_pow */

int narcissistic(int num, int n)
{
    int renum = num, sum = 0;
    int digit;

    while(renum != 0 && sum <= num){
        digit = renum % 10;
        renum = renum / 10;
        sum  += fast_pow(digit, n);
    }
    return sum == num;
} /* narcissistic */

int main()
{
    unsigned n;
    unsigned long i, min, max;

    scanf("%ld",&n);
    min = fast_pow(10UL, n - 1UL);
    max = fast_pow(10UL, n) - 1UL;
 
    for(i = min; i <= max; i++) {
        if(narcissistic(i, n)) {
            printf("%lu\n", i);
        }
    }
    return 0;
} /* main */

字符串

lyfkaqu1

lyfkaqu14#

这个答案很容易理解。

#include <stdio.h>
#include <math.h>

// Function to count the number of digits in a given number
int countDigits(int number) {
  int count = 0;
  while (number != 0) {
    number /= 10;
    count++;
  }
  return count;
}

// Function to check if a number is a narcissistic number
int isNarcissistic(int number) {
  int originalNumber = number;
  int numDigits = countDigits(number);
  int sum = 0;

  while (number > 0) {
    int digit = number % 10;
    sum += pow(digit, numDigits);
    number /= 10;
  }

  return (sum == originalNumber);
}

// Function to find narcissistic numbers of given digits
void findNarcissisticNumbers(int digits) {
  printf("Narcissistic numbers %d digits:\n", digits);
  for (int i = pow(10, digits-1); i <= pow(10, digits); ++i) {
    if (isNarcissistic(i)) {
      printf("%d\n", i);
    }
  }
}

int main() {
  int digits;

  printf("Enter the digits: ");
  scanf("%d", &digits);

  findNarcissisticNumbers(digits);

  return 0;
}

字符串

相关问题