学习日记三:素因子分解,撸了一个上午

铁锈_ 2015-11-05 11:33:06

前天整数分解书上给了代码,自己分析一下代码感觉还是不行。
于是今天想自己撸一个素因子分解,结果快吃饭了还没好,下午继续。
写递归的太少了,只有汉诺塔自己写的,其他的都看书上的也就那么几个,看懂和自己会完全不一样啊

开始expon没弄成全局变量,在纸上写了调用过程发现错了,然后发现输入20没结果分析一下原来是当输入20运行到5时remainder/i为1无法输出,现在递归出口不知道往哪里放都是错的。

再弱弱的问句,无返回值的递归函数加了return语句是结束整个递归调用过程,还是返回上一层调用函数??


#include <stdio.h>
#include <math.h>
#define max 30

int a[max] ;
int b[max] ;
int expon ;

int IsPrimeNumber( int factor )
{
int k ;
int m;
(int)k=sqrt(factor); //判别i是否为素数,只需使2~根号i之间的每一个整数去除
for(m=2;m<=k;m++)
if(factor%m==0) break;
if(m>k)
return 1 ;
else return 0 ;
}



void search(int remainder , int factor ,int nTerm )//剩余值,起始因子
{

/*int expon;*/ //指数,第nTerm项
int i ;
int k ;


if(remainder==1||remainder==factor) //递归出口
{
a[nTerm] = factor ;
b[nTerm] = expon+1 ;


printf( "%d^%d" , a[0],b[0] ) ;
for( k=1 ; k<nTerm-1 ; k++ )
printf( "*%d^%d",a[k],b[k] ) ;
//如果指数为1不打印,太麻烦先这么用吧
printf( "*%d^%d\n",a[k],b[k] ) ;

return ;
}
else
{
for( i=factor ; i<=remainder ; i++,expon=0 )//递归出口可否放在循环内部
{
//如果已经是素数只能分解为自身时应该输出
if( IsPrimeNumber(i) && remainder%i==0 ) //如果i是因子且剩余值remainder能整除这个因子,保存数据
{
if(a[nTerm]!=i/*i!=factor*/) //如果因子发生变化则项数加1,没变化项数不变
nTerm++ ;

expon++ ;
a[nTerm] = factor ;
b[nTerm] = expon ;
//判断remainder/i是否为0即判断remainder是否等于i

search( remainder/i , i , nTerm) ;//remainder/i必须是整数,当输入20运行到5时remainder/i为1无法输出
}

else if( !IsPrimeNumber(i) ||remainder%i!=0/*&& remainder%i!=0*/ ) //如果不是素数或者无法整除,进入下一个因子的判断
{
continue ;
}
}
}



}


int main()
{
int N;
scanf( "%d" , &N ) ;

expon=0 ; //遗漏,并改为全局变量
printf("%d=",N);
search( N , 2 , 0) ;
//如果起始因子从1开始那么当整数是1时数据无法保存,故整数N=1单独考虑
}
...全文
354 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
没必要循环到n, sqrt(n)就够了,比sqrt(n)大的质数约数之多只有一个。
引用 3 楼 fefe82 的回复:
[quote=引用 2 楼 u010107248 的回复:] [quote=引用 1 楼 fefe82 的回复:] 随便写一下,仅供参考

void split(int n){
  if (n<=1) return;
  map<int, int> factors;
  for (int i = 2; i <= n; i++){
    while (n%i == 0) {
        n = n / i;
        factors[i] ++;
    }
  }
  printf ("1");
  for (auto &v: factors) {
    printf("*%d^%d", v.first, v.second);
  }
}
没学过C++。。。。[/quote]
void split(int n){
  if (n<=1) return;
  printf ("1");
  for (int i = 2; i <= n; i++){
    int k = 0;
    while (n%i == 0) {
        n = n / i;
        k++;
    }
    if ( k > 0) {
        printf("*%d^%d", i, k);
    }
  }
}
[/quote]
赵4老师 2015-11-06
  • 打赏
  • 举报
回复
仅供参考:
#include <iostream>
using namespace std;
struct MyStruct {
    int Nodedata;
    MyStruct *pLeft;
    MyStruct *pRight;
} s1,s2,s3,s4,s5,s6,s7,s8;
void ashow(MyStruct * p) {
    if (p != nullptr) {
        ashow(p->pLeft);
        ashow(p->pRight);
        cout << p->Nodedata << endl;
        if (p->Nodedata == 4) {
            throw 1;//退出递归.直接返回.
        }
    }
}
int main() {
    MyStruct *pRoot;//根

    pRoot = &s1;
    s1.Nodedata = 1;
    s2.Nodedata = 2;
    s3.Nodedata = 3;
    s4.Nodedata = 4;
    s5.Nodedata = 5;
    s6.Nodedata = 6;
    s7.Nodedata = 7;
    s8.Nodedata = 8;

    s1.pLeft = &s2;
    s1.pRight = &s3;

    s2.pLeft = &s4;
    s2.pRight = &s5;

    s3.pLeft = &s6;
    s3.pRight = &s7;
    try {
        ashow(pRoot);
    } catch (int err) {
        cout<<"catch err "<<err<<endl;
    }
    return 0;
}
//4
//catch err 1
//
赵4老师 2015-11-06
  • 打赏
  • 举报
回复
Finding prime numbers - Kenneth Haugland Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers
paschen 2015-11-05
  • 打赏
  • 举报
回复
只是返回该层,返回后会继续执行上一层
fefe82 2015-11-05
  • 打赏
  • 举报
回复
引用 2 楼 u010107248 的回复:
[quote=引用 1 楼 fefe82 的回复:] 随便写一下,仅供参考

