C++ 为什么每个解的渐近时间和实际时间都有异常?

C++ 为什么每个解的渐近时间和实际时间都有异常?,c++,c++11,time,stl,time-complexity,C++,C++11,Time,Stl,Time Complexity,我正在解决这个问题:- 你得到了代表宝石类型的字符串J和代表你拥有的宝石的字符串S。S中的每个字符都是您拥有的石头类型。你想知道你有多少宝石也是珠宝 保证J中的字母是不同的,J和S中的所有字符都是字母。字母区分大小写,因此“a”被视为与“a”不同的石头类型 例1: 输入:J=“aA”,S=“aaabbb” 产出:3 例2: 输入:J=“z”,S=“ZZ” 输出:0 我的解决方案1的逻辑。 散列宝石(无序的_图),这样我们就有了每种类型的频率,并且只需在给定的宝石中找到不同的宝石一次。 fin

我正在解决这个问题:- 你得到了代表宝石类型的字符串J和代表你拥有的宝石的字符串S。S中的每个字符都是您拥有的石头类型。你想知道你有多少宝石也是珠宝

保证J中的字母是不同的,J和S中的所有字符都是字母。字母区分大小写,因此“a”被视为与“a”不同的石头类型

例1:

输入:J=“aA”,S=“aaabbb” 产出:3 例2:

输入:J=“z”,S=“ZZ” 输出:0

我的解决方案1的逻辑。
散列宝石(无序的_图),这样我们就有了每种类型的频率,并且只需在给定的宝石中找到不同的宝石一次。 find函数对每个石头n取o(n),因此时间复杂度为o(n^2)。

int NUMJEWELSINSTONE(字符串j、字符串s){
无序的地图石;
用于(字符s1:s)
++石头[s1];
auto it=stones.begin();
整数计数=0;
for(it=stones.begin();it!=stones.end();+it)
{
char s1=it->first;
如果(j.find(s1)!=string::npos)
计数+=它->秒;
}
返回计数;
所以我认为o(n^2)太多了,决定进一步优化它。 因此,我也将珠宝放入一个无序的集合中,这样一来,所有重复的珠宝都会被移除,并且需要o(1)个时间才能在其中找到一颗宝石。 因此,对于每一块石头,它需要o(1)个时间,因此时间复杂度变成o(n)。

int NUMJEWELSINSTONE(字符串j、字符串s){
无序的地图石;
用于(字符s1:s)
++石头[s1];
无序设置(j.begin(),j.end());
auto it=stones.begin();
整数计数=0;
for(it=stones.begin();it!=stones.end();+it)
{
char s1=it->first;
if(uset.find(s1)!=uset.end())
计数+=它->秒;
}
返回计数;
问题出现在这里-当我使用time.h的时钟函数来测量运行时间时
对于解决方案1,我得到了0.000126个时间单位
对于解决方案2,我得到了0.000145个时间单位
,当第一个是o(n^2),第二个是o(n)时,这是没有意义的。
顺便说一句,这是我获取时间的代码-

int main()
{
    clock_t tStart = clock();
    Solution ob;
    string j = "aA", s = "aAAbbbb";
    cout << ob.numJewelsInStones(j, s) << endl;
    cout << (double)(clock() - tStart)/CLOCKS_PER_SEC;
    cout << endl;
    return 0;
}
intmain()
{
时钟启动=时钟();
溶液ob;
字符串j=“aA”,s=“aaabbb”;

不能用足够大的n测试你的算法

对于N的小值,<强>缓存性能占主导地位。C++中的代码> unOrdEdEdSt/<代码>被实现为哈希表,因此查找涉及遍历指针(这里,我假设您知道如何实现哈希映射)。。遍历指针意味着从内存的不同部分读取。这会影响缓存性能,因为哈希映射要检查的下一个对象很可能不在缓存中,必须从更高的内存级别获取。
另一方面,数组显示。这可以有效地利用缓存,因此在小示例中使用数组可以获得更好的性能


算法的时间复杂度用于查看算法随大小扩展的程度。
O(n^2)
算法在较小输入上的性能可能优于
O(n)
算法(如本例所示),但在足够大的输入量下,时间复杂度较低的算法一定会表现得更好。

您是否在启用优化的情况下编译?大小和时间似乎太小,无法得出一个结论conclusion@cigien不,我不是。然后比较结果基本上是没有意义的。使用优化和相当大的输入进行编译。哦,我明白了。所以,基本上是这样由于每个元素都是由散列函数散列的,所以搜索一个元素需要O(1)时间,但实际上从内存中检索它的时间比数组慢(数组具有引用的局部性)。是的。此外,如果您想要更好的缓存性能,您可能可以在中实现哈希集。这将使您两全其美。性能将取决于输入的大小和缓存的大小(以及相对访问速度)
int numJewelsInStones(string j, string s) {
        
        unordered_map<char, int>stones;
        for(char s1:s)
            ++stones[s1];
        unordered_set<char>uset(j.begin(), j.end()); 
        auto it = stones.begin(); 
        int count = 0;
        for(it = stones.begin(); it != stones.end(); ++it)
        {
            char s1 = it->first;
            
            if(uset.find(s1) != uset.end())
                count += it->second;
                
        }
        return count;
int main()
{
    clock_t tStart = clock();
    Solution ob;
    string j = "aA", s = "aAAbbbb";
    cout << ob.numJewelsInStones(j, s) << endl;
    cout << (double)(clock() - tStart)/CLOCKS_PER_SEC;
    cout << endl;
    return 0;
}