求第100,000个质数的C++算法

janchin 2009-10-15 10:50:03
Attention:是第第第100,000个,不是100,000以内!!!!
貌似这个数很大啊~这是金山的笔试题目,怎么算?说出大致思想也成,拜谢了!遍历肯定是不行的吧?虽然我答案就是用写的遍历-_-""!
...全文
1568 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
leesaiya 2011-06-30
  • 打赏
  • 举报
回复
变量n是用来保存个数的,稍微改一下就能回答你的问题了!
这个对于大数,算起来很慢,需用别的算法!
leesaiya 2011-06-30
  • 打赏
  • 举报
回复
我的网站http://www.evecalm.com
	#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

int main()
{
int m;
int n=0;
//vector<int> prime;
char ch;
fstream fp;
cout<<"What prime numbers do you want get within? ";
if((cin>>m)==0)
{
cout<<"Bad input! Please try agin!\n";
return 1;
}
if(m<2)
{
cout<<"There are no prime numbers within "<<m<<endl;
return 0;
}
else if(m==2)
{
fp.open("prime.txt",ios::in|ios::out|ios::trunc);
fp<<"There are only 1 prime number within 2.\n";
fp<<"2\n";
fp.close();
cout<<"Congratulations! It has worked out!\n";
return 0;
}
else
{
int j;
int sq;
fp.open("prime.txt",ios::in|ios::out|ios::trunc);
fp<<"2\t\t";
n++;
for(int i=3;i<=m;i+=2)
{
sq=static_cast<int>(sqrt(i))+1;
fp.seekg(0,ios::beg);
fp>>j;
for(;j<sq;)
{
if(i%j==0)
{
break;
}

else
{
if((fp>>j)==NULL)
{
j=3;
}
}
}
if(j>=sq)
{
fp.seekg(0,ios::end);
fp<<i<<"\t\t";
n++;
if(n%4==0)
fp<<'\n';
}
}
fp.seekg(0,ios::end);
fp<<"\nThere are only "<<n<<" prime number within "<<m<<".\n";
fp.close();
cout<<"Congratulations! It has worked out!\n";
return 0;
}
}
mgw2314 2010-10-19
  • 打赏
  • 举报
回复

#include <iostream>
#include <iomanip>
using namespace std;
int main(){
int max;
cout<<"请输入要显示的个数:";
cin>>max;
long* prime=new long[max];
int count=1;
*prime=2;
int trial=3;
while(count<max){
for(int i=0;i<count;i++)
if(trial%*(prime+i)==0){
trial+=2;
i=0;
}
*(prime+count++)=trial;
trial+=2;
}
for(int i=0;i<max;i++){
if(i%5==0)
cout<<endl;
cout<<setw(5)<<*(prime+i);
}
cout<<endl;
}
mLee79 2009-10-17
  • 打赏
  • 举报
回复
10W很小,啥办法都可以,10G就小有挑战了。。。

zhengjiankang 2009-10-17
  • 打赏
  • 举报
回复
之前找出来的素数可以用数组存起来,在判断后1个数是否为素数的时候可以从两个方面去约束,用来检验n是否为素数的数:1:不大于n^0.5的数,2:之前已经找出来储存起来的数,,所以感觉找起来也不是特别复杂的哈。
baihacker 2009-10-16
  • 打赏
  • 举报
回复

//暂时只给第一种的实现,大家可以测试一下在自己电脑上跑多少时间.
#include <cstdio>
#include <cstring>
using namespace std;

const int MAX_PRIME = 2000000;

int PrimeTable[6000000];
int IsPrime[MAX_PRIME+1];
int PrimeCnt = 0;

void get_prime()
{
memset(IsPrime, 1, sizeof(IsPrime));
IsPrime[0] = IsPrime[1] = 0;
for (int i = 2 ; i < MAX_PRIME; i++)
if (IsPrime[i])
{
for (long long j = (PrimeTable[PrimeCnt++] = i) * (long long)i; j < MAX_PRIME; j += i)
IsPrime[j] = 0;
}
}

int main()
{
get_prime();
printf("%d\n", PrimeTable[99999]);
return 0;
}
baihacker 2009-10-16
  • 打赏
  • 举报
回复
两种方法:
1.就是暴力,筛选出第十万个
已经知道:
1百以内:25 97
1千以内:168 997
1万以内:1229 9973
10万以内:9592 99991
100万以内:78498 999983
1000万以内:664579 9999991
所以,大概在200万以内筛选就OK了.
(筛选1亿以内的素数大概是不超过10秒(我的计算机), 100万差不多是瞬间)

2.二分枚举

记函数search(n)的功能为计算n以内的素数的个数
那么
int l = 1, r = max;
while (l <= r)
{
int mid = (l + r) >> 1;
if (search(mid) >= 100000) r = mid - 1;
else l = mid + 1;
}
l为所求.

现在问题的关键在于高效计算search(n),可以用容斥原理...
pcboyxhy 2009-10-16
  • 打赏
  • 举报
回复
目前性能比较好的生成素数表的方法是筛数法
测试单个素数性能比较好的方法是mr伪素数测试
James__Zhan 2009-10-15
  • 打赏
  • 举报
回复
答案:1299709.
一个素数为素数的条件是不能被它之前的任何素数给整除,事实上,还有一个条件,假设n为合数,则存在除一和它自身的两个数a,b,使得a×b=n,两个数之中必定有一个小于根号n,一个大于根号n,故此,可以得出结论,如果一个数n不能被小于根号n的所有输整除,则此数是素数。算法如下,不过是Java的。希望能满足你的要求。

