查找两个字符串共有的最大字符数

时间:2014-02-13 08:57:26

标签: c++ string algorithm stl comparison

查找两个字符串共有的最大字符数。字符区分大小写,即小写和大写字符被视为不同。

这是我的代码:

#include <iostream>
#include <cstring> 
using namespace std;

int main() {
    std::string a, b;
    int number_cases = 0, count = 0;
    cin >> number_cases;
    while (number_cases != 0) {
        cin >> a;
        cin >> b;
        for (int i = 0; i < a.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                if (a[i] == b[j]) {
                    count++;
                    b[j] = '#';
                    break;
                }
            }
        }
        cout << count << endl;
        count = 0;
        --number_cases;
    }
}

但运行需要1秒以上,我需要在1秒或1秒内完成。任何优化提示?

4 个答案:

答案 0 :(得分:2)

只需对它们进行排序并使用set_intersection

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

int main()
{
    std::string s1 = "Hello";
    std::string s2 = "World";

    std::sort(begin(s1), end(s1));
    std::sort(begin(s2), end(s2));

    std::string s3;
    std::set_intersection(begin(s1), end(s1), begin(s2), end(s2), std::back_inserter(s3));
    std::cout << s3.size() << ":" << s3;
}

Live Example

注意:如果您对唯一重叠字符感兴趣,可以在std::unique上运行s3

答案 1 :(得分:0)

假设只有256个字符。我们可以扫描每个字符串一次,并将每个字符的计数保留在两个数组中int[]arrayA用于字符串A,将int [] arrayB用于字符串B.

最后,遍历{0}中的int[] arrayA , arrayB,添加到结果:

result +=Min(arrayA[i],arrayB[i]);

时间复杂度为O(n + m + 256)= O(n),n为n,m为字符串A和B的长度

答案 2 :(得分:0)

我不确定你的意思是“有共同点”,但对于 我想到的第一个定义是最简单的解决方案 可能只使用两个bool数组:

bool inA[256] = {};
for ( auto current = a.begin(), end = a.end(); current != end; ++ current ) {
    inA[static_cast<unsigned char>(*current)] = true;
}
bool inB[256] = {};
for ( auto current = b.begin(), end = b.end(); current != end; ++ current ) {
    inB[static_cast<unsigned char>(*current)] = true;
}
int count = 0;
for (int i = 0; i != 256; ++ i ) {
    if ( inA[i] && inB[i] ) {
        ++ count;
    }
}

但是,当然,这与完全不同的东西有所不同 你的代码呢。如果你正在寻找最长的共同点 子序列或所有子序列,你需要一个不同的 算法

答案 3 :(得分:0)

以下可能会有所帮助:

std::size_t count_letter_in_common_with_dup(const std::string& s1, const std::string& s2)
{
    std::size_t present1[256] = {};
    std::size_t present2[256] = {};

    for (unsigned char c : s1) {
        ++present1[c];
    }
    for (unsigned char c : s2) {
        ++present2[c];
    }
    std::size_t res = 0;
    for (int i = 0; i != 256; ++i) {
        res += std::min(present1[i], present2[i]);
    }
    return res;
}