Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 最大限度地提高效率_C++_Algorithm - Fatal编程技术网

C++ 最大限度地提高效率

C++ 最大限度地提高效率,c++,algorithm,C++,Algorithm,给定一个由n个非负整数组成的数组:A1,A2,…,an。如何找到一对整数Au,Av(1≤ u=0;i--){ if(按位[i].size()>1){ 返回最大值和最小值(按位[i]); } } //如果你到了这里,最大值是0。 返回0; } 此算法仍然具有最坏情况下的运行时O(N*N),但平均而言,它的性能应该要好得多。在搜索较小的向量时,您还可以通过重复分区步骤来进一步提高性能(请记住忽略分区步骤中的最高有效位,这样做会将性能提高到O(N)的最坏情况) 保证输入数据中没有重复项将进一步提高性

给定一个由n个非负整数组成的数组:A1,A2,…,an。如何找到一对整数Au,Av(1≤ u 示例:设N=4,数组为[2 4 8 10]。这里的答案是8

解释

2 and 4 = 0
2 and 8 = 0
2 and 10 = 2
4 and 8 = 0
4 and 10 = 0
8 and 10 = 8
如果N可以达到10^5,该怎么做。 我有O(N^2)解,但它不是有效的

代码:

for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
        if(arr[i] & arr[j] > ans)
        {
            ans=arr[i] & arr[j];
        }
    }
}