public static void main(String[] args)
{
int len = 100000;
int[] arr = new int[len];
arr[0] = 2;
int m = 3;
int i = 1;
while(i < len){

boolean isLeap = true;
for(int j = 0; j < i && arr[j] < Math.sqrt(m) + 1; j++){
if(m % arr[j] == 0){
isLeap = false;
break;
}
}
if(isLeap){
arr[i++] = m;
}
m += 2;
}

System.out.println(arr[len - 1]);

}
pcboyxhy 2009-10-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 la_feng 的回复:]
ls的算过那个数是否是unsigned int能表示的没有,我想估计表示不了吧,随着数的增大,素数越来越少的
[/Quote]

一个复数域上的函数 - Riemann ζ 函数 - 的非平凡零点 (在无歧义的情况下我们有时将简称其为零点) 的分布怎么会与风马牛不相及的自然数域中的素数分布产生关联呢?这还得从 Euler 乘积公式 谈起。

我们知道, 早在古希腊时期, Euclid 就用精彩的反证法证明了素数有无穷多个。 随着数论研究的深入,人们很自然地对这些素数在自然数域上的分布产生了越来越浓厚的兴趣。 1737 年, 著名数学家 Leonhard Euler (1707-1783) 在圣彼得堡科学院 (St. Petersburg Academy) 发表了一个极为重要的公式,为数学家们研究素数分布的规律奠定了基础。 这个公式就是 Euler 乘积公式:

∑n n-s = ∏p(1-p-s)-1

公式中左边的求和对所有的自然数进行,右边的连乘积则对所有的素数进行。 可以 证明, 这个公式对所有 Re(s)>1 的复数 s 都成立。这个公式的左边正是我们在 上文 中介绍过的 Riemann ζ 函数, 而右边则是一个纯粹有关素数 (且包含所有素数) 的表达式, 这样的形式正是 Riemann ζ 函数与素数分布之间存在关联的征兆。那么这个公式究竟蕴涵着有关素数分布的什么样的信息呢? Riemann ζ 函数的零点又是如何出现在这种关联之中的呢?这就是本节及未来几节所要介绍的内容。

Euler 本人率先对这个公式所蕴涵的信息进行了研究。 他注意到在 s=1 的时候, 公式的左边 ∑n n-1 是一个发散级数 (这是一个著名的发散级数, 称为调和级数), 这个级数以对数方式发散。这些对于 Euler 来说都是不陌生的。 为了处理公式右边的连乘积,他对公式两边同时取了对数, 于是连乘积变成了求和, 由此他得到:

ln (∑n n-1) = -∑p ln(1 - p-1) = ∑p (p-1 + p-2/2 + p-3/3 + ... ...)

由于上式右端括号中除第一项外所有其它各项的求和都收敛,而且这些求和的结果累加在一起仍然收敛 (有兴趣的读者不妨自己证明一下)。 因此右边只有第一项的求和是发散的。由此 Euler 得到了这样一个有趣的渐近表达式:

∑p p-1 ~ lnln(∞)

或者, 更确切地说:

∑p<N p-1 ~ lnln(N)

这个结果 - 即 ∑p p-1 以 lnln(N) 的方式发散 - 是继 Euclid 证明素数有无穷多个以来有关素数的又一个重要的研究结果。它同时也是对素数有无穷多个这一命题的一种崭新的证明 (因为假如素数只有有限多个, 则求和就只有有限多项, 不可能发散)。 但 Euler 的这一新证明所包含的内容要远远多于 Euclid 的证明,因为它表明素数不仅有无穷多个,而且其分布要比许多同样也包含无穷多个元素的序列 - 比如 n2 序列 - 密集得多 (因为后者的倒数之和收敛)。 不仅如此,如果我们进一步注意到上式的右端可以改写为一个积分表达式:

lnln(N) ~ ∫ x-1ln-1(x) dx

而左端通过引进一个素数分布的密度函数 ρ(x) - 它给出在 x 附近单位区间内发现素数的几率 - 也可以改写为一个积分表达式:

∑p<N p-1 ~ ∫ x-1ρ(x) dx

将这两个积分表达式进行比较, 不难猜测到素数的分布密度为 ρ(x)~1/ln(x), 从而在 x 以内的素数个数 - 通常用 π(x) 表示 - 为:

π(x) ~ Li(x)

其中 Li(x) ≡ ∫ ln-1(x) dx 是对数积分函数[注一]。这正是著名的素数定理 (当然这种粗略的推理并不构成对素数定理的证明)。因此 Euler 发现的这个结果可以说是一扇通向素数定理的暗门。 可惜 Euler 本人并没有沿着这样的思路走, 从而错过了这扇暗门,数学家们提出素数定理的时间也因此而延后了几十年。



素数分布与素数定理


提出素数定理的荣誉最终落到了另外两位数学家的肩上:他们是德国数学家 Friedrich Gauss (1777-1855) 和法国数学家 Adrien-Marie Legendre (1752-1833)。

