我想做的任务很简单,不知何故会让程序崩溃。
我有一个包含在其中的数字列表,都是唯一的。过了一定数,我想颠倒顺序。
示例:5,16,11, 3,8,4 - >使用3作为支点时,5,16,11, 4,8,3 。
以下是我尝试过的众多方法之一。
private List<int> ShiftPath(List<int> oldPath, int shift)
{
List <int> newPath = new List<int>();
int counter = 0;
// Start reordering
// Forwards
while (oldPath[counter] != shift)
{
newPath.Add(oldPath[counter]);
counter++;
}
// Backwards
counter = oldPath.Count - 1;
while (oldPath[counter] != shift)
{
newPath.Add(oldPath[counter]);
counter--;
}
// New endpoint
newPath.Add(shift);
// Update
return newPath;
}
现在这个有效。它可能不是最佳解决方案,但它确实有效。我已经使用这种方法已经有一段时间了,但是现在我已经达到了列表中的项目数量变得非常大(超过6,000)的程度。最后,当我尝试向newPath添加内容时,我得到了一个StackOverFlowException。
我百分百肯定没有像VS声称的无限循环。我已经尝试过其他方法,例如直接获取项目范围,for和foreach循环而不是while,最终都会崩溃。似乎数据量太大了。而且它会变得更大(超过20,000)。
证明(?):即使这会使程序抛出异常:List&lt; int&gt; newPath = new List&lt; int&gt;(oldPath);
有关导致此问题/如何解决问题的任何想法?
- 从初学者开始。
答案 0 :(得分:3)
堆栈溢出不能出现在您向我们展示的代码中,因为那里没有递归。查找代码执行递归的位置。更好的是,当您获得StackOverflowException时,您获得的堆栈跟踪是什么?这将告诉你在递归中你的代码将进入无限递归循环。
普通的旧无限循环不会导致StackOverflowException。为了实现这一点,您需要进行不会结束的递归,直到堆栈耗尽为止。
答案 1 :(得分:2)
StackOverflowException
没有出现,因为List
中的项目太多(可能是OutOfMemoryException
),当你进行太多的方法调用时会发生这种情况,通常是因为递归。
作为旁注,int
中的6,000 List
s无效。我刚刚运行了一些测试代码,在获得OutOfMemoryException
之前,它在列表中添加了多达6700万个整数。
答案 2 :(得分:0)
我可能会解决这个问题:
List<int> reverseMe = new List<int>();
List<int> reversedList = new List<int>();
reverseMe.Add(5);
reverseMe.Add(16);
reverseMe.Add(11);
reverseMe.Add(3);
reverseMe.Add(8);
reverseMe.Add(4);
int pivotPoint = 3;
for (int c = 0; c < reverseMe.Count; c++)
{
if (c >= pivotPoint)
{
reversedList.Add(reverseMe[reverseMe.Count - c + pivotPoint - 1]);
}
else
{
reversedList.Add(reverseMe[c]);
}
}
这使用原始列表空间的两倍,但是20k并不是真正的问题,对我来说至少它更具可读性 - 并且不应该遇到任何StackOverflow异常
修改我的算法(不像第一个那样经过测试,并且没有多少想法进入计算for条件的最佳方法)
int temp;
for (int c2 = pivotPoint; c2 < reverseMe.Count - ((reverseMe.Count - pivotPoint) / 2); c2++)
{
temp = reverseMe[reverseMe.Count - c2 + pivotPoint - 1];
reverseMe[reverseMe.Count - c2 + pivotPoint - 1] = c2;
reverseMe[c2] = temp;
}
答案 3 :(得分:0)
我必须同意@Eddie - 看起来你没有向我们展示导致堆栈溢出的代码 - 你向我们展示的代码不会导致堆栈溢出。
使用.NET 3.5的另一种解决方案:
class Program
{
static void Main(string[] args)
{
const int where = 5;
var aList = new List<int>();
for (var i=0; i < 100; i++)
aList.Add(i);
var reversed = aList.Take(where).Concat(Enumerable.Reverse(aList)
.Take(aList.Count - where));
Console.WriteLine(String.Join(",",
reversed.Select(i => i.ToString()).ToArray()));
Console.ReadLine();
}
}
答案 4 :(得分:0)
感谢您的回答,这有助于我确定问题
之前我确实有一个递归。但我肯定它不是无限的(这就是为什么我不认为这是问题,特别是因为它不是溢出发生的地方)。它大致可以描述为:
搜索(参数)
--SomeParameters.ShiftPath
- 转移有用吗?
----是 - &gt;退出递归
----否 - &gt;我们可以转移更多吗?
------是 - &gt;搜索(新参数)
------否 - &gt;回溯
(搜索的效果在很大程度上取决于数千个其他代码行提供的数据 - 但代码确实适用于较小的问题。)
因为在找到答案之前它可以非常深入,我想这是导致溢出的原因吗?所以我想我会尝试另一种方法,比如使用堆:
虽然(只要需要)
--ArrayOfParameters.Last()。ShiftPath
- 转移有用吗?
----是 - &gt;退出循环
----否 - &gt;我们可以转移更多吗?
-------是 - &gt;将当前参数添加到ArrayofParameters
-------否 - &gt; Backtrack - 删除ArrayOfParameters.Last()