程序的时间复杂性确定两个字符串是否彼此排列

Time complexity of program determining if two strings are permutations of each other

本文关键字:字符串 两个 是否 排列 时间复杂性 程序      更新时间:2023-10-16

我已经编写了一个程序来确定两个字符串是否彼此排列。我正在尝试使用哈希表。这是我的代码:

bool permutation(string word1, string word2) {
    unordered_map<char, int> myMap1;
    unordered_map<char, int> myMap2;
    int count1 = 0;
    int count2 = 0;
    if (word1.length() == word2.length()) {
        for (int i = 0; i < word1.length(); i++) {
            count1++;
            count2++;
            for (int j = 0; j < word1.length(); j++) {
                if (word1[i] == word1[j] && myMap1.find(word1[i]) == myMap1.end()) {
                    count1++;
                }
                if (word2[i] == word2[j] && myMap2.find(word1[i]) == myMap2.end()) {
                    count2++;
                }
            }
            myMap1.insert({word1[i], count1});
            myMap2.insert({word2[i], count2});
        }
    }
    else {
        return false;
    }
    return (myMap1.size() == myMap2.size());
}
int main() {
    string word1;
    string word2;
    getline(cin, word1);
    getline(cin, word2);
    bool result = permutation(word1, word2);
    return 0;
}

我相信上述代码的时间复杂性是o(n^2)。我想不出没有嵌套循环的算法。是否有更快的方法可以使用哈希表?

是的。

#include <climits>
#include <iostream>
#include <unordered_map>
namespace {
bool permutation(const std::string& word1, const std::string& word2) {
  std::unordered_map<char, std::size_t> freqdiff;
  // alternatively, std::size_t freqdiff[UCHAR_MAX + 1] = {};
  for (char c : word1) {
    // alternatively, freqdiff[(unsigned char)c]++;
    freqdiff[c]++;
  }
  for (char c : word2) {
    // alternatively, freqdiff[(unsigned char)c]--;
    freqdiff[c]--;
  }
  for (auto i : freqdiff) {
    // alternatively, i != 0
    if (i.second != 0) {
      return false;
    }
  }
  return true;
}
bool permutation_with_array(const std::string& word1,
                            const std::string& word2) {
  std::size_t freqdiff[UCHAR_MAX + 1] = {};
  for (char c : word1) {
    freqdiff[static_cast<unsigned char>(c)]++;
  }
  for (char c : word2) {
    freqdiff[static_cast<unsigned char>(c)]--;
  }
  for (std::size_t i : freqdiff) {
    if (i != 0) {
      return false;
    }
  }
  return true;
}
}
int main() {
  std::string word1;
  std::string word2;
  std::getline(std::cin, word1);
  std::getline(std::cin, word2);
  std::cout << permutation(word1, word2) << 'n';
  std::cout << permutation_with_array(word1, word2) << 'n';
}

tl;我想测试解决方案(包括我自己的):大卫的基于地图的答案表现良好(更通用),他的基于数组的解决方案的性能很好,我自己的解决方案速度略高,但读取性也稍微降低(可能不值得)。

老实说,当我看到这个时,我简直不敢相信大卫对无序地图的回答可能会具有最低的时间复杂性。(从理论上讲,但实际上不是在实践中)

我通常在C中写作,所以我不知道C 在这些数据结构中提供了哪种优化,或者它们在现实生活中的表现如何。所以我决定对其进行测试。

因此,我在i7上设置了一些测试,以测试各种解决方案的性能,并进行一些略有改编(源代码在此处)

我在1)2排列和2个不同单词

上运行了100000次程序

结果如下:

PERM original
======================
PERMUTATIONS OF SAME WORD
real 104.73
user 104.61
sys 0.06
DIFFERENT WORDS
real 104.24
user 104.16
sys 0.02
PERM David map
======================
PERMUTATIONS OF SAME WORD
real 2.46
user 2.44
sys 0.00
DIFFERENT WORDS
real 2.45
user 2.42
sys 0.02
PERM David array
======================
PERMUTATIONS OF SAME WORD
real 0.15
user 0.14
sys 0.00
DIFFERENT WORDS
real 0.14
user 0.14
sys 0.00
PERM Me
======================
PERMUTATIONS OF SAME WORD
real 0.13
user 0.13
sys 0.00
DIFFERENT WORDS
real 0.14
user 0.12
sys 0.01