我想重新排序向量中的项目,使用另一个向量来指定顺序:
char A[] = { 'a', 'b', 'c' };
size_t ORDER[] = { 1, 0, 2 };
vector<char> vA(A, A + sizeof(A) / sizeof(*A));
vector<size_t> vOrder(ORDER, ORDER + sizeof(ORDER) / sizeof(*ORDER));
reorder_naive(vA, vOrder);
// A is now { 'b', 'a', 'c' }
Run Code Online (Sandbox Code Playgroud)
以下是一个低效的实现,需要复制向量:
void reorder_naive(vector<char>& vA, const vector<size_t>& vOrder)
{
assert(vA.size() == vOrder.size());
vector vCopy = vA; // Can we avoid this?
for(int i = 0; i < vOrder.size(); ++i)
vA[i] = vCopy[ vOrder[i] ];
}
Run Code Online (Sandbox Code Playgroud)
有没有更有效的方法,例如,使用swap()?
典型的基于LOG()宏的日志记录解决方案可能如下所示:
#define LOG(msg) \
std::cout << __FILE__ << "(" << __LINE__ << "): " << msg << std::endl
Run Code Online (Sandbox Code Playgroud)
这允许程序员使用方便且类型安全的流操作符创建数据丰富的消息:
string file = "blah.txt";
int error = 123;
...
LOG("Read failed: " << file << " (" << error << ")");
// Outputs:
// test.cpp(5): Read failed: blah.txt (123)
Run Code Online (Sandbox Code Playgroud)
问题是这会导致编译器内联多个ostream :: operator <<调用.这会增加生成的代码,从而增加函数大小,我怀疑这可能会损害指令缓存性能并阻碍编译器优化代码的能力.
这是一个"简单"替代方案,它通过调用可变参数模板函数替换内联代码:
********* 解决方案#2:VARIADIC模板功能 *********
#define LOG(...) LogWrapper(__FILE__, __LINE__, __VA_ARGS__)
// Log_Recursive wrapper that creates the ostringstream
template<typename... Args>
void LogWrapper(const char* file, int line, const Args&... …Run Code Online (Sandbox Code Playgroud) 我想我的tcsh脚本启动编辑器(例如,vi,emacs):
#!/bin/tcsh
vi my_file
Run Code Online (Sandbox Code Playgroud)
这将使用my_file启动vi,但首先显示警告"Vim:警告:输出不是终端",并且我的键击不会出现在屏幕上.在我杀死vi之后,我的终端窗口搞砸了(没有新行),需要"重置".我尝试了"emacs -nw","xemacs -nw"和pico,结果相似."xemacs"可以工作,但会启动一个单独的窗口.我想重用相同的终端窗口.
有没有办法从脚本启动编辑器,以便它重用相同的终端窗口?
写一个无分支函数,如果两个有符号整数之间的差为零,负或正,则返回0,1或2.
这是一个分支版本:
int Compare(int x, int y)
{
int diff = x - y;
if (diff == 0)
return 0;
else if (diff < 0)
return 1;
else
return 2;
}
Run Code Online (Sandbox Code Playgroud)
这是一个可能更快的版本,具体取决于编译器和处理器:
int Compare(int x, int y)
{
int diff = x - y;
return diff == 0 ? 0 : (diff < 0 ? 1 : 2);
}
Run Code Online (Sandbox Code Playgroud)
你能想出一个没有分支的更快的吗?
摘要
我基准测试的10个解决方案具有相似的性能.实际数字和获胜者取决于编译器(icc/gcc),编译器选项(例如,-O3,-march = nocona,-fast,-xHost)和机器. 佳能的解决方案在许多基准测试中表现良好,但性能优势再次轻微.令我感到惊讶的是,在某些情况下,某些解决方案比使用分支的天真解决方案慢.
给定STL向量,仅按排序顺序输出重复项,例如,
INPUT : { 4, 4, 1, 2, 3, 2, 3 }
OUTPUT: { 2, 3, 4 }
Run Code Online (Sandbox Code Playgroud)
该算法很简单,但目标是使其与std :: unique()一样高效.我天真的实现就地修改了容器:
我天真的实施:
void not_unique(vector<int>* pv)
{
if (!pv)
return;
// Sort (in-place) so we can find duplicates in linear time
sort(pv->begin(), pv->end());
vector<int>::iterator it_start = pv->begin();
while (it_start != pv->end())
{
size_t nKeep = 0;
// Find the next different element
vector<int>::iterator it_stop = it_start + 1;
while (it_stop != pv->end() && *it_start == *it_stop)
{
nKeep = 1; // …Run Code Online (Sandbox Code Playgroud) 我们多次遭到以下错误的困扰:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(int* pn) { cout << *pn << " "; }
int main() {
int* n1 = new int(1);
int* n2 = new int(2);
int* n3 = new int(3);
vector<int*> v;
v.push_back(n1);
v.push_back(n2);
v.push_back(n3);
sort(v.begin(), v.end()); // Here be dragons!
for_each(v.begin(), v.end(), print);
cout << endl;
delete n1; delete n2; delete n3;
}
Run Code Online (Sandbox Code Playgroud)
问题是std :: sort比较整数指针而不是整数,这不是程序员想要的.更糟糕的是,输出可能看起来是正确的和确定的(考虑新的或在堆栈上分配的地址的顺序).根问题是sort最终调用operator <for T,当T是指针类型时,这很少是个好主意.
有没有办法防止这种情况或者至少得到编译器警告?例如,有没有办法创建一个自定义版本的std :: sort,当T是指针时需要比较函数?