for(int i=0;i加速的一种方法是利用这样一个事实:如果在任何两个数字中设置了任何高位,那么这两个数字的AND将始终大于使用低位的任何组合

因此,如果您按设置的位对数字进行排序,则可能会大幅减少操作数

为了有效地查找最高有效位,GCC有一个内置的内在函数:
\uuuuuuuuuuiltin\uCLZ(unsigned int x)
,它返回最高有效位的索引(其他编译器有类似的内在函数,至少在x86上转换为一条指令)

const unsigned int BITS=sizeof(unsigned int)*8;//假设为8位字节。
//你的实现结束了。
无符号整数max_和平凡(const std::vector&input);
//对集合进行分区。
无符号整数max_和(常数std::向量和输入){
//对于较小的输入,只需使用平凡算法。
如果(input.size()<100){
返回最大值和最小值(输入);
}        
std::按位向量[BITS];
用于(自动元素:输入){
无符号整数掩码=elem;
while(mask){//忽略0的元素。
无符号整数most_sig=uu内置clz(掩码);
按位[多数信号]。推回(元素);
掩码^=(0x1>most_sig;
}
}
//现在,如果by_位中的任何向量具有更多
//多个元素,索引最高的元素
//将包括最大值和最大值。
对于(无符号整数i=BITS-1;i>=0;i--){
if(按位[i].size()>1){
返回最大值和最小值(按位[i]);
}
}
//如果你到了这里,最大值是0。
返回0;
}
此算法仍然具有最坏情况下的运行时O(N*N),但平均而言,它的性能应该要好得多。在搜索较小的向量时,您还可以通过重复分区步骤来进一步提高性能(请记住忽略分区步骤中的最高有效位,这样做会将性能提高到O(N)的最坏情况)

保证输入数据中没有重复项将进一步提高性能

  • 按降序排列数组
  • 以前两个数字为例,如果它们都在2的两个连续幂之间(比如2^k和2^(k+1)),则可以删除所有小于2^k的元素
  • 从其余元素中减去2^k
  • 重复步骤2和3,直到数组中的元素数为2
  • 注意:如果您发现只有最大的元素在2^k和2^(k+1)之间,而第二大元素小于2^k,则您不会删除任何元素,只需从最大元素中减去2^k即可


    此外,确定元素在序列{1,2,4,8,16,…}中的位置可以在O(log(log(MAX))时间内完成,其中MAX是数组中的最大数。

    我没有测试这个,我也不打算讨论.O(N)内存和O(N)复杂性

    #include <vector>
    #include <utility>
    #include <algorithm>
    
    using namespace std;
    
    
    /*
     * The idea is as follows:
     * 1.) Create a mathematical set A that holds integers.
     * 2.) Initialize importantBit = highest bit in any integer in v
     * 3.) Put into A all integers that have importantBit set to 1.
     * 4.) If |A| = 2, that is our answer. If |A| < 2, --importantBit and try again. If |A| > 2, basically
     *     redo the problem but only on the integers in set A.
     *
     * Keep "set A" at the beginning of v.
     */
    pair<unsigned, unsigned> find_and_sum_pair(vector<unsigned> v)
    {
        // Find highest bit in v.
        int importantBit = 0;
        for(auto num : v)
            importantBit = max(importantBit, highest_bit_index(num));
    
        // Move all elements with imortantBit to front of vector until doing so gives us at least 2 in the set.
        int setEnd;
        while((setEnd = partial_sort_for_bit(v, importantBit, v.size())) < 2 && importantBit > 0)
            --importantBit;
    
        // If the set is never sufficient, no answer exists
        if(importantBit == 0)
            return pair<unsigned, unsigned>();
    
        // Repeat the problem only on the subset defined by A until |A| = 2 and impBit > 0 or impBit  = 0
        while(importantBit > 1)
        {
            unsigned secondSetEnd = partial_sort_for_bit(v, --importantBit, setEnd);
            if(secondSetEnd >= 2)
                setEnd = secondSetEnd;
        }
    
        return pair<unsigned, unsigned>(v[0], v[1]);
    }
    
    // Returns end index (1 past last) of set A
    int partial_sort_for_bit(vector<unsigned> &v, unsigned importantBit, unsigned vSize)
    {
        unsigned setEnd = 0;
    
        unsigned mask = 1<<(importantBit-1);
        for(decltype(v.size()) index = 0; index < vSize; ++index)
            if(v[index]&mask > 0)
                swap(v[index], v[setEnd++]);
    
        return setEnd;
    }
    
    
    unsigned highest_bit_index(unsigned i)
    {
        unsigned ret = i != 0;
        while(i >>= 1)
            ++ret;
        return ret;
    }
    
    #包括
    #包括
    #包括
    使用名称空间std;
    /*
    *其思路如下:
    *1.)创建一个包含整数的数学集合a。
    *2.)Initialize importantBit=v中任何整数的最高位
    *3.)将importantBit设置为1的所有整数放入A。
    *4)如果A=2,这就是我们的答案。如果| A |<2,--很重要,请重试。如果| A |>2,基本上
    *重做这个问题,但只对集合A中的整数进行重做。
    *
    *在v开头保持“set A”。
    */
    对查找对和对求和对(向量v)
    {
    //查找v中的最高位。
    int importantBit=0;
    用于(自动编号:v)
    importantBit=max(importantBit,最高位索引(num));
    //使用imortantBit将所有元素移动到向量的前面,直到这样做使集合中至少有2个元素。
    int setEnd;
    while((setEnd=partial_sort_for_bit(v,importantBit,v.size())<2&&importantBit>0)
    --重要信息;
    //如果集合永远不够,则不存在答案
    if(importantBit==0)
    返回对();
    //仅在由A定义的子集上重复该问题,直到| A |=2且impBit>0或impBit=0
    while(importantBit>1)
    {
    无符号secondSetEnd=位(v,-importantBit,setEnd)的部分排序;
    如果(secondSetEnd>=2)
    setEnd=第二个setEnd;
    }
    返回对(v[0],v[1]);
    }
    //返回集合A的结束索引(最后1个)
    int partial_sort_for_位(向量&v、无符号重要位、无符号vSize)
    {
    无符号setEnd=0;
    无符号掩码=1>=1)
    ++ret;
    返回ret;
    }
    
    这里有一个O(N*log MAX_A)解决方案:

    1) 让我们贪婪地构造答案,从最高位迭代到最低位

    2) 要做到这一点,你可以得到一组目前适合的数字。最初,它由数组中的所有数字组成。我们还假设初始ANS=0

    3) 现在让我们从最高到最低遍历所有位。假设当前位是B

    4) 如果S中第B位值为1的元素数量大于1,则在不更改ANS中较高位的值的情况下,该位置可能有1个元素,因此我们应向ANS中添加2^B,并从S中删除该位值为0的所有元素(它们不再适合)


    5) 否则,在此位置不可能获得1,因此我们不会更改S和ANS并继续下一位。

    您的任务是…-不,这是您的任务。可能是任何正在进行的编程竞赛的问题!听起来很像是在进行编码测试。为什么不简单地对数组排序,然后选择最后一个和第二个元素呢
    #include <vector>
    #include <utility>
    #include <algorithm>
    
    using namespace std;
    
    
    /*
     * The idea is as follows:
     * 1.) Create a mathematical set A that holds integers.
     * 2.) Initialize importantBit = highest bit in any integer in v
     * 3.) Put into A all integers that have importantBit set to 1.
     * 4.) If |A| = 2, that is our answer. If |A| < 2, --importantBit and try again. If |A| > 2, basically
     *     redo the problem but only on the integers in set A.
     *
     * Keep "set A" at the beginning of v.
     */
    pair<unsigned, unsigned> find_and_sum_pair(vector<unsigned> v)
    {
        // Find highest bit in v.
        int importantBit = 0;
        for(auto num : v)
            importantBit = max(importantBit, highest_bit_index(num));
    
        // Move all elements with imortantBit to front of vector until doing so gives us at least 2 in the set.
        int setEnd;
        while((setEnd = partial_sort_for_bit(v, importantBit, v.size())) < 2 && importantBit > 0)
            --importantBit;
    
        // If the set is never sufficient, no answer exists
        if(importantBit == 0)
            return pair<unsigned, unsigned>();
    
        // Repeat the problem only on the subset defined by A until |A| = 2 and impBit > 0 or impBit  = 0
        while(importantBit > 1)
        {
            unsigned secondSetEnd = partial_sort_for_bit(v, --importantBit, setEnd);
            if(secondSetEnd >= 2)
                setEnd = secondSetEnd;
        }
    
        return pair<unsigned, unsigned>(v[0], v[1]);
    }
    
    // Returns end index (1 past last) of set A
    int partial_sort_for_bit(vector<unsigned> &v, unsigned importantBit, unsigned vSize)
    {
        unsigned setEnd = 0;
    
        unsigned mask = 1<<(importantBit-1);
        for(decltype(v.size()) index = 0; index < vSize; ++index)
            if(v[index]&mask > 0)
                swap(v[index], v[setEnd++]);
    
        return setEnd;
    }
    
    
    unsigned highest_bit_index(unsigned i)
    {
        unsigned ret = i != 0;
        while(i >>= 1)
            ++ret;
        return ret;
    }