c++ - 使用单链表筛选 Eratosthenes C++
问题描述
嗨,我对 C++ 中的 Eratosthenes 筛有疑问。我必须使用单链表来做到这一点。我的程序正在运行并显示列表的第一个声明,但我不知道如何正确删除非素数。我的功能对我不起作用。我应该如何更改我的删除功能?
#include <iostream>
#include <cmath>
using namespace std;
struct List
{
int number;
List* next;
};
List* head = new List;
void l_add(int n)
{
List* temp = head;
for (int i = 2; i <= n; i++)
{
temp->next = new List();
temp->number = i;
temp = temp->next;
}
}
void l_print()
{
List* temp = head;
while (temp->next != 0)
{
cout << temp->number << " ";
temp = temp->next;
}
cout << endl;
}
void l_delete(int n)
{
List* temp = head;
for (int i = 2; i < sqrt(n); i++)
{
if (temp->number % i == 0)
{
head = temp->next;
delete temp;
temp = head;
}
while (temp->next != 0)
{
if (temp->next->number % i == 0)
{
temp->next = temp->next->next;
delete temp->next;
}
temp = temp->next;
}
}
}
int main()
{
int n;
cout << "Enter up to which number to find prime numbers using Sieve of Eratosthenes: " << endl;
cin >> n;
l_add(n);
l_print();
l_delete(n);
l_print();
return 0;
}
解决方案
这将是 l_delete 方法的工作版本:
void l_delete(int n)
{
List* temp = head;
for (int i = 2; i < sqrt(n); i++)
{
while (temp->next != 0)
{
if (temp->next->number % i == 0 && temp->next->number != i)
{
List* temp2 = temp->next->next;
delete temp->next;
temp->next = temp2;
}
if(temp->next == 0) break;
temp = temp->next;
}
temp = head;
if (temp->number % i == 0 && temp->number != i)
{
head = temp->next;
delete temp;
temp = head;
}
}
}
您的删除方法有几个问题。算法逻辑的问题:你的算法头应该最后检查,否则如果它被删除,新的头不会检查素数,你会立即检查新的下一个,它是旧的->下一个->下一个。此外,您没有检查数字是否等于分隔符,在这种情况下不应将其删除。
编程逻辑问题:当你在while循环中删除下一个节点时,与删除head时一样,你需要另一个临时变量来存储temp->next->next,然后在删除后将其分配给temp->next。
但这里最大的问题是,这根本不是 Eratosthenes 筛子,你只是在检查所有数字与所有其他小于 sqrt(n) 的数字的可分性。与 Eratosthenes 筛相比,它是次优的。如果你用谷歌搜索 Eratosthenes 筛子,你会发现很多详细的教程和解释。
推荐阅读
- html - 水平和垂直居中 h1 和 h2
- jquery - 本地主机上 reCaptcha 的 postMessageId 错误
- fabricjs - 如何在 FabricJS 中获取部分文本的边界?
- java - 如何在旧版 Android 中降级 java.time 代码?
- php - admin-post.php 请求中的 WordPress $_POST 为空
- node.js - 首次使用 Node 和 pg 创建数据库后如何创建表
- c++ - 无需等待响应的 HTTP 发布
- python - 从嵌入在一个中的两个字典中提取数据并合并数据
- python - 通过自举的置信区间
- c# - 使用 StartsWith 的 Lambda 过滤在 c# 中不起作用