Gauss 对素数分布的研究始于 1792 到 1793 年间, 那时他才 15 岁。在那期间, 每当“无所事事” 的时候 Gauss 就会挑上几个长度为一千的自然数区间, 计算这些区间中的素数个数,并进行比较。 在做过了大量的计算和比较后, Gauss 发现素数分布的密度可以近似地用对数函数的倒数来描述, 即 ρ(x)~1/ln(x), 这正是上面提到的素数定理的主要内容。 但是 Gauss 并没有发表这一结果。 Gauss 是一位追求完美的数学家,他很少发表自己认为还不够完美的结果,而他的数学思想与灵感犹如浩瀚奔腾的江水, 汹涌激荡,常常让他还没来得及将一个研究结果完美化就又展开了新课题的研究。 因此 Gauss 一生所做的数学研究远远多过他正式发表的。 但另一方面, Gauss 常常会通过其它的方式 - 比如书信 - 透露自己的某些未发表的研究成果,他的这一做法给一些与他同时代的数学家带来了不小的尴尬。 其中 “受灾” 较重的一位便是 Legendre。 这位法国数学家在 1806 年率先发表了线性拟合中的最小平方法, 不料 Gauss 在 1809 出版的一部著作中提到自己曾在 1794 年 (即比 Legendre 早了 12 年) 就发现了同样的方法, 使 Legendre 极为不快。

有道是: 不是冤家不聚首。 在素数定理的提出上, 可怜的 Legendre 又一次不幸地与数学巨匠 Gauss 撞到了一起。 Legendre 在 1798 年发表了自己关于素数分布的研究,这是数学史上有关素数定理最早的文献[注二]。由于 Gauss 没有发表自己的研究结果, Legendre 便理所当然地成为了素数定理的提出者。 Legendre 的这个优先权一共维持了 51 年。 但是到了 1849 年, Gauss 在给德国天文学家 Johann Encke (1791-1865) 的一封信中提到了自己在 1792 至 1793 年间对素数分布的研究, 从而把尘封了半个世纪的优先权从 Legendre 的口袋中勾了出来, 挂到了自己已经鼓鼓囊囊的腰包上。

幸运的是, Gauss 给 Encke 写信的时候 Legendre 已经去世十六年了,他用最无奈的方式避免了再次遭受残酷打击。

无论 Gauss 还是 Legendre,他们对于素数分布规律的研究都是以猜测的形式提出的 (Legendre 的研究带有一定的推理成份, 但离证明仍然相距甚远)。 因此确切地说,素数定理在那时只是一个猜想 - 素数猜想,我们所说的提出素数定理指的也只是提出素数猜想。素数定理的数学证明直到一个世纪之后的 1896 年, 才由法国数学家 Jacques Hadamard (1865-1963) 与比利时数学家 Charles de la Vallée-Poussin (1866-1962) 彼此独立地给出。 他们的证明与 Riemann 猜想有着很深的渊源, 其中 Hadamard 的证明出现的时机和场合还有着很大的戏剧性, 这些我们将在 后文 中加以叙述。

素数定理是简洁而优美的,但它对于素数分布的描述仍然是比较粗略的,它给出的只是素数分布的一个渐近形式 - 也就是当 N 趋于无穷时的分布形式。从前面有关素数分布与素数定理的图示中我们也可以看到, π(x) 与 Li(x) 之间是有偏差的, 而且这种偏差的绝对值随着 x 的增加似有持续增加的趋势 (所幸的是, 这种偏差的增加与 π(x) 及 Li(x) 本身的增加相比仍是微不足道的 - 否则素数定理也就不成立了)[注三]。

那么有没有一个公式可以比素数定理更精确地描述素数的分布呢?这便是 Riemann 在 1859 年想要回答的问题。 那一年是 Gauss 去世后的第五年, 32 岁的 Riemann 继 Johann Dirichlet (1805-1859) 之后成为了 Gauss 在 Göttingen 大学的继任者。同年八月十一日, 他被选为柏林科学院 (Berlin Academy) 的通信院士 (Corresponding Member)。 作为对这一崇高荣誉的回报, Riemann 向柏林科学院提交了一篇论文。 这是一篇只有短短八页的论文, 标题是:论小于给定数值的素数个数。 正是这篇论文将 Euler 乘积公式 蕴涵的信息破译得淋漓尽致, 也正是这篇论文将 Riemann ζ 函数的零点分布与素数的分布联系在了一起。
liushuiyou_sheng 2009-10-15
  • 打赏
  • 举报
回复

楼上还是老算法啊。
la_feng 2009-10-15
  • 打赏
  • 举报
回复
ls的算过那个数是否是unsigned int能表示的没有,我想估计表示不了吧,随着数的增大,素数越来越少的
pcboyxhy 2009-10-15
  • 打赏
  • 举报
回复
稍作修改,更快一些

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

unsigned int s[100000] = {2};
unsigned int s_i = 1;

inline int is_sushu(unsigned int n)
{
int m = sqrt(n)+1;
for (int i=0; s[i]<=m; i++) {
if (i==s_i)
return 1;
if (n%s[i]==0)
return 0;
}
return 1;
}

int main()
{
for (int i=3; s_i!=100000; i+=2)
if (is_sushu(i))
s[s_i++] = i;
printf("%d\n", s[99999]);
}
pcboyxhy 2009-10-15
  • 打赏
  • 举报
回复
这个数据量很小啊,最朴素的穷举法就行了
代码正确性不保证,自己验证

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

unsigned int s[100000] = {2};
unsigned int s_i = 1;

int is_sushu(unsigned int n)
{
int i = 0;
int m = sqrt(n)+1;
for (i=0; i<=m; i++) {
if (i==s_i)
return 1;
if (n%s[i]==0)
return 0;
}
return 1;
}

int main()
{
int i;
for (i=3; ; i++) {
if (is_sushu(i))
s[s_i++] = i;
if (s_i>=100000)
break;
}
printf("%d\n", s[99999]);
}
wensheng_zh2007 2009-10-15
  • 打赏
  • 举报
