简体   繁体   English

程序的时间复杂度,确定两个字符串是否彼此置换

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

I have written a program to determine if two strings are permutations of one another. 我编写了一个程序来确定两个字符串是否相互排列。 I am trying to do so using a hash table. 我正在尝试使用哈希表。 Here is my code: 这是我的代码:

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;
}

I believe the time complexity of the above code is O(n^2). 我相信以上代码的时间复杂度为O(n ^ 2)。 I couldn't think of an algorithm that didn't involve using nested loops. 我想不出一个不涉及使用嵌套循环的算法。 Is there a faster way to do this using a hash table? 有没有使用哈希表执行此操作的更快方法?

Yep. 是的

#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;DR I wanted to test the solutions (including my own): David's map based answer performs decently well (it is a lot more generic), his array based solution performs very well, my own solution was only slightly faster but also slightly less readable (probably not worth it). TL; DR我想测试解决方案(包括我自己的解决方案):David的基于地图的答案表现不错(更为通用),他的基于数组的解决方案表现非常好,我自己的解决方案仅稍快一些,但也略少一些可读(可能不值得)。

In all honesty, when I saw this, I couldn't believe David's answer with the unordered map could possibly have the lowest time complexity. 老实说,当我看到这一点时,我不敢相信大卫对无序地图的回答可能具有最低的时间复杂度。 (well possibly theoretically, but not in practice) (很可能是理论上的,但实际上不是)

I'm usually writing in C, so I have no idea what kind of optimisations C++ offers with these data structures or how well they perform in real life. 我通常是用C编写的,所以我不知道C ++对这些数据结构提供了什么样的优化,或者它们在现实生活中的表现如何。 So I decided to test it. 因此,我决定进行测试。

So I set up some tests on my i7, to test the performance of the various solutions, with some slight adaptations ( source code here ) 因此,我在i7上进行了一些测试,以对各种解决方案的性能进行一些稍微的改动( 此处为源代码

I ran the programs 100000 times on 1) 2 permutations and 2) 2 different words 我在1)2个排列和2)2个不同的单词上运行程序100000次

The results came in as follows: 结果如下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM