Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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
如何减少这个问题的执行时间(即更快的代码) 这个问题来自于CooCheF.[如果有人还在解决这个问题,在尝试之前不要再深入研究这个帖子了。虽然它运行正常,但我需要更快地完成它。我是C、C++的初学者。(我知道数组、字符串和指针的内容,但不知道文件处理等)。.那么,有没有一种方法可以让这个程序运行得更快,而不使它变得复杂(如果它的算法复杂,那就没问题了)。 我也会接受复杂的编码,如果你提到你遵循的是哪本书,在那里给出了它:)。 我目前正在跟踪罗伯特·拉福尔。 节目如下:-_C++_C_Time_Performance_Execution - Fatal编程技术网

如何减少这个问题的执行时间(即更快的代码) 这个问题来自于CooCheF.[如果有人还在解决这个问题,在尝试之前不要再深入研究这个帖子了。虽然它运行正常,但我需要更快地完成它。我是C、C++的初学者。(我知道数组、字符串和指针的内容,但不知道文件处理等)。.那么,有没有一种方法可以让这个程序运行得更快,而不使它变得复杂(如果它的算法复杂,那就没问题了)。 我也会接受复杂的编码,如果你提到你遵循的是哪本书,在那里给出了它:)。 我目前正在跟踪罗伯特·拉福尔。 节目如下:-

如何减少这个问题的执行时间(即更快的代码) 这个问题来自于CooCheF.[如果有人还在解决这个问题,在尝试之前不要再深入研究这个帖子了。虽然它运行正常,但我需要更快地完成它。我是C、C++的初学者。(我知道数组、字符串和指针的内容,但不知道文件处理等)。.那么,有没有一种方法可以让这个程序运行得更快,而不使它变得复杂(如果它的算法复杂,那就没问题了)。 我也会接受复杂的编码,如果你提到你遵循的是哪本书,在那里给出了它:)。 我目前正在跟踪罗伯特·拉福尔。 节目如下:-,c++,c,time,performance,execution,C++,C,Time,Performance,Execution,有N个数字a[0],a[1]…a[N-1]。一开始都是0。您必须执行两种类型的操作: 1) 将索引A和B之间的数字增加1。这由命令“0ab”表示 2) 回答指数A和B之间有多少个数字可以被3整除。这由命令“1A B”表示 输入: 第一行包含两个整数,N和Q。接下来的Q行中的每一行都是上述形式的“0ab”或“1ab” 输出: 为表格“1A B”中的每个查询输出1行,其中包含相应查询的所需答案 样本输入: 4 7 1 0 3 0 1 2 0 1 3 1 0 0 0 0 3 1 3 3 1 0 3

有N个数字a[0],a[1]…a[N-1]。一开始都是0。您必须执行两种类型的操作:

1) 将索引A和B之间的数字增加1。这由命令“0ab”表示

2) 回答指数A和B之间有多少个数字可以被3整除。这由命令“1A B”表示

输入:

第一行包含两个整数,N和Q。接下来的Q行中的每一行都是上述形式的“0ab”或“1ab”

输出:

为表格“1A B”中的每个查询输出1行,其中包含相应查询的所需答案

样本输入:

4 7
1 0 3
0 1 2
0 1 3
1 0 0
0 0 3
1 3 3
1 0 3
样本输出:

4
1
0
2
限制条件:

1 <= N <= 100000
1 <= Q <= 100000
0 <= A <= B <= N - 1

1从我所看到的,您的代码是最优化的


-Alex

除了缺少边界检查之外,我认为你的解决方案似乎很好。在检查“c”或开关时,可能会使用“else”,但这将为您节省微不足道的时间。
我不认为你会在任何一本书中找到像这样毫无用处的东西。

这在我看来相当有效。 我看到的是,你正在使用,这对于C(AFAIK)是可以的,但是C++中是非法的,对于C++,你需要使用<代码> STD::vector < /COD>或<代码>新< /COD>数组。
我能看到您提高性能的唯一地方是使用部分循环展开,我不建议将其用于玩具样本。

您可以做的一个改进是更换

if (c == 0) {
    //code here
}

if (c == 1) {
   // code here
}
与:

如果您确定
c
始终为0或1,您也可以用简单的
else
替换
else if

真正让你慢下来的是I/O。如果它是一个足够大的列表,它可能需要花费
malloc
足够的内存来保存输入和输出。然后在进入循环之前收集所有输入,并在最后显示输出

1) 将索引A和B之间的数字增加1。这由命令“0ab”表示

2) 回答指数A和B之间有多少个数字可以被3整除。这由命令“1A B”表示

最初的数字是0,因此可以被3整除。增加1使这个数字不可整除。下一个增量-数字仍然不可整除。第三个增量使数字再次可整除

我们可以尝试的第一个优化是不让数字增长到2以上:若在增量期间数字从2变为3,则将其设置回零。现在搜索范围成为与0的简单比较。(这样,数组将包含其模3而不是数字。)

第二个优化是使用区段而不是普通数组,例如类似于:将所有具有相同整除性的相邻数字压缩到一个范围内。数组将包含如下结构,而不是数字:

struct extent {
   int start; /* 0 .. N-1; extent should have at least one number */
   int end;   /* 0 .. N   */
   int n;     /* 0, 1, 2; we are only interested in the result of % */
};
最初,数组将包含覆盖所有数字的单个区段
{0,N,0}
。在增量步骤中,可能会将一个范围拆分或与相邻的范围合并。这种表示法将加快数字的计数,因为你将不是一个接一个地遍历数组,而是逐块遍历数组。(如果所有范围仅包含一个元素,则仍将降级为线性搜索。)


另一种方法是使用三组索引代替数组。集合#0将包含模3为0、集合#1-1、集合#2-2的所有数字的索引。由于在增量操作期间,我们需要进行搜索,而不是
std::set
,因此最好使用每个位标记属于集合的数字的索引

注意,这样我们就根本不保留原始数字。我们隐式地只保留模3的结果


在增量过程中,我们需要找到索引所属的集合,例如集合#n,并将索引移动到下一个(mod 3)集合:在集合
n
中将位设置为零,在集合
n+1(mod 3)
中将位设置为1。现在,计算可被3整除的数字就像计算集合#0中的非零位一样简单。这可以通过创建一个temp
std::bitset
作为掩码,将范围
[a,B]
中的位设置为1,将temp设置为set#0进行掩码,并对生成的位集调用
std::bitset::count()

实际上,只能在数组中存储模3的值,而不能存储实际值

增量可以通过一个简单的查找表来完成(以避免比较和分支):


测试3-整除率现在比0-要快得多。

这相当复杂,但请听我说。除了“27年的编码经验”之外,我无法列举任何具体的地方

原问题将数字线设置为自然整数0,1,2,3,4,5,6。。。但是,我们只关心可被3整除的数字,因此让我们重新定义数字行,使其仅包含三个值:{2,3,4}并重新映射数字行,以便:

0=>4
1=>2
2=>3
3=>4
4=>2
5=>3
6=>4
.. 等等

你会注意到,在我们的序列中,可被3整除的数字被映射为4。为什么使用{2,3,4}?4在二进制中是100,这意味着任何第3位的元素都可以被3整除。这很容易通过位操作进行测试。

if (c == 0) { //... } else if (c == 1) { //... }
struct extent {
   int start; /* 0 .. N-1; extent should have at least one number */
   int end;   /* 0 .. N   */
   int n;     /* 0, 1, 2; we are only interested in the result of % */
};
char increment[3] = { 1, 2 ,0 };
new_val = increment[old_val];
unsigned char *arr = malloc(n/2 + 1);

// Init all element values to 4:
memset(&arr, 0x44, n/2 + 1);
/**
   @param p
      p is the address of the byte with the first aligned element to be incremented, &arr[A/2] when A is even, &arr[A/2]+1 when A is odd.
   @param j
      j is the number of elements to increment.  (B-A) when A is even, (B-A-1) when A is odd.
 */ 
void increment_aligned_block(unsigned char *p, int j)
    uint64_t fours;

    while (j>16) {
       // Find the ones that are value 4
       fours = *p & 0x4444444444444444;
       // Decrement each that matches by 3
       *p -= (fours >> 1 | fours >> 2);

       // Add 1 to each of the 16 array elements in the block.
       (uint64_t)(*p) += 0x1111111111111111;
       p += 8; j -= 16;
    }
    if (j >= 8) {
        // repeat the above for 32-bits (8 elements)
        // left as an exercise for the reader.
        p += 4; j -= 8;
   }
    if (j >= 4) {
        // repeat the above for 16-bits (4 elements)
        // left as an exercise for the reader.
        p += 2; j -= 4;
    }
    if (j >= 2) {
        // repeat the above for 8-bits (2 elements)
        // left as an exercise for the reader.
        p += 1; j -= 2;
    }
    if (j == 1) {
        // repeat the above for 8-bits (1 elements)
        // left as an exercise for the reader.
    }
}
/**
   @param p
      p is the address of the byte with the first aligned element to be counted, &arr[A/2] when A is even, &arr[A/2]+1 when A is odd.
   @param j
      j is the number of elements to count.  (B-A) when A is even, (B-A-1) when A is odd.
 */ 
int count_aligned_block(unsigned char *p, int j)
    int count = 0;
    uint64_t divisible_map;

    while (j > 16) {
        // Find the values of 4 in the block
        divisible_map = (uint64_t)(*p) & 0x4444444444444444;

        // Count the number of 4s in the block,
        // 8-bits at a time
        while (divisible_map) {
          switch (divisible_map & 0x44) {
            case 0x04:
            case 0x40:
                count++;
                break;
            case 0x44:
                count += 2;
                break;
            default:
                break;
          }
          divisible_map >>= 8;
        }
    }
    // Repeat as above with 32, 16, 8 and 4-bit math.
    // Left as an exercise to the reader

    return count;
}