Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
算法比较C#_C#_Performance_Algorithm - Fatal编程技术网

算法比较C#

算法比较C#,c#,performance,algorithm,C#,Performance,Algorithm,我目前正在看一些典型的面试问题,以便让我有一个正确的心态。 我试图提出自己的问题解决方案,而不是试图记住给定的解决方案 问题是,我不确定我的解决方案是否最优,或者在设计中是否存在我没有看到的重大缺陷 下面是我为基本的“这个字符串唯一吗”问题提出的解决方案之一,比如检查字符串中的所有字符是否唯一 public static bool IsUnique(string str) { bool isUnique = true; for (int i = 0; i

我目前正在看一些典型的面试问题,以便让我有一个正确的心态。 我试图提出自己的问题解决方案,而不是试图记住给定的解决方案

问题是,我不确定我的解决方案是否最优,或者在设计中是否存在我没有看到的重大缺陷

下面是我为基本的“这个字符串唯一吗”问题提出的解决方案之一,比如检查字符串中的所有字符是否唯一

public static bool IsUnique(string str)
    {
        bool isUnique = true;

        for (int i = 0; i < str.Length; i++)
        {
            if (str.LastIndexOf(str.ElementAt(i)) != i)
            {
                isUnique = false;
                break;
            }
        }

        return isUnique;
    }
公共静态bool是唯一的(字符串str)
{
bool isUnique=true;
对于(int i=0;i

有人对这段代码是否是最优的,是否具有可接受的时间和空间复杂度提出了建议吗?

为了回答这个问题,我将引用Big-O符号来表示算法的复杂度。提高效率的诀窍是实现解决问题的最小大O度量,然后尝试复制该效率

通过逻辑地考虑算法,您可以得出一些效率事实:要检查所有字符是否唯一,您需要计算所有字符。所以这是一个O(n)遍历字符串的保证,我怀疑你会很容易得到比这更有效的。现在,你能在O(n)或O(2n)时间内自己解决它吗?如果是这样的话,那就相当不错了,因为您的算法处于线性时间段,并且将以线性进行缩放(对于较大的字符串输入,稳定地变慢)

您当前的算法在字符串上循环,然后针对每个字符,再次在字符串上迭代以进行比较并找到相等的字符。这使得该算法成为一个n次遍历,其中每次访问本身执行一个n次遍历,因此是一个O(n^2)算法。这就是所谓的多项式时间算法,它不是很好,因为它不是线性伸缩的;它以多项式方式缩放。这意味着您的算法在输入较大时会变得慢得多,这是一件坏事

一个快速的改变是,在字符串+1中的当前索引处开始比较一个等效字符,使其稍微更有效。。。您知道所有以前选中的字符都是唯一的,所以您只关心将来的字符。这将成为一个n遍历,其中每次访问都从当前点进行子字符串遍历(遍历字符串时所做的工作更少),但这也是一个O(n^2)算法,因为它在外循环时间的平方内运行。与以前一样,这也是一种多项式时间算法,但效率稍高。然而,如果投入更大,它的规模仍然会很糟糕

考虑避免重复迭代的替代方法。这些通常是以牺牲内存为代价的,但它们是实用的。我知道我会如何解决这个问题,但告诉你我的答案无助于你学习

编辑:根据您的要求,我将分享我的答案

我会通过拥有一个哈希集来实现这一点,我会将每个访问的字符加载到哈希集中。HashSet查找和添加大约是一个O(1)操作。Add方法的优点在于,如果它添加了值,则返回true;如果值已经存在,则返回false(这是决定算法结果的条件)。因此,我的建议是:

var hashSet = new HashSet<char>();
foreach (char c in myString)
{
    if (!hashSet.Add(c))
    {
        return false;
    }
}

return true;
var hashSet=new hashSet();
foreach(myString中的字符c)
{
如果(!hashSet.Add(c))
{
返回false;
}
}
返回true;
优点:O(n)线性算法

缺点:用于哈希集的额外内存

EDIT2:每个人都喜欢廉价的LINQ把戏,所以这里有另一种方法

var hashSet = new HashSet<char>();
return myString.Any(c => !hashSet.Add(c));
var hashSet=new hashSet();
返回myString.Any(c=>!hashSet.Add(c));

与使用线性查找时间O(n)查找字符串中的字符相比,使用哈希集的查找时间O(1)恒定,因此效率更高:

公共静态bool AreCharsUnique(字符串str)
{
var charset=new HashSet();
foreach(str中的字符c){
if(字符集包含(c)){
返回false;
}否则{
添加(c);
}
}
返回true;
}

可能是因为这个问题似乎离题了,因为它是关于而不是代码修复的。请使用
str[i]
。考虑使用HasSt集。取决于你要做什么-微优化与可读性。可读性,您可能不需要使用
s.Length==s.Distinct().Count()
,但这可能不是微优化的。即使这只使用1作为循环,它仍然是一个O(n^2)算法。这是因为
elementAt
LastIndexOf
是O(n)。试着把这些字符放进某种字典里,检查是否有冲突不要给他们答案:他们想知道如何判断他们何时得到了正确答案,而不是正确答案是什么。谢谢你的答案大卫。我也在沿着这些思路思考。我发现很难找到一个复杂度很高的解决方案,另外还要注意的是,算法中不能使用其他数据结构。是的,在当前索引之后启动索引1,以避免再次遍历整个字符串,这更有意义。O(n^2)是多项式。O(2^n)是指数的。而且,阶乘是指数的,所以它比O(n^2)差得多,不是更好。啊,非常好,因为哈希集中不允许有重复项。。快乐的日子。
public static bool AreCharsUnique(string str)
{
    var charset = new HashSet<char>();
    foreach (char c in str) {
        if (charset.Contains(c)) {
            return false;
        } else {
            charset.Add(c);
        }
    }
    return true;
}