void split(int n){
  if (n<=1) return;
  map<int, int> factors;
  for (int i = 2; i <= n; i++){
    while (n%i == 0) {
        n = n / i;
        factors[i] ++;
    }
  }
  printf ("1");
  for (auto &v: factors) {
    printf("*%d^%d", v.first, v.second);
  }
}
没学过C++。。。。[/quote]
void split(int n){
  if (n<=1) return;
  printf ("1");
  for (int i = 2; i <= n; i++){
    int k = 0;
    while (n%i == 0) {
        n = n / i;
        k++;
    }
    if ( k > 0) {
        printf("*%d^%d", i, k);
    }
  }
}
铁锈_ 2015-11-05
  • 打赏
  • 举报
回复
引用 1 楼 fefe82 的回复:
随便写一下,仅供参考

void split(int n){
  if (n<=1) return;
  map<int, int> factors;
  for (int i = 2; i <= n; i++){
    while (n%i == 0) {
        n = n / i;
        factors[i] ++;
    }
  }
  printf ("1");
  for (auto &v: factors) {
    printf("*%d^%d", v.first, v.second);
  }
}
没学过C++。。。。
fefe82 2015-11-05
  • 打赏
  • 举报
回复
随便写一下,仅供参考

void split(int n){
  if (n<=1) return;
  map<int, int> factors;
  for (int i = 2; i <= n; i++){
    while (n%i == 0) {
        n = n / i;
        factors[i] ++;
    }
  }
  printf ("1");
  for (auto &v: factors) {
    printf("*%d^%d", v.first, v.second);
  }
}
铁锈_ 2015-11-05
  • 打赏
  • 举报
回复
代码有了,不给
paschen 2015-11-05
  • 打赏
  • 举报
回复
引用 16 楼 u010107248 的回复:
[quote=引用 14 楼 adlay 的回复:] [quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote]
引用 14 楼 adlay 的回复:
[quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote] 我一直觉得用goto会使得代码写起来简单一些,可就是不让用[/quote]
引用 16 楼 u010107248 的回复:
[quote=引用 14 楼 adlay 的回复:] [quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote]
引用 14 楼 adlay 的回复:
[quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote] 我一直觉得用goto会使得代码写起来简单一些,可就是不让用[/quote] goto通常可以用于跳出比较深的循环,其他情况能不用还是不用
铁锈_ 2015-11-05
  • 打赏
  • 举报
回复
引用 14 楼 adlay 的回复:
[quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote]
引用 14 楼 adlay 的回复:
[quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote] 我一直觉得用goto会使得代码写起来简单一些,可就是不让用
paschen 2015-11-05
  • 打赏
  • 举报
回复
引用 14 楼 adlay 的回复:
[quote=引用 13 楼 paschen 的回复:] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍![/quote] 我没说他是一种好主意,另外他是跳出递归,用goto不行
www_adintr_com 2015-11-05
  • 打赏
  • 举报
回复
引用 13 楼 paschen 的回复:
通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
用异常来跳出循环比用 goto 语句还恶劣 100 倍!
paschen 2015-11-05
  • 打赏
  • 举报
回复
引用 12 楼 u010107248 的回复:
[quote=引用 11 楼 paschen 的回复:] void f() { if() //满足某条件 throw(xxx); f(); } main() { try { f(); } catch(xxx) { } //...............跳出之后的代码 }
不明白,能解释下么。。。[/quote] 通过异常处理,可以快速从递归跳出,当满足某种条件后就抛出异常,在外面捕捉这个异常,从而达到跳出
铁锈_ 2015-11-05
  • 打赏
  • 举报
回复
引用 11 楼 paschen 的回复:
void f() { if() //满足某条件 throw(xxx); f(); } main() { try { f(); } catch(xxx) { } //...............跳出之后的代码 }
不明白,能解释下么。。。
paschen 2015-11-05
  • 打赏
  • 举报
回复
void f() { if() //满足某条件 throw(xxx); f(); } main() { try { f(); } catch(xxx) { } //...............跳出之后的代码 }
paschen 2015-11-05
  • 打赏
  • 举报
回复
引用 5 楼 u010107248 的回复:
[quote=引用 4 楼 paschen 的回复:] 只是返回该层,返回后会继续执行上一层
这样的话我要怎么输出啊,我希望得到结果输出后立即停止函数运行[/quote] 这样呢 void f() { if() //满足某条件 throw(xxx); } main() { try { f(); } catch(xxx) { } }
赵4老师 2015-11-05
  • 打赏
  • 举报
回复
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出
铁锈_ 2015-11-05
  • 打赏
  • 举报
回复
引用 7 楼 jiht594 的回复:
[quote=引用 5 楼 u010107248 的回复:] [quote=引用 4 楼 paschen 的回复:] 只是返回该层,返回后会继续执行上一层
这样的话我要怎么输出啊,我希望得到结果输出后立即停止函数运行[/quote] 全局变量,flag, 遇见flag==true就继续返回上层[/quote] 像这样写个,举个例子吧 void f() { if() { } else { f() } } main() { f(); }
jiht594 2015-11-05
  • 打赏
  • 举报
回复
引用 5 楼 u010107248 的回复:
[quote=引用 4 楼 paschen 的回复:] 只是返回该层,返回后会继续执行上一层
这样的话我要怎么输出啊,我希望得到结果输出后立即停止函数运行[/quote] 全局变量,flag, 遇见flag==true就继续返回上层
铁锈_ 2015-11-05
  • 打赏
  • 举报
回复
加载更多回复(1)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