我是一个非常业余的C#开发人员,他试图使用Visual Studio在MacOS上制作此控制台程序。我在学校做,但是我很自学,并且已经为此工作了不到两个星期,所以我很可能错过了一些简单的解决方案。
我已经制作了一个程序,该程序读取了一个填充质数的文本文件并将其转换为列表,然后开始生成素数,同时将它们添加到列表和文件中,并同时报告信息。一个新的。
这是我拥有的代码:
String fileLocation = "Prime Number List.txt"; //sets the file location to the root of where the program is stored
if (!File.Exists(fileLocation)) //tests if the file has already been created
{
using (FileStream fs = File.Create(fileLocation))
{
Byte[] info = new UTF8Encoding(true).GetBytes("2"); //if not, it creates the file and creates the initial prime number of 2
fs.Write(info, 0, info.Length);
}
}
List<string> fileContents = File.ReadAllLines(fileLocation).ToList(); //imports the list of prime numbers from the file
List<int> listOfPrimeNumbers = fileContents.ConvertAll(s => Int32.Parse(s)); //converts the list into the integer variable type
int currentNumber = listOfPrimeNumbers[listOfPrimeNumbers.Count() - 1]; //sets the current number to the most recent prime number
bool isPrime; //initializing the primality test variable
int numbersGeneratedThisSession = 0; //initializing the variable for the amount of primes found in this session
var loopStart = DateTime.Now; //initializes the program start time, ignoring the time taken to load the file list
while (true)
{
isPrime = true; //defaults the number to prime
currentNumber++; //repeats the cycle for the next number
double currentNumberRoot = Math.Sqrt(System.Convert.ToDouble(currentNumber));
for (int i = 0; i < listOfPrimeNumbers.Count; i++) //cyles through all of the primes in the list. no reason to divide by composites, as any number divisible by a
//composite would be divisible by the prime factors of that composite anyway, thus if we were to divide by
//every number it would slow down the program
{
if (listOfPrimeNumbers[i] < Math.Sqrt(System.Convert.ToDouble(currentNumber))) //filters out any prime numbers greater than the square root of the current number, as any potential
//factor pair would have one of the values less than or equal to the square root
{
if (currentNumber % listOfPrimeNumbers[i] == 0) //checks for the even division of the current number by the current prime
{
isPrime = false; //if an even division is found, it reports that the number isn't false and breaks the loop
break;
}
}
else
break; //if no even divisons are found, then it reaches this point with the primality test variable still true, and breaks the loop
}
if (isPrime) //this section of the code activates when the primality test variable is true
{
listOfPrimeNumbers.Add(currentNumber); //adds the new prime to the list
File.AppendAllText(fileLocation, Environment.NewLine + currentNumber); //adds the new prime to the file on a new line
numbersGeneratedThisSession++; //raises the counter for the prime numbers generated in this session
var runtime = DateTime.Now - loopStart; //calculates the runtime of the program, excluding the time taken to load the file into the list
int runtimeInSecs = (runtime.Milliseconds / 1000) + runtime.Seconds + (runtime.Minutes * 60) + (runtime.Hours * 360) + (runtime.Days * 86400); //converts the datetime var into an int of seconds
int generationSpeed = runtimeInSecs == 0 ? 0 : numbersGeneratedThisSession / runtimeInSecs;
Console.WriteLine("nI've generated {0} prime numbers, {1} of those being in the current session." +
"nI've been running for {2}, which means I've been generating numbers at a speed of {3} primes per second. " +
"nThe largest prime I've generated so far is {4}, which is {5} digits long.",
listOfPrimeNumbers.Count(), numbersGeneratedThisSession, runtime, generationSpeed, currentNumber, currentNumber.ToString().Length);
}
}
我一直在" listofprimenumbers.add(currentnumber("上获得例外;部分。我已经阅读了类似的问题,对他人问题的最常见解决方案是将gcallyverylargeobjects设置为true,以打破2GB的限制。这对我来说将是一个暂时的修复,但是随着时间的流逝,列表将不断遇到计算机功能的限制而不是Visual Studio Cap的极限。
会有一点。我想知道是否有一些经验丰富的开发人员用来绕过此问题的技术,例如将数据分为多个列表,做与简化代码不同的事情等。我知道,由于我程序的性质是不可避免的,最终数据会增长太大,但是我试图将其推迟到现在的文件尽可能长的时间,而不是一半的演出,这是一个不合理的记忆崩溃程序。
我还要注意,我每天都在统计反馈(这意味着文件读数,写作和生成代码本身在这段时间内都没有受到影响(过去一周。我在启动的任何时间都没有问题,而且它的最后一次运行顺利进行(由于不记忆的例外,并没有崩溃(。今天我只是尝试再次开始时才遇到这个问题。
.net中的单个数组或列表都受所有限制:
- 2GIB对象限制(除非启用
gcAllowVeryLargeObjects
( - 可用的过程内存(特别与32位过程有关(
- 2,146,435,071个每个维度的项目(单字节值2,147,483,591(
如果您在这些问题附近获得,则是:您需要另一种方法。移至您将作为复合块视为的多个单独列表应充当定格间隙,但是...我认为这最终不是计算质数的非常可扩展的方法。
由于您正在使用他的程序搜索素数,因此,如果您只是尝试将其存储在上述内存中,就会用尽内存。
分开列表将有所帮助,但最终您会遇到相同的问题;5组3个项目是15个项目,分组与否。您将迅速填补记忆。
我认为您的问题可能在这里:
List<string> fileContents = File.ReadAllLines(fileLocation).ToList(); //imports the list of prime numbers from the file
List<int> listOfPrimeNumbers = fileContents.ConvertAll(s => Int32.Parse(s)); //converts the list into the integer variable type
这两个Lists<T>
都是不必要的。您的文件中有运输返回(您的条目中正在插入Environment.NewLine
(,因此假设您只想继续关闭的位置,则需要从该文件中恰好一个值:
//note that I used ReadLines, not ReadAllLines
int lastNumber;
if(!int.TryParse(File.ReadLines(fileLocation).ToList().Last(), out lastNumber))
{
//last value wasn't a valid integer. Start over.
lastNumber = 1;
}
然后,使用lastNumber
执行所有逻辑,在素数时写入文件,并且根本不存储集合。这将使您的新限制因素成为目标计算机上的存储空间。如果您用完存储器的内存加载文件并获取最后一个字符串,则需要整理一些涉及向后读取文件的代码,但是由于这是一个更具学术的项目,我怀疑您需要将其视为远的。