回复
期待高手出现,出从头遍历之外还有什么办法?
但是增加的步长可以是2,从3开始起。
2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。2积分福利。 涵盖广泛 精炼的理论讲述搭配大量经典算法示例,学习查询兼而有之。 阐述到位 算法思想、算法实现和完整示例合理搭配,相辅相成。 示例完善 示例分析精准,代码注释精确,每段代码皆可通过编译执行。 计算机技术的发展和普及不仅改变了人们的生活和娱乐方式,也改变了人们的工作方式,这其中最为重要的便是计算机编程技术。现代的设计任务大多通过代码编程交给计算机来完成,其中算法起到了至关重要的作用。可以毫不夸张地说,算法是一切程序设计的灵魂和基础。 《C/C++常用算法手册》分3篇,共13章,“第1篇算法基础篇”介绍了算法概述,重点分析了数据结构和基本算法思想;“第2篇算法基本应用篇”详细讲解了算法在排序、查找、数值计算、数论、经典趣题和游戏中的应用;“第3篇算法高级应用篇”讲解了算法的一些高级应用技术,包括在密码学和数据压缩/解压缩中的应用。 《C/C++常用算法手册》知识点覆盖全面、结构安排紧凑、讲解详细、示例丰富。《C/C++常用算法手册》对每一个知识点都给出了相应的算法及应用示例。虽然这些例子都是以C语言来编写的,但是算法并不局限于C语言。如果读者采用其他编程语言,例如C++、C#、VB、Java等,根据其语法格式进行适当的修改即可。 《C/C++常用算法手册 》主要定位于有一定C/C++语言编程基础、想通过学习算法与数据结构提升编程水平的读者,也可作为具有一定编程经验的程序员以及大中专院校学生学习数据结构和算法的参考书。 第1篇 算法基础篇 1 第1章 算法概述 2 1.1 什么是算法 2 1.2 算法的发展历史 3 1.3 算法的分类 4 1.4 算法相关概念的区别 4 1.5 算法的表示 5 1.5.1 自然语言表示 5 1.5.2 流程图表示 6 1.5.3 N-S图表示 7 1.5.4 伪代码表示 7 1.6 算法的性能评价 8 1.7 算法实例 9 1.7.1 查找数字 9 1.7.2 创建项目 11 1.7.3 编译执行 12 1.8 算法的新进展 13 1.9 小结 14 第2章 数据结构 15 2.1 数据结构概述 15 2.1.1 什么是数据结构 15 2.1.2 数据结构中的基本概念 16 2.1.3 数据结构的内容 16 2.1.4 数据结构的分类 18 2.1.5 数据结构的几种存储方式 18 2.1.6 数据类型 19 2.1.7 常用的数据结构 20 2.1.8 选择合适的数据结构解决实际问题 21 2.2 线性表 21 2.2.1 什么是线性表 21 2.2.2 线性表的基本运算 22 2.3 顺序表结构 23 2.3.1 准备数据 23 2.3.2 初始化顺序表 24 2.3.3 计算顺序表长度 24 2.3.4 插入结点 24 2.3.5 追加结点 25 2.3.6 删除结点 25 2.3.7 查找结点 25 2.3.8 显示所有结点 26 2.3.9 顺序表操作示例 26 2.4 链表结构 30 2.4.1 什么是链表结构 30 2.4.2 准备数据 31 2.4.3 追加结点 31 2.4.4 插入头结点 33 2.4.5 查找结点 33 2.4.6 插入结点 34 2.4.7 删除结点 35 2.4.8 计算链表长度 36 2.4.9 显示所有结点 36 2.4.10 链表操作示例 37 2.5 栈结构 41 2.5.1 什么是栈结构 41 2.5.2 准备数据 42 2.5.3 初始化栈结构 42 2.5.4 判断空栈 43 2.5.5 判断满栈 43 2.5.6 清空栈 43 2.5.7 释放空间 44 2.5.8 入栈 44 2.5.9 出栈 44 2.5.10 读结点数据 45 2.5.11 栈结构操作示例 45 2.6 队列结构 48 2.6.1 什么是队列结构 48 2.6.2 准备数据 49 2.6.3 初始化队列结构 49 2.6.4 判断空队列 50 2.6.5 判断满队列 50 2.6.6 清空队列 50 2.6.7 释放空间 51 2.6.8 入队列 51 2.6.9 出队列 51 2.6.10 读结点数据 52 2.6.11 计算队列长度 52 2.6.12 队列结构操作示例 53 2.7 树结构 56 2.7.1 什么是树结构 56 2.7.2 树的基本概念 56 2.7.3 二叉树 57 2.7.4 准备数据 61 2.7.5 初始化二叉树 61 2.7.6 添加结点 62 2.7.7 查找结点 63 2.7.8 获取左子树 64 2.7.9 获取右子树 64 2.7.10 判断空树 65 2.7.11 计算二叉树深度 65 2.7.12 清空二叉树 65 2.7.13 显示结点数据 66 2.7.14 遍历二叉树 66 2.7.15 树结构操作示例 68 2.8 图结构 71 2.8.1 什么是图结构 71 2.8.2 图的基本概念 72 2.8.3 准备数据 76 2.8.4 创建图 78 2.8.5 清空图 79 2.8.6 显示图 79 2.8.7 遍历图 80 2.8.8 图结构操作示例 81 2.9 小结 84 第3章 基本算法思想 85 3.1 常用算法思想概述 85 3.2 穷举算法思想 85 3.2.1 穷举算法基本思想 86 3.2.2 穷举算法示例 86 3.3 递推算法思想 88 3.3.1 递推算法基本思想 88 3.3.2 递推算法示例 88 3.4 递归算法思想 90 3.4.1 递归算法基本思想 90 3.4.2 递归算法示例 90 3.5 分治算法思想 92 3.5.1 分治算法基本思想 92 3.5.2 分治算法示例 92 3.6 概率算法思想 96 3.6.1 概率算法基本思想 96 3.6.2 概率算法示例 97 3.7 小结 98 第2篇 算法基本应用篇 99 第4章 排序算法 100 4.1 排序算法概述 100 4.2 冒泡排序法 101 4.2.1 冒泡排序算法 101 4.2.2 冒泡排序算法示例 102 4.3 选择排序法 104 4.3.1 选择排序算法 104 4.3.2 选择排序算法示例 105 4.4 插入排序法 107 4.4.1 插入排序算法 107 4.4.2 插入排序算法示例 108 4.5 Shell排序法 110 4.5.1 Shell排序算法 110 4.5.2 Shell排序算法示例 111 4.6 快速排序法 113 4.6.1 快速排序算法 113 4.6.2 快速排序算法示例 114 4.7 堆排序法 116 4.7.1 堆排序算法 116 4.7.2 堆排序算法示例 121 4.8 合并排序法 123 4.8.1 合并排序算法 123 4.8.2 合并排序算法示例 126 4.9 排序算法的效率 129 4.10 排序算法的其他应用 130 4.10.1 反序排序 130 4.10.2 字符串数组的排序 132 4.10.3 字符串的排序 135 4.11 小结 137 第5章 查找算法 138 5.1 查找算法概述 138 5.2 顺序查找 138 5.2.1 顺序查找算法 139 5.2.2 顺序查找操作示例 139 5.3 折半查找 141 5.3.1 折半查找算法 141 5.3.2 折半查找操作示例 142 5.4 数据结构中的查找算法 145 5.4.1 顺序表结构中的查找算法 145 5.4.2 链表结构中的查找算法 148 5.4.3 树结构中的查找算法 151 5.4.4 图结构中的查找算法 152 5.5 小结 153 第6章 基本数学问题 154 6.1 判断闰年 154 6.2 多项式计算 156 6.2.1 —维多项式值 156 6.2.2 二维多项式值 158 6.2.3 多项式乘法 160 6.2.4 多项式除法 161 6.3 随机数生成算法 164 6.4 复数运算 171 6.4.1 简单的复数运算 172 6.4.2 复数的幂运算 174 6.4.3 复指数运算 176 6.4.4 复对数运算 177 6.4.5 复正弦运算 178 6.4.6 复余弦运算 179 6.5 阶乘 180 6.6 计算π的近似值 183 6.6.1 割圆术 183 6.6.2 蒙特卡罗算法 185 6.6.3 级数公式 187 6.7 矩阵运算 190 6.7.1 矩阵加法 190 6.7.2 矩阵减法 191 6.7.3 矩阵乘法 193 6.8 方程解 195 6.8.1 线性方程解——高斯消元法 195 6.8.2 非线性方程解——二分法 200 6.8.3 非线性方程解——牛顿迭代法 202 6.9 小结 205 第7章 复杂的数值计算算法 206 7.1 拉格朗日插值 206 7.1.1 拉格朗日插值算法 206 7.1.2 拉格朗日插值示例 207 7.2 数值积分 210 7.2.1 数值积分算法 210 7.2.2 数值积分示例 211 7.3 开平方 213 7.3.1 开平方算法 213 7.3.2 开平方示例 213 7.4 极值问题的算法 215 7.4.1 极值算法 215 7.4.2 极值解示例 217 7.5 特殊函数的计算算法 221 7.5.1 伽玛函数 221 7.5.2 贝塔函数 224 7.5.3 正弦积分函数 228 7.5.4 余弦积分函数 231 7.5.5 指数积分函数 235 7.6 小结 239 第8章 经典数据结构问題 240 8.1 动态数组排序 240 8.1.1 动态数组的存储和排序 240 8.1.2 动态数组排序示例 241 8.2 约瑟夫环 243 8.2.1 简单约瑟夫环算法 243 8.2.2 简单约瑟夫环解 245 8.2.3 复杂约瑟夫环算法 247 8.2.4 复杂约瑟夫环解 248 8.3 城市之间的最短总距离 250 8.3.1 最短总距离算法 250 8.3.2 最短总距离解 253 8.4 最短路径 257 8.4.1 最短路径算法 258 8.4.2 最短路径解 260 8.5 括号匹配 265 8.5.1 括号匹配算法 265 8.5.2 括号匹配解 267 8.6 小结 270 第9章 数论问题 271 9.1 数论 271 9.1.1 数论概述 271 9.1.2 数论的分类 272 9.1.3 初等数论 273 9.1.4 基本概念 273 9.2 完全数 274 9.2.1 完全数概述 274 9.2.2 计算完全数算法 275 9.3 亲密数 277 9.3.1 亲密数概述 277 9.3.2 计算亲密数算法 277 9.4 水仙花数 280 9.4.1 水仙花数概述 280 9.4.2 计算水仙花数算法 281 9.5 自守数 283 9.5.1 自守数概述 283 9.5.2 计算自守数算法 284 9.6 最大公约数 287 9.6.1 计算最大公约数算法——搌转相除法 287 9.6.2 计算最大公约数算法一一Stein算法 288 9.6.3 计算最大公约数示例 289 9.7 最小公倍数 290 9.8 素数 292 9.8.1 素数概述 292 9.8.2 计算素数算法 292 9.9 回文素数 294 9.9.1 回文素数概述 294 9.9.2 计算回文素数算法 294 9.10 平方回文数 297 9.10.1 平方回文数概述 297 9.10.2 计算平方回文数算法 297 9.11 分解质因数 299 9.12 小结 301 第10 章算法经典趣题 302 0. .l 百钱买百鸡 302 10.1.1 百钱买百鸡算法 302 10.1.2 百钱买百鸡解 303 10.2 五家共井 304 10.2.1 五家共井算法 304 10.2.2 五家共井解 305 10.3 鸡兔同笼 307 10.3.1 鸡兔同笼算法 307 10.3.2 鸡兔同笼解 308 10.4 猴子吃桃 308 10.4.1 猴子吃桃算法 308 10.4.2 猴子吃桃解 309 10.5 舍罕王赏麦 310 10.5.1 舍罕王赏麦问题 310 10.5.2 舍罕王赏麦解 311 10.6 汉诺塔 312 10.6.1 汉诺塔算法 312 10.6.2 汉诺塔解 314 10.7 窃贼问题 315 10.7.1 窃贼问题算法 315 10.7.2 窃贼问题解 317 10.8 马踏棋盘 320 10.8.1 马踏棋盘算法 320 10.8.2 马踏棋盘解 321 10.9 八皇后问题 323 10.9.1 八皇后问题算法 324 10.9.2 八皇后问题解 325 10.10 寻找假银币 327 10.10.1 寻找假银币算法 327 10.10.2 寻找假银币解 329 10.11 青蛙过河 331 10.11.1 青蛙过河算法 331 10.11.2 青蛙过河解 333 10.12 三色旗 335 10.12.1 三色旗算法 335 10.12.2 三色旗解 337 10.13 渔夫捕鱼 339 10.13.1 渔夫捕鱼算法 339 10.13.2 渔夫捕魚解 340 10.14 爱因斯坦的阶梯 341 10.14.1 爱因斯坦的阶梯算法 341 10.14.2 爱因斯坦的阶梯解 342 10.15 兔子产仔 342 10.15.1 兔子产仔算法 343 10.15.2 兔子产仔解 343 10.16 常胜将军 344 10.16.1 常胜将军算法 344 10.16.2 常胜将军解 345 10.17 新郎和新娘 346 10.17.1 新郎和新娘算法 347 10.17.2 新郎和新娘解 348 10.18 三色球 349 10.18.1 三色球算法 349 10.18.2 三色球解 350 10.19 小结 351 第11章 游戏中的算法 352 11.1 洗扑克牌 352 11.1.1 洗扑克牌算法 352 11.1.2 洗扑克牌示例 353 11.2 取火柴游戏 356 11.2.1 取火柴游戏算法 356 11.2.2 取火柴游戏示例 357 11.3 10点半 358 11.3.1 10点半算法 358 11.3.2 10点半游戏示例 363 11.4 生命游戏 368 11.4.1 生命游戏的原理 368 11.4.2 生命游戏的算法 369 11.4.3 生命游戏示例 371 11.5 小结 376 第3篇 算法高级应用篇 377 第12章 密码学算法 378 12.1 密码学概述 378 12.1.1 密码学的发展 378 12.1.2 密码学的基本概念 379 12.1.3 柯克霍夫斯原则 379 12.1.4 经典密码学算法 380 12.2 换位加密解密 381 12.2.1 换位加密解密算法 381 12.2.2 换位加密解密算法示例 383 12.3 替换加密解密 386 12.3.1 替换加密解密算法 386 12.3.2 替换加密解密算法示例 388 12.4 位加密解密 389 12.4.1 位加密解密算法 390 12.4.2 位加密解密算法示例 391 12.5 一次一密加密解密算法 392 12.5.1 一次一密加密解密算法 392 12.5.2 一次一密加密解密算法示例 394 12.6 小结 396 第13章 压缩与解压缩算法 397 13.1 压缩与解压缩概述 397 13.1.1 压缩与解压缩分类 397 13.1.2 典型的压缩解压缩算法 397 13.2 压缩算法 398 13.3 解压缩算法 401 13.4 压缩/解压缩示例 404 13.5 小结 406
java经典算法题例。参赛必做。 【程序14】   题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。   1.程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数。   【程序15】   题目:打印出如下图案(菱形)   *   ***   ******   ********   ******   ***   *   1.程序分析:先把图形分成两部分来看待,前四行一个规律,后三行一个规律,利用双重 for循环,第一层控制行,第二层控制列。   【程序16】   题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...出这个数列的前20项之和。   1.程序分析:请抓住分子与分母的变化规律。   【程序17】   题目:1+2!+3!+...+20!的和   1.程序分析:此程序只是把累加变成了累乘。   【程序18】   题目:利用递归方法5!。   1.程序分析:递归公式:fn=fn_1*4!   【程序19】   题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?   1.程序分析:利用递归的方法,递归分为回推和递推两个阶段。要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。   【程序20】   题目:给一个不多于5位的正整数,要:一、它是几位数,二、逆序打印出各位数字。   【程序21】   题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。   【程序22】   题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母。   1.程序分析:用情况语句比较好,如果第一个字母一样,则判断用情况语句或if语句判断第二个字母。   【程序23】   题目:100之内的素数   【程序24】   题目:对10个数进行排序   1.程序分析:可以利用选择法,即从后9个比较过程中,选择一个最小的与第一个元素交换, 下次类推,即用第二个元素与后8个进行比较,并进行交换。   【程序25】   题目:一个3*3矩阵对角线元素之和   1.程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。   【程序26】   题目:有一个已经排好序的数组。现输入一个数,要按原来的规律将它插入数组中。   1. 程序分析:首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。   【程序27】   题目:将一个数组逆序输出。   1.程序分析:用第一个与最后一个交换。   【程序28】   题目:取一个整数a从右端开始的4~7位。   程序分析:可以这样考虑:   (1)先使a右移4位。   (2)设置一个低4位全为1,其余全为0的数。可用~(~0 < <4)   (3)将上面二者进行&运算。 【程序29】:用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要:"4"不能在第三位,"3"与"5"不能相连。 【程序30】写一个方法,用二分查找法判断任意整数在任意整数数组里面是否存在,若存在就返回它在数组中的索引位置,不存在返回-1
Algorithms   本次README修订为算法仓库Algorithms的第100次commit,首先我们庆祝自2016年8月4日本仓库建立以来Dev-XYS在算法学习方面取得的显著进步!   这里有各种算法C++代码,任何人可以在自己的任何程序中使用,欢迎大家指出代码中的错误以及有待改进的地方。   本仓库内所有代码的授权方式为Unlicense,大家如果使用我的代码开发自己的软件挣了大钱,或是参考我的代码在NOI中得了金牌,我都会很高兴的。使用这里的代码之后,你可以自主选择是否公开源代码。总而言之,你可以把这里的代码当作你自己写的一样,无论怎样使用都是被允许的。但是,我不对本仓库内代码的正确性负责。大家要是使用我的代码开发软件而导致程序崩溃,或是参考我的代码在考试时出错,请不要向我抱怨。如果你愿意,遇到问题可以在Issues中提出来,我们共同解决。我们不赞成Pull Request,因为本仓库主要储存作者已经学习的算法,全部代码均由作者本人负责维护与更新。   以下索引提供了本仓库内算法的中文名,方便大家查找。更新可能有很长时间的延迟,不保证所有算法的名称都在列表中出现。 Index --------------------------Contents-------------------------- --------------------------FileName-------------------------- AC自动机 Aho-Corasick-Automation 单源最短路径(SPFA) Bellman-Ford(Queue-Optimised) 单源最短路径(Bellman-Ford) Bellman-Ford 使用Edmonds-Karp进行二分图匹配 Bigrpah-Matching(Edmonds-Karp) 普通的二叉搜索树 Binary-Search-Tree 广度优先搜索 Breadth-First-Search 冒泡排序 Bubble-Sort 桶排序 Bucket-Sort 组合数的递推解 Combination(Recursion) 枚举组合 Combination 基本的复数类 Complex-Number 割点 Cut-Vertex 深度优先搜索 Depth-First-Search 堆优化的Dijkstra算法 Dijkstra(Heap-Optimised) 并查集 Disjoint-Set-Union 最大流Edmonds-Karp算法 Edmonds-Karp 欧拉函数 Euler's-Totient-Function 有向图的欧拉回路 Eulerian-Tour(Digraph) 拓展欧几里得算法 Extended-Euclid 简单的快速幂 Fast-Exponentiation 树状数组 Fenwick-Tree 所有结点对之间的最短路径(Floyd) Floyd-Warshall 凸包算法(Graham扫描法) Graham-Scan 辗转相除法最大公约数 Greatest-Common-Divisor 堆排序 Heap-Sort ISAP算法 Improved-Shortest-Augmenting-Path(Naive) 插入排序 Insertion-Sort 字符串匹配(KMP) Knuth-Morris-Pratt 最小生成树(Kruskal) Kruskal 最近公共祖先(Tarjan) Least-Common-Ancestor(Tarjan) 使用后缀数组解最长公共子串 Longest-Common-Substring 最长上升子序列(n·log(n)) Longest-Increasing-Subsequence(n·log(n)) 倍增法最近公共祖先 Lowest-Common-Ancestor(Doubling) 朴素的矩阵乘法 Matrix-Multiplication(Naive) 归并排序 Merge-Sort 最小堆 Min-Heap 乘法逆元 Modular-Multiplicative-Inverse 仅支持单点修改的可持久化线段树(维护区间和值) Persistent-Segment-Tree(Sum) 试除法素数测试 Prime-Check(Naive) 线性的素数筛法 Prime-Sieve(Linear) 队列的基本操作 Queue 快速排序的优化版本 Quick-Sort(Extra-Optimised) 快速排序的随机化版本 Quick-Sort(Randomized) 快速排序 Quick-Sort 使用向量叉积判断两个有向线段的时针关系 Segment-Direction 线段树维护区间最大值 Segment-Tree(Maximum) 线段树维护区间最小值 Segment-Tree(Minimum) 线段树维护区间和值 Segment-Tree(Sum) 普通的选择算法 Selection Eratosthenes素数筛法 Sieve-of-Erotosthenes 指针版的单向链表 Singly-Linked-List(Pointer) 跳表 Skip-List ST表 Sparse-Table 伸展树 Splay 博弈论SG函数 Sprague-Grundy 栈的基本操作 Stack 递推法解无符号第一类斯特林数 Stirling-Number(Cycle,Unsigned,Recursion) 递推法解第二类斯特林数 Stirling-Number(Subset,Recursion) 倍增法解后缀数组 Suffix-Array(Doubling) 倍增法解后缀数组(附带Height数组) Suffix-Array-with-Height(Doubling) 使用Tarjan算法解强连通分量 Tarjan(Strongly-Connected-Components) 数组版的字典树 Trie(Array) 指针版的字典树 Trie(Pointer)
本书旨在探讨如何优化算法效率,详细阐述了经典算法和特殊算法的实现、应用技巧和复杂度验证过程,内容由浅入深,能帮助读者快速掌握复杂度适当、正确率高的高效编程方法以及自检、自测技巧,是参加ACM ICPC、Google Code Jam等国际编程竞赛、备战编程考试、提高编程效率、优化编程方法的参考书目。 作者简介 Christoph Dürr,法国国家科学研究院研究员,巴黎皮埃尔-玛丽·居里大学博士生导师,Operation Research科研组研究主任。 Jill-Jênn Vie,法国高等电力学院博士、算法讲师,担任法国高等师范学院Paris-Saclay团队在ACM竞赛中的算法导师;曾任法国国际编程大赛Prologin主席,并于2014年获Google RISE Award。 目录 第 1 章 引言 1 1 1 编程竞赛 1 1 1 1 线上学习网站 3 1 1 2 线上裁判的返回值 4 1 2 我们的选择:Python 5 1 3 输入输出 6 1 3 1 读取标准输入 6 1 3 2 显示格式 9 1 4 复杂度 9 1 5 抽象类型和基本数据结构 11 1 5 1 栈 11 1 5 2 字典 12 1 5 3 队列 12 1 5 4 优先级队列和最小堆 13 1 5 5 并查集 16 1 6 技术 18 1 6 1 比较 18 1 6 2 排序 18 1 6 3 扫描 19 1 6 4 贪婪算法 20 1 6 5 动态规划算法 20 1 6 6 用整数编码集合 21 1 6 7 二分查找 23 1 7 建议 25 1 8 走得更远 27 第 2 章 字符串 28 2 1 易位构词 28 2 2 T9:9 个按键上的文字 29 2 3 使用字典树进行拼写纠正 31 2 4 KMP(Knuth-Morris-Pratt)模式匹配算法 33 2 5 最大边的 KMP 算法 35 2 6 字符串的幂 38 2 7 模式匹配算法:Rabin–Karp 算法 38 2 8 字符串的最长回文子串:Manacher 算法 42 第 3 章 序列 44 3 1 网格中的最短路径 44 3 2 编辑距离(列文斯登距离45 3 3 最长公共子序列 47 3 4 升序最长子序列 49 3 5 两位玩家游戏中的必胜策略 52 第 4 章 数组 53 4 1 合并已排序列表 53 4 2 区间的总和 54 4 3 区间内的重复内容 54 4 4 区间的最大总和 55 4 5 查询区间中的最小值:线段树 55 4 6 计算区间的总和:树状数组(Fenwick 树)57 4 7 有 k 个独立元素的窗口 59 第 5 章 区间 61 5 1 区间树(线段树) 61 5 2 区间的并集 64 5 3 区间的覆盖 64 第 6 章 图 66 6 1 使用 Python 对图编码 66 6 2 使用 C++ 或 Java 对图编码 67 6 3 隐式图 68 6 4 深度优先遍历:深度优先算法 69 6 5 广度优先遍历:广度优先算法 70 6 6 连通分量 71 6 7 双连通分量 74 6 8 拓扑排序 77 6 9 强连通分量 79 6 10 可满足性 84 第 7 章 图中的环 86 7 1 欧拉路径 86 7 2 中国邮差问题 88 7 3 最小长度上的比率权重环:Karp 算法 89 7 4 单位时间成本最小比率环 92 7 5 旅行推销员问题 93 第 8 章 最短路径 94 8 1 组合的属性 94 8 2 权重为 0 或 1 的图 96 8 3 权重为正值或空值的图: Dijkstra 算法 97 8 4 随机权重的图:Bellman-Ford 算法 100 8 5 所有源点 - 目标顶点对:Floyd-Warshall 算法 101 8 6 网格 102 8 7 变种问题 104 8 7 1 无权重图 104 8 7 2 有向无环图 104 8 7 3 最长路径 104 8 7 4 树中的最长路径 104 8 7 5 最小化弧上权重的路径 105 8 7 6 顶点有权重的图 105 8 7 7 令顶点上最大权重最小的路径 105 8 7 8 所有边都属于一条最短路径 105 第 9 章 耦合性和流 106 9 1 二分图最大匹配 107 9 2 最大权重的完美匹配: Kuhn-Munkres 算法 110 9 3 无交叉平面匹配 116 9 4 稳定的婚姻:Gale-Shapley 算法 117 9 5 Ford-Fulkerson 最大流算法 119 9 6 Edmonds-Karp 算法的最大流 121 9 7 Dinic 最大流算法 122 9 8 s-t 最小割 125 9 9 平面图的 s-t 最小割 126 9 10 运输问题 127 9 11 在流和匹配之间化简 127 9 12 偏序的宽度:Dilworth 算法 129 第 10 章 树 132 10 1 哈夫曼编码 133 10 2 最近的共同祖先 135 10 3 树中的最长路径 138 10 4 最小权重生成树:Kruskal 算法 140 第 11 章 集合 142 11 1 背包问题 142 11 2 找零问题 143 11 3 给定总和值的子集 145 11 4 k 个整数之和 146 第 12 章 点和多边形 148 12 1 凸包问题 149 12 2 多边形的测量 150 12 3 最近点对 151 12 4 简单直线多边形 153 第 13 章 长方形 156 13 1 组成长方形 156 13 2 网格中的最大正方形 157 13 3 直方图中的最大长方形 158 13 4 网格中的最大长方形 159 13 5 合并长方形 160 13 6 不相交长方形的合并 164 第 14 章 计算 165 14 1 最大公约数 165 14 2 贝祖等式 165 14 3 二项式系数 166 14 4 快速幂 167 14 5 素数 167 14 6 计算算数表达式 168 14 7 线性方程组 170 14 8 矩阵序列相乘 174 第 15 章 穷举 176 15 1 激光路径 176 15 2 精确覆盖 179 15 3 数独 184 15 4 排列枚举 186 15 5 正确计算 188 调试工具 191 参考文献 192

64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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