相关疑难解决方法(0)

为什么尾调用优化需要操作码?

所以我之前已经阅读了很多次,技术上.NET 确实支持尾调用优化(TCO),因为它有操作码,只有C#不生成它.

我不确定为什么TCO需要操作码或它会做什么.据我所知,能够进行TCO的要求是递归调用的结果不与当前函数范围中的任何变量组合.如果你没有那个,那么我看不到操作码如何阻止你必须保持堆栈框架打开.如果你有,那么编译器是否总能轻易地将其编译为迭代的东西?

那么操作码有什么意义呢?显然有一些我不知道的东西.在完全可以使用TCO的情况下,不能总是在编译器级别处理,而不是在操作码级别处理?什么是不能的例子?

.net c# theory cil tail-call-optimization

13
推荐指数
1
解决办法
436
查看次数

C#编译与尾递归优化?

基于丰富的stackoverflow,我一直在研究是否对特定的c#代码进行了尾递归优化.一些问题似乎在讨论

  1. 推测正在发布的更新版本的.net中的优化
  2. 构建应用程序作为x64bit应用程序来实现优化
  3. 在Visual Studio中从调试版本切换到发布版本以实现优化
  4. 根本没有优化,并且微软社区声称他们不会对"安全问题"进行尾递归优化(实际上并不理解这个问题)
  5. 它是随机发生的

从C#4.0(Visual Studio 2013/2015)开始,如果可以确保尾递归优化,如何确保尾递归优化呢?

c# recursion tail-recursion c#-4.0

12
推荐指数
1
解决办法
4037
查看次数

如何避免更改堆栈大小并避免在C#中获得堆栈溢出

我一直想在网上和这个网站上找几个小时回答这个问题的答案,我不在那里.

我知道.NET会为应用程序分配1MB,并且最好通过重新编码而不是强制堆栈大小来避免堆栈溢出.

我正在开发一个"最短路径"的应用程序,可以运行大约3000个节点,此时它会溢出.这是导致问题的方法:

    public void findShortestPath(int current, int end, int currentCost)
    {
        if (!weight.ContainsKey(current))
        {
            weight.Add(current, currentCost);
        }
        Node currentNode = graph[current];
        var sortedEdges = (from entry in currentNode.edges orderby entry.Value ascending select entry);
        foreach (KeyValuePair<int, int> nextNode in sortedEdges)
        {
            if (!visited.ContainsKey(nextNode.Key) || !visited[nextNode.Key])
            {
                int nextNodeCost = currentCost + nextNode.Value;
                if (!weight.ContainsKey(nextNode.Key))
                {
                    weight.Add(nextNode.Key, nextNodeCost);
                }
                else if (weight[nextNode.Key] > nextNodeCost)
                {
                    weight[nextNode.Key] = nextNodeCost;
                }
            }
        }
        visited.Add(current, true);
        foreach (KeyValuePair<int, int> nextNode in sortedEdges)
        {
            if(!visited.ContainsKey(nextNode.Key) …
Run Code Online (Sandbox Code Playgroud)

c# stack-overflow

7
推荐指数
3
解决办法
706
查看次数

在C#中只编写等效于副作用自由编程的静态方法吗?

我有两个问题,源于观察到的C#静态方法的行为(我可能会误解):

第一:递归静态方法在某种意义上是通过静态方法在封面下实现的方式进行尾调用优化吗?

第二:使用静态方法编写整个应用程序并且没有超出局部范围的变量,它是否等同于函数式编程?我很想知道,因为我仍然没有把这个"没有副作用"的术语包围起来,我一直听说功能性编程.

编辑:让我提一下,我确实使用并理解为什么以及何时在正常的C#OO方法中使用静态方法,并且我确实理解尾部调用优化不会明确地对递归静态方法进行.也就是说,我理解尾部调用优化是尝试在每次传递时停止创建新的堆栈帧,并且我在几个点观察到在它的调用方法的框架内执行的似乎是一个静态方法,尽管我可能误解了我的观察.

.net c# static functional-programming

6
推荐指数
1
解决办法
912
查看次数

如何避免堆栈溢出?

我使用CSharpCodeProvider编译我的代码,并在结果汇编中动态创建某个类的实例.比我叫一些方法.如果方法有递归,我得到StackOverflowException,我的应用程序终止.

我该如何避免这种情况?

using System;
using System.Runtime.Remoting;
namespace TestStackOverflow
{
    class Program
    {
        class StackOver : MarshalByRefObject
        {
            public void Run()
            {
                Run();
            }
        }

        static void Main(string[] args)
        {
        AppDomain domain = AppDomain.CreateDomain("new");

        ObjectHandle handle = domain.CreateInstance(typeof (StackOver).Assembly.FullName, typeof (StackOver).FullName);
        if (handle != null)
        {
            StackOver stack = (StackOver) handle.Unwrap();
            stack.Run();
        }

    }
}
}
Run Code Online (Sandbox Code Playgroud)

有关:

什么是堆栈溢出?

.net c# .net-2.0

5
推荐指数
2
解决办法
4729
查看次数

从F#调用C#函数

我试图从f#调用这个函数

http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.cloudstorageaccount.setconfigurationsettingpublisher.aspx

功能签名是:

CloudStorageAccount.SetConfigurationSettingPublisher
      (Action<string, Func<string, bool>>) : unit
Run Code Online (Sandbox Code Playgroud)

C#调用是这样的:

CloudStorageAccount.SetConfigurationSettingPublisher((configName,
                                                  configSettingPublisher) =>
{
    string configValue = "something"
    configSettingPublisher(configValue);
});
Run Code Online (Sandbox Code Playgroud)

而在F#中,我必须做这样的事情:

let myPublisher configName (setter:Func<string, bool>) =
    let configValue = RoleEnvironment.GetConfigurationSettingValue(configName)
    setter.Invoke(configName) |> ignore

let act = new Action<string, Func<string, bool>>(myPublisher)

CloudStorageAccount.SetConfigurationSettingPublisher(act)
Run Code Online (Sandbox Code Playgroud)

这可以在f#中更简洁地写出来吗?

c# f#

4
推荐指数
1
解决办法
2928
查看次数

如何压平树

我有一个包含的嵌套列表

public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; set; }

    public List<Person> Childs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

该列表可以像这样使用:

var Persons = new List<Person>();
Persons.Add(new Person("Eric"));
Persons[0].Childs = new List<Person>();
Persons[0].Childs.Add(new Person("Tom"));
Persons[0].Childs.Add(new Person("John"));
Persons[0].Childs[0].Childs = new List<Person>();
Persons[0].Childs[0].Childs.Add(new Person("Bill"));
Persons.Add(new Person("John");
Run Code Online (Sandbox Code Playgroud)

如何展平这棵树(将所有节点和子节点以及子子节点放入列表中),例如,我想在同一级别上使用“参数”级别显示所有子级和父级。这意味着:

之前:

-Eric
    -Tom
    -John
        -Bill
Run Code Online (Sandbox Code Playgroud)

我想要的是:

-Eric, Level1
-Tom, Level2
-John, Level2
-Bill, Level3
Run Code Online (Sandbox Code Playgroud)

c# tree list

2
推荐指数
1
解决办法
201
查看次数

如何将递归算法转换为尾递归算法?

作为进入合并排序的第一次尝试,我生成了以下代码,这些代码适用于字符串,因为它们比列表更容易处理.

class Program
{
    static int iterations = 0;
    static void Main(string[] args)
    {            
        string test = "zvutsrqponmlihgfedcba";
        test = MergeSort(test);
        // test is sorted after 41 iterations
    }

    static string MergeSort(string input)
    {
        iterations++;
        if (input.Length < 2)
            return input;
        int pivot = 0;
        foreach (char c in input)
            pivot += c;
        pivot /= input.Length;
        string left = "";
        string right = "";
        foreach (char c in input)            
            if (c <= (char)pivot)
                left += c;
            else
                right += c; …
Run Code Online (Sandbox Code Playgroud)

c# mergesort tail-recursion

1
推荐指数
1
解决办法
424
查看次数

递归 - 你什么时候使用它,何时不使用它

递归 - 你何时会使用它,什么时候不使用它?

c# recursion

0
推荐指数
2
解决办法
691
查看次数

无法返回最大元素

我试图使用递归从数组返回最大元素
这里是我的代码

    static void Main(string[] args)
    {
        int[] Array=new int[]{10,233,34};

        int _MaxVal = CalculateMax(Array, 0, 0);
        Console.WriteLine(_MaxVal);
        Console.ReadKey();

    }

    private static int CalculateMax(int[] Array, int Startpos, int maxval)
    {
        if (Startpos != Array.Length)
        {
            if (Array[Startpos] > maxval)
            {
                maxval = Array[Startpos];
            }


            CalculateMax(Array, ++Startpos, maxval);
        }

        return maxval;
    }
Run Code Online (Sandbox Code Playgroud)

我得到MaxVal为10.

这有什么问题?

谢谢大家

c#

0
推荐指数
1
解决办法
90
查看次数

是否可以在不使用仅包含C#代码的yield的情况下实现无限的IEnumerable?

编辑:显然偏离主题...转移到Programmers.StackExchange.com.

这不是一个实际问题,它更像是一个谜.

问题

我很想知道是否有办法实现与以下相同的东西,但不使用yield:

IEnumerable<T> Infinite<T>()
{
    while (true) { yield return default(T); }
}
Run Code Online (Sandbox Code Playgroud)

规则

  1. 您无法使用该yield关键字
  2. 直接使用C#本身 - 没有IL代码,没有构建动态程序集等.
  3. 您只能使用基本的.NET lib(仅限mscorlib.dll,System.Core.dll?不确定还包括哪些内容).但是,如果您找到一些其他.NET程序集(WPF ?!)的解决方案,我也很感兴趣.
  4. 不要实现IEnumerable或IEnumerator.

笔记

我最接近的是:

IEnumerable<int> infinite = null;
infinite = new int[1].SelectMany(x => new int[1].Concat(infinite));
Run Code Online (Sandbox Code Playgroud)

这是"正确的",但在14399次迭代通过可枚举(非常无限)之后会遇到StackOverflowException.

我认为由于CLR 缺乏尾递归优化,可能无法做到这一点.证明会很好:)

c# ienumerable infinite-loop

-2
推荐指数
1
解决办法
557
查看次数