幂集生成函数的时间复杂度

发布于 2024-10-10 22:41:58 字数 1361 浏览 8 评论 0原文

我试图计算出我编写的函数的时间复杂度(它生成一个 幂集 对于给定的字符串):

public static HashSet<string> GeneratePowerSet(string input)
{
    HashSet<string> powerSet = new HashSet<string>();

    if (string.IsNullOrEmpty(input))
        return powerSet;

    int powSetSize = (int)Math.Pow(2.0, (double)input.Length);

    // Start at 1 to skip the empty string case
    for (int i = 1; i < powSetSize; i++)
    {
        string str = Convert.ToString(i, 2);
        string pset = str;
        for (int k = str.Length; k < input.Length; k++)
        {
            pset = "0" + pset;
        }

        string set = string.Empty;
        for (int j = 0; j < pset.Length; j++)
        {
            if (pset[j] == '1')
            {
                set = string.Concat(set, input[j].ToString());
            }
        }
        powerSet.Add(set);
    }
    return powerSet;
}

所以我的尝试是这样的:

  • 让输入字符串的大小为n
  • 在外层for循环中
  • ,必须迭代2^n次(因为设置的大小为2^n)。在内部 for 循环中,我们必须迭代 2*n 次(最坏情况下)。

1.所以 Big-O 将是 O((2^n)*n) (因为我们删除了常数 2)...这是正确的吗?

并且 n*(2^n) 比 n^2 更糟糕。

如果 n = 4 则
(4*(2^4)) = 64
(4^2) = 16

如果 n = 100 则
(10*(2^10)) = 10240
(10^2) = 100

2。是否有更快的方法来生成幂集,或者这是否是最佳方法?

I'm trying to figure out the time complexity of a function that I wrote (it generates a power set for a given string):

public static HashSet<string> GeneratePowerSet(string input)
{
    HashSet<string> powerSet = new HashSet<string>();

    if (string.IsNullOrEmpty(input))
        return powerSet;

    int powSetSize = (int)Math.Pow(2.0, (double)input.Length);

    // Start at 1 to skip the empty string case
    for (int i = 1; i < powSetSize; i++)
    {
        string str = Convert.ToString(i, 2);
        string pset = str;
        for (int k = str.Length; k < input.Length; k++)
        {
            pset = "0" + pset;
        }

        string set = string.Empty;
        for (int j = 0; j < pset.Length; j++)
        {
            if (pset[j] == '1')
            {
                set = string.Concat(set, input[j].ToString());
            }
        }
        powerSet.Add(set);
    }
    return powerSet;
}

So my attempt is this:

  • let the size of the input string be n
  • in the outer for loop, must iterate 2^n times (because the set size is 2^n).
  • in the inner for loop, we must iterate 2*n times (at worst).

1. So Big-O would be O((2^n)*n) (since we drop the constant 2)... is that correct?

And n*(2^n) is worse than n^2.

if n = 4 then
(4*(2^4)) = 64
(4^2) = 16

if n = 100 then
(10*(2^10)) = 10240
(10^2) = 100

2. Is there a faster way to generate a power set, or is this about optimal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

新人笑 2024-10-17 22:41:58

评论:

上面的函数是面试问题的一部分,程序应该接受一个字符串,然后打印出字典中的单词,这些单词的字母是输入字符串的字谜子集(例如输入:tabrcoz 输出:boat,汽车、猫等)。面试官声称 an*m 实现很简单(其中 n 是字符串的长度,m 是字典中的单词数),但我认为您无法找到给定字符串的有效子字符串。看来面试官的说法有误。

1995 年我在微软面试时也遇到了同样的面试问题。基本上问题是实现一个简单的拼字游戏播放算法。

你用这种产生动力组的想法完全错了。不错的想法,显然太贵了。放弃它并寻找正确的答案。

这里有一个提示:对字典进行分析,构建一个新的数据结构,更适合有效地解决您实际需要解决的问题。通过优化的字典,您应该能够实现 O(nm)。通过更巧妙构建的数据结构,您可能可以做得更好。

A comment:

the above function is part of an interview question where the program is supposed to take in a string, then print out the words in the dictionary whose letters are an anagram subset of the input string (e.g. Input: tabrcoz Output: boat, car, cat, etc.). The interviewer claims that a n*m implementation is trivial (where n is the length of the string and m is the number of words in the dictionary), but I don't think you can find valid sub-strings of a given string. It seems that the interviewer is incorrect.

I was given the same interview question when I interviewed at Microsoft back in 1995. Basically the problem is to implement a simple Scrabble playing algorithm.

You are barking up completely the wrong tree with this idea of generating the power set. Nice thought, clearly way too expensive. Abandon it and find the right answer.

Here's a hint: run an analysis pass over the dictionary that builds a new data structure more amenable to efficiently solving the problem you actually have to solve. With an optimized dictionary you should be able to achieve O(nm). With a more cleverly built data structure you can probably do even better than that.

七颜 2024-10-17 22:41:58

2.是否有更快的方法来生成幂集,或者这是否是最佳方法?

您的算法是合理的,但您的字符串处理需要改进。

string str = Convert.ToString(i, 2);
string pset = str;
for (int k = str.Length; k < input.Length; k++)
{
    pset = "0" + pset;
}

您在这里所做的只是设置一个位字段,但使用字符串。跳过这个,直接使用变量i

for (int j = 0; j < input.Length; j++)
{
    if (i & (1 << j))
    {

构建字符串时,请使用 StringBuilder,而不是创建多个字符串。

// At the beginning of the method
StringBuilder set = new StringBuilder(input.Length);
...
// Inside the loop
set.Clear();
...
set.Append(input[j]);
...
powerSet.Add(set.ToString());

这会改变你的算法的复杂性吗?不会。但它会显着减少您创建的额外 String 对象的数量,这将为您提供良好的加速。

2. Is there a faster way to generate a power set, or is this about optimal?

Your algorithm is reasonable, but your string handling could use improvement.

string str = Convert.ToString(i, 2);
string pset = str;
for (int k = str.Length; k < input.Length; k++)
{
    pset = "0" + pset;
}

All you're doing here is setting up a bitfield, but using a string. Just skip this, and use variable i directly.

for (int j = 0; j < input.Length; j++)
{
    if (i & (1 << j))
    {

When you build the string, use a StringBuilder, not creating multiple strings.

// At the beginning of the method
StringBuilder set = new StringBuilder(input.Length);
...
// Inside the loop
set.Clear();
...
set.Append(input[j]);
...
powerSet.Add(set.ToString());

Will any of this change the complexity of your algorithm? No. But it will significantly reduce the number of extra String objects you create, which will provide you a good speedup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文