#include <iostream>
#include <vector>
#include <thread>
#include <fstream>
#include <mutex>
#include "BigInt.h"
#include <Windows.h>
#include <deque>
#include <algorithm>
#define KEY_DOWN(vkey) ((GetAsyncKeyState(vkey)&0x8000)?0:1)
using namespace std;
BigInt a, b;
string kfp[1024]; // 保存多个kp文件的路径
ofstream fout;
bool isp;
bool termin;
bool on[1024];
unsigned long long sos[1024], eos[1024];
bool readone[1024];
std::vector<BigInt> kp[1024]; // 多个kp数组
int kp_count = 0; // kp文件的数量
std::vector<BigInt> nbkp;
void checkPrimesInSegment(int i, bool& isp, const std::vector<BigInt>& kp) {
while (!termin) {
if (on[i]) {
for (auto p = sos[i]; p <= eos[i]; p++) {
if (p >= kp.size()) {
cout << "Out of range: p=" << p << " eos[i]=" << eos[i] << " kp.size()=" << kp.size() << "\n";
on[i] = 0; // 避免无限循环
break;
}
BigInt prime = kp[p];
if (prime * prime > a) {
on[i] = 0;
break;
}
if (a % prime == BigInt("0")) {
isp = false;
on[i] = 0;
break;
}
}
on[i] = 0;
}
}
return;
}
void SetPCC(BigInt a, BigInt b, int thread_count) {
fout.open("pcc.txt");
fout << a << " " << b << '\n' << thread_count << '\n';
for (int i = 0; i < kp_count; i++) {
if(kfp[i]!="NULL")
fout << kfp[i] << '\n';
}
fout.close();
}
void ReadPrimesFromFile(std::vector<BigInt>& kp, const std::string filename,int i)
{
std::ifstream fin(filename);
if (fin.is_open())
{
string temp;
BigInt te, form(0);
while (fin >> temp)
{
te = temp;
if (te * te > b || te < form)
break;
if (i == -1)
{
form = te;
kp.push_back(te);
continue;
}
while (te * te > a)
{
if (readone[i])
break;
}
form = te;
kp.push_back(te);
// cout << "Readone! " << kp.size()<<endl;
readone[i] = 0;
}
fin.close();
}
}
void mergeKpFiles(std::vector<string> files) {
vector<pair<BigInt, BigInt>> ranges(files.size());
// 获取每个文件的范围
for (int i = 0; i < files.size(); i++) {
ifstream fin(files[i]);
if (fin.is_open()) {
BigInt first, last;
string temp;
fin >> temp;
first = temp;
while (fin >> temp) {
last = temp;
}
ranges[i] = make_pair(first, last);
fin.close();
}
}
// 合并范围重叠的文件
for (int i = 0; i < files.size(); i++) {
for (int j = i + 1; j < files.size(); j++) {
if (ranges[i].second >= ranges[j].first) { // 检查重叠
vector<BigInt> merged_primes;
ReadPrimesFromFile(merged_primes, files[j],-1);
ofstream fout(files[i],ios::app);
for (auto& jp : merged_primes)
{
if (jp > ranges[i].second)
fout << '\n' << jp;
}
fout.close();
remove(files[j].c_str()); // 删除被合并的文件
ranges[j] = ranges.back();
ranges.pop_back();
files[j] = files.back();
files.pop_back();
kfp[j] = "NULL";
kp_count--;
j--; // 重新检查当前j位的文件
}
}
}
}
void findPrimesInRange(BigInt& a, BigInt b, int thread_count) {
ofstream ufout("primes.txt", ios::app);
std::vector<std::thread> threads;
if (kp[0].size() == 0) {
for (BigInt i = a; i > 2; i = i - BigInt(2)) {
bool oldflag = 0;
for (BigInt j = 3; j * j <= a; j = j + BigInt(2)) {
if (i % j == 0) {
oldflag = 1;
break;
}
}
if (oldflag == 0) {
kp[0].push_back(i);
break;
}
}
}
for (int i = 0; i < kp_count; ++i)
{
if (kp[i].size() == 0)
{
// cout << i << "readone requested!\n";
readone[i] = 1;
while(readone[i]){}
}
}
for (int i = 0; i < thread_count; ++i) {
threads.emplace_back(checkPrimesInSegment, i, std::ref(isp), std::ref(kp[0]));
}
while (a <= b) {
isp = 1;
for (auto& np : nbkp)//这个方法稍微有些低效
{
if (np * np < a)
kp[kp_count].push_back(np);
}
for (int qwe = 0; qwe < kp_count; qwe++)
{
if (!isp)
{
a = a + BigInt(2);
SetPCC(a, b, thread_count);
break;
}
for (int i = 0; i < thread_count; i++)
on[i] = 0;
int segment_size = kp[qwe].size() / thread_count;
for (int i = 0; i < thread_count; ++i) {
sos[i] = i * segment_size;
eos[i] = (i == thread_count - 1) ? kp[qwe].size() - 1 : (i + 1) * segment_size;
}
for (int i = 0; i < thread_count; i++)
on[i] = 1;
while (1) {
if (!isp) {
for (int i = 0; i < thread_count; i++)
on[i] = 0;
// cout << a << " do not pass kp[" << qwe << "] check.\n";
// Sleep(1000);
break;
}
int count = 0;
for (int i = 0; i < thread_count; i++) {
if (!on[i])
count++;
}
if (count == thread_count)
break;
}
if (isp) {
if (qwe == 0&&kp_count>1)
{
for (BigInt k =3; k < kp[qwe].front() && k * k <= a; k = k + BigInt(2)) {
if (a % k == 0) {
// cout << a << " do not pass kp[0]'s front check.\n";
// Sleep(1000);
isp = 0;
break;
}
}
if (!isp)
continue;
}
if (qwe == kp_count- 1&&kp_count>1)
{
// cout << qwe << "called back at pigu!\n";
for (BigInt k = kp[qwe].back() + BigInt(2); k * k <= a; k = k + BigInt(2)) {
if (a % k == 0) {
// cout << a << " do not pass kp[kp_count]'s back check.\n";
// Sleep(1000);
isp = 0;
break;
}
}
if (!isp)
continue;
}
if(qwe!=0&&qwe!=kp_count-1)
{
// cout << kp[qwe].size() << "called back at normal! "<<qwe<<endl;
for (BigInt k = kp[qwe-1].back()+BigInt(2); k < kp[qwe].front() && k * k <= a; k = k + BigInt(2)) {
if (a % k == 0) {
// cout << a << " do not pass kp["<<qwe<<"]'s front check.\n";
// Sleep(1000);
isp = 0;
break;
}
}
if (!isp)
continue;
}
}
}
if (isp)
{
// cout << a << " PASSED!\n";
ufout << a << '\n';
nbkp.push_back(a);
a = a + BigInt(2);
SetPCC(a, b, thread_count);
}
}
termin = 1;
for (auto& th : threads) {
th.join();
}
ufout.close();
}
int main() {
int thread_count;
ifstream fin("pcc.txt");
thread RPFF[1024];
if (fin.is_open()) {
vector<string> files;
string ta, tb;
fin >> ta >> tb;
a = ta;
b = tb;
if (a > b) {
cout << "Invalid range.\n";
return 0;
}
fin >> thread_count;
string temp;
int kfpdei = 0;
while (fin >> temp) {
files.push_back(temp);
kfp[kfpdei] = temp;
++kfpdei;
++kp_count;
}
fin.close();
mergeKpFiles(files); // 合并重叠的kp文件
// Sleep(100000);
for (int i = 0; i < kp_count; i++)
{
RPFF[i] = thread(ReadPrimesFromFile, std::ref(kp[i]), kfp[i],i);
}
if (a <= 2 && b >= 2) {
fout.open("primes.txt");
fout << 2 << '\n';
fout.close();
a = 3;
}
if (a % 2 == 0)
a = a + BigInt(1);
if (b % 2 == 0)
b = b - BigInt(1);
findPrimesInRange(a, b, thread_count);
for (int i = 0; i < thread_count; i++)
RPFF[i].join();
}
return 0;
}
BigInt.h:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
class BigInt {
private:
std::vector<int> digits;
bool is_negative;
// Helper function to remove leading zeros
void removeLeadingZeros() {
while (digits.size() > 1 && digits.back() == 0) {
digits.pop_back();
}
if (digits.size() == 1 && digits[0] == 0) {
is_negative = false;
}
}
public:
// Constructors
BigInt() : is_negative(false) { digits.push_back(0); }
BigInt(const std::string& number) { *this = number; }
BigInt(int number) { *this = std::to_string(number); } // 支持整数初始化
// Assignment operator
BigInt& operator=(const std::string& number) {
digits.clear();
is_negative = false;
int start = 0;
if (number[0] == '-') {
is_negative = true;
start = 1;
}
for (int i = number.length() - 1; i >= start; --i) {
if (isdigit(number[i])) {
digits.push_back(number[i] - '0');
}
}
removeLeadingZeros();
return *this;
}
// Display
friend std::ostream& operator<<(std::ostream& os, const BigInt& num) {
if (num.is_negative) {
os << '-';
}
for (int i = num.digits.size() - 1; i >= 0; --i) {
os << num.digits[i];
}
return os;
}
// Comparison
bool operator==(const BigInt& other) const {
return is_negative == other.is_negative && digits == other.digits;
}
bool operator!=(const BigInt& other) const {
return !(*this == other);
}
bool operator<(const BigInt& other) const {
if (is_negative != other.is_negative) {
return is_negative;
}
if (digits.size() != other.digits.size()) {
return is_negative ? digits.size() > other.digits.size() : digits.size() < other.digits.size();
}
for (int i = digits.size() - 1; i >= 0; --i) {
if (digits[i] != other.digits[i]) {
return is_negative ? digits[i] > other.digits[i] : digits[i] < other.digits[i];
}
}
return false;
}
bool operator<=(const BigInt& other) const {
return *this < other || *this == other;
}
bool operator>(const BigInt& other) const {
return !(*this <= other);
}
bool operator>=(const BigInt& other) const {
return !(*this < other);
}
// Addition
BigInt operator+(const BigInt& other) const {
if (is_negative == other.is_negative) {
BigInt result;
result.is_negative = is_negative;
result.digits.clear();
int carry = 0, i = 0;
while (i < digits.size() || i < other.digits.size() || carry) {
int sum = carry;
if (i < digits.size()) sum += digits[i];
if (i < other.digits.size()) sum += other.digits[i];
result.digits.push_back(sum % 10);
carry = sum / 10;
i++;
}
result.removeLeadingZeros();
return result;
}
return *this - (-other);
}
// Subtraction
BigInt operator-(const BigInt& other) const {
if (is_negative == other.is_negative) {
if (abs() >= other.abs()) {
BigInt result;
result.is_negative = is_negative;
result.digits.clear();
int borrow = 0, i = 0;
while (i < digits.size() || i < other.digits.size() || borrow) {
int diff = (i < digits.size() ? digits[i] : 0) - (i < other.digits.size() ? other.digits[i] : 0) - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
}
else {
borrow = 0;
}
result.digits.push_back(diff);
i++;
}
result.removeLeadingZeros();
return result;
}
return -(other - *this);
}
return *this + (-other);
}
// Multiplication
BigInt operator*(const BigInt& other) const {
BigInt result;
result.digits.resize(digits.size() + other.digits.size(), 0);
result.is_negative = is_negative != other.is_negative;
for (size_t i = 0; i < digits.size(); ++i) {
int carry = 0;
for (size_t j = 0; j < other.digits.size() || carry; ++j) {
int sum = result.digits[i + j] + digits[i] * (j < other.digits.size() ? other.digits[j] : 0) + carry;
carry = sum / 10;
result.digits[i + j] = sum % 10;
}
}
result.removeLeadingZeros();
return result;
}
// Division and Modulo
BigInt operator/(const BigInt& other) const {
if (other == BigInt("0")) throw std::runtime_error("Division by zero!");
BigInt dividend = abs();
BigInt divisor = other.abs();
BigInt quotient, remainder;
quotient.digits.resize(dividend.digits.size(), 0);
for (int i = dividend.digits.size() - 1; i >= 0; --i) {
remainder = remainder * 10 + dividend.digits[i];
int div = 0;
while (remainder >= divisor) {
remainder = remainder - divisor;
++div;
}
quotient.digits[i] = div;
}
quotient.is_negative = is_negative != other.is_negative;
quotient.removeLeadingZeros();
return quotient;
}
BigInt operator%(const BigInt& other) const {
return *this - (*this / other) * other;
}
// Negation
BigInt operator-() const {
BigInt result = *this;
result.is_negative = !is_negative;
return result;
}
// Absolute value
BigInt abs() const {
BigInt result = *this;
result.is_negative = false;
return result;
}
BigInt operator+(int num) const {
return *this + BigInt(num);
}
BigInt operator-(int num) const {
return *this - BigInt(num);
}
BigInt operator*(int num) const {
return *this * BigInt(num);
}
BigInt operator/(int num) const {
return *this / BigInt(num);
}
BigInt operator%(int num) const {
return *this % BigInt(num);
}
bool isPrime(const std::vector<BigInt>& primeArray) const {
// 如果数小于2,则不是质数
if (*this < BigInt("2")) return false;
// 逐一检查 primeArray 中的质数是否是 BigInt 的因子
for (const auto& prime : primeArray) {
if (prime * prime > *this) break; // 如果 prime 的平方大于当前数,停止检查
if (*this % prime == BigInt("0")) return false; // 如果能整除,说明不是质数
}
// 如果没有任何质因数能整除,说明是质数
return true;
}
};
出现了vecotr越界访问的情况,在Visual Studio 2022环境下编译