Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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#_.net - Fatal编程技术网

C# 如何计算该函数的时间复杂度,该函数检查字符串是否具有所有唯一字符?

C# 如何计算该函数的时间复杂度,该函数检查字符串是否具有所有唯一字符?,c#,.net,C#,.net,《破解编码面试》一书中讨论了一个函数,该函数确定字符串是否包含所有唯一字符。本书使用位移位的答案在问题链接中(请参见页面顶部的答案),我在这里不再重复 Java的答案有一个O(N)复杂度,我无法理解O(N)的实际含义。实际上,我想知道我刚才写的这个实现的时间复杂度是多少。是O(N)吗?如何理解复杂性 static void Main(string[] args) { string stringToCheck ; bool hasAllUniqueChars

《破解编码面试》一书中讨论了一个函数,该函数确定字符串是否包含所有唯一字符。本书使用位移位的答案在问题链接中(请参见页面顶部的答案),我在这里不再重复

Java的答案有一个O(N)复杂度,我无法理解O(N)的实际含义。实际上,我想知道我刚才写的这个实现的时间复杂度是多少。是O(N)吗?如何理解复杂性

static void Main(string[] args)
    {
        string stringToCheck ;
        bool hasAllUniqueChars = false;
        stringToCheck = "Test";

        hasAllUniqueChars = CheckForUniqueChars(stringToCheck);

        Console.WriteLine("String is Unique {0}", hasAllUniqueChars);
        Console.Read();
    }

    private static bool CheckForUniqueChars(string stringToCheck)
    {
        for (int i = 0; i < stringToCheck.Length - 1; i++)
        {
            for (int j = i; j < stringToCheck.Length - 1; j++)
            {
                if (Char.ToUpper(stringToCheck.ElementAt(i)) == 
                    Char.ToUpper(stringToCheck.ElementAt(j+1)))
                {
                    return false;
                }
            }
        }
        return true;           

    }
static void Main(字符串[]args)
{
字符串检查;
bool hasaluniquechars=假;
stringToCheck=“测试”;
HASALUNIQUECHARS=检查唯一字符(stringToCheck);
WriteLine(“字符串是唯一的{0}”,hasAllUniqueChars);
Console.Read();
}
专用静态bool CheckForUniqueChars(字符串stringToCheck)
{
对于(int i=0;i
对于Test、Test、Hello,返回false;对于超人、蜘蛛侠和海绵,返回true,工作正常


谢谢你

编辑:根据其他用户的建议,它是O(n^3),或者与三阶多项式成比例增长。这是因为ElementAt()在字符串中循环

这种复杂性的关键在于迭代。这一结构:

for (each item in this thing)
{
   for(each item in this thing)
   {
      if (iterate through this thing to check a condition)
   }
}
有一个与三阶多项式成比例的增长阶。这并不像其他类似的例程那样糟糕,因为通过内部循环的内部迭代随着您的增量而变小,但您仍然在对字符串的每个元素进行迭代,并对这些迭代中的每个元素在字符串上进行迭代。如果你的算法是O(n^3),你就可以重构它

如果您感兴趣的话,无ElementAt()调用,它与它的迭代方式非常相似。

您的算法是O(n^2),或者更准确地说,可以是O(n^2)。可能是,因为现在是O(n^3)

ElementAt()
方法在
IEnumerable
上是O(n),所以因为它在两个嵌套循环中执行,所以整个方法是O(n^3)

通过将
string
s转换为
char[]
before循环,并使用数组索引器而不是
ElementAt
扩展方法,可以实现O(n^2):

private static bool CheckForUniqueChars(string stringToCheck)
{
    var chars = stringToCheck.ToCharArray();
    for (int i = 0; i < stringToCheck.Length - 1; i++)
    {
        for (int j = i; j < stringToCheck.Length - 1; j++)
        {
            if (Char.ToUpper(chars[i]) == Char.ToUpper(chars[j+1]))
            {
                return false;
            }
        }
    }
    return true;           
}
专用静态bool CheckForUniqueChars(字符串stringToCheck)
{
var chars=stringToCheck.tocharray();
对于(int i=0;i
Bonus:另一种O(n)方法(因为
HashSet
查找是O(1)):

专用静态bool CheckForUniqueChars(字符串stringToCheck)
{
var characters=新的HashSet();
foreach(stringToCheck中的变量字符)
如果(!个字符。添加(个字符))
返回false;
返回true;
}
调用符号O(N)。它提供的是算法所需的(基本)操作量相对于其输入大小的上限。输入的大小通常表示为N

如果原语操作的数量与输入大小无关,则算法的复杂度为O(1),即恒定时间

如果基元运算量随着N的增长而线性增长(即:当N翻倍时,运算量也会翻倍),则时间复杂度是线性的,即O(N)

在您的示例中,对于普通读者来说,上限似乎是O(N^2):

for (each item in input)
  for (each item in input)
    // do something
当N增加一倍时,运算量将增加四倍

然而,由于ElementAt的时间复杂度是线性的且不是常数,因此复杂度实际上是O(N^3)。

不是O(?)

但这接近于O(N),因为对于这一点,哈希集应该接近于O(1)。
注意HashSet。计数是O(1)

HashSet chars=new HashSet();
字符串password=“password”;
Int32计数=0;
炭杯;
foreach(密码中的字符c)
{
计数++;
cUpper=char.ToUpper(c);
如果(!chars.Add(char.ToUpper(c)))
{
System.Diagnostics.Debug.WriteLine(“非uniue”);
打破
}
}
if(count==chars.count)System.Diagnostics.Debug.WriteLine(“uniue”);
+我看不出Marcin有这个答案,但没有这个答案
ToUpper比ToLower好用,但我忘了为什么

String具有不区分大小写的比较,但char不区分大小写(因为
String.ElementAt
在其中生成另一个循环)。在维基百科上阅读更多关于大O符号的内容:这个问题似乎离题了,因为它是关于大O的notation@MarcinJuraszek这不是另一个循环。这只是使用两个循环中的索引进行比较。@是的,但不是简单的数组查找
ElementAt()
方法在
IEnumerable
上是O(n),所以整个方法是O(n^3),不是吗?(
ElementAt
IList
上是O(1),但
string
不实现
IList
)。检查此项:
ElementAt()
在内部生成另一个循环。是的,确实如此。正在修改,因为这现在是一个三阶多项式。@MarcinJuraszek该实现可以很容易地更改为O(N^2)。@Asad Yes,只需两次
tocharray()
调用。然而,当前的实现是O(n^3)。@MarcinJuraszek我知道。能够
for (each item in input)
  for (each item in input)
    // do something
HashSet<char> chars = new HashSet<char>();
string password = "password";
Int32 count = 0;
char cUpper;
foreach (char c in password)
{
    count++;
    cUpper = char.ToUpper(c);
    if (!chars.Add(char.ToUpper(c))) 
    {
        System.Diagnostics.Debug.WriteLine("not uniue");
        break;
    }
}
if(count == chars.Count) System.Diagnostics.Debug.WriteLine("uniue");