不使用任何外部计数器或其他状态,我正在寻找一个有效的函数,它取一个n位值(32位或左右)并返回格雷码中的后续值.
那是:
int fn(int x)
{
int y = gray_to_binary(x);
y = y + 1;
return binary_to_gray(y);
}
Run Code Online (Sandbox Code Playgroud)
但是虽然binary_to_gray()函数是微不足道的(x ^ (x >> 1)),但相应gray_to_binary()的并不是那么微不足道(log(n)迭代循环).
也许有一个更有效的操作序列?要么是标准反射格雷码,要么选择其他格雷码以适应这个问题.
旁白: 我看到这个问题有两种可能的解决方案类型 - 一种是选择一种更容易转换为二进制的代码并使用上面给出的形式(或者为了反映代码演示更有效的二进制转换),以及另一种方法是将转换推迟到二进制并生成一种方法,该方法在不使用二进制增量的情况下遍历格雷码.
在后一种情况下,将结果代码转换为二进制代码可能会变得特别困难.从实际角度来看,这可能是一个不利因素,但它仍然是一件有趣的事情.
更新: 因为有人指出灰色解码只是log(n)操作(使用两种不同技术中的任何一种),我花了一些时间试图弄清楚这是否是对事物可以简化的严格限制.在确定要执行的下一个操作时必须考虑所有位,否则"考虑"位将无法改变,并且函数将在两个值之间振荡.必须以某种方式将输入压缩到可管理的比例以确定要执行的下一个操作.
为了使其log(n-k)运行,可以使用2 k -entry LUT来缩短最后的k操作(评论建议k=32).
另一种可以经常减少事物的技术是乘法和位掩码的组合.例如,计算奇偶校验以实现基于奇偶校验的算法.
从乘法和位掩码的方法来看,似乎可能有空间来发明格雷码,这进一步简化了操作集......但我不认为任何这样的代码是已知的.
假设有一个单词集,我想根据他们的char包(multiset)对它们进行聚类.例如
{茶,吃,阿巴,阿巴,你好}
将聚集成
{{tea,eat},{abba,aabb},{hello}}.
abbaaabb由于它们具有相同的char包,即两个a和两个,因此聚集在一起b.
为了使它高效,我能想到的一种天真的方式是将每个单词转换成一个char-cnt系列,例如,abba并且aabb将被转换为a2b2,tea/eat将被转换为a1e1t1.这样我就可以构建一个字典并用相同的键组合单词.
这里有两个问题:首先我必须对字符进行排序以构建密钥; 第二,字符串键看起来很笨拙,性能不如char/int键.
有没有更有效的方法来解决问题?
是否有人要求对连续均匀分布进行浮点近似与(似乎更受欢迎的)离散均匀分布形成对比?
为了产生量化为浮点类型的任意精度随机值,我希望有以下几点:
double rand0to1(void)
{
int exp = -53;
while (random_bit() == 0) exp--;
return ldexp((double)((1L << 52) | random_52bits()), exp);
}
Run Code Online (Sandbox Code Playgroud)
看起来很常见的是:
double rand0to1(void)
{
return ldexp((double)random_53bits(), -53);
}
Run Code Online (Sandbox Code Playgroud)
显然,前者是不可能实现的近似值,这是一个很大的问题,但我想知道是否在某些情况下,如果结果碰巧很小,尾数总是完全随机的保证会变得有用。
如果我正在实现我自己的通用统一实随机数生成器库,那么偏离惯例并保持尾数对于小值完全随机化会造成什么危害?
我最好的猜测是,在随后的算术之后,额外的精度可能会强制一个舍入条件,这会偏置低位。然而,我的直觉是,这通常也会发生在离散分布的算术上。
在我看来,以下是X宏技巧的首选样式:
#define LIST_OF_COLOURS(X) \
X(RED) \
X(GREEN) \
X(BLUE)
#define LIST_OF_FRUIT(X) \
X(APPLE) \
X(ORANGE) \
X(TOMATO)
Run Code Online (Sandbox Code Playgroud)
具体来说,将X宏传递给列表,而不是在每次实例化列表时都对其进行取消定义和重新定义。这允许:
#define X_LIST(x) x,
#define X_STRING_LIST(x) #x,
#define COMPREHENSIVE_SETUP(n, l) \
enum n { l(X_LIST) }; \
char const* n##Names[] = { l(X_STRING_LIST) };
COMPREHENSIVE_SETUP(Colour, LIST_OF_COLOURS)
COMPREHENSIVE_SETUP(Fruit, LIST_OF_FRUIT)
Run Code Online (Sandbox Code Playgroud)
但是问题是我没有经常在野外看到这种习语,这不是Wikipedia所描述的,即使我每次尝试并觉得更方便的时候它似乎都可以工作。
我的问题是,这实际上合法且已完全定义,还是我依赖未定义的行为?
假设我想在循环中一遍又一遍地调用一些模板,并在模板参数中使用循环索引。像这样(除非不违法):
template <typename T, int k>
T function(T x) {
for (int i = 1; i <= k; ++i) {
for (int j = i - 1; j >= 0; --j) {
constexpr bool method_one_ok = function_of(i, j);
if (method_one_ok) {
x = method_one<T, i, j, k>(x);
} else {
x = method_two<T, i, j, k>(x);
}
}
}
return x;
}
Run Code Online (Sandbox Code Playgroud)
我知道如何使用递归模板和专业化来艰难地完成它,但这是我在 C++11 或更早版本中发现的恐怖之处。
有没有更干净的方法来做到这一点?
在下面的类中,wrapper获取指向任意const方法的指针,并返回对const已删除的方法的调用结果.这可以用来生成相应的非const方法......
struct C {
int x[10];
int const& get(int i) const { return x[i]; }
int const& getr(int const& i) const { return x[i]; }
template<typename T, typename... Ts>
auto& wrapper(T const& (C::*f)(Ts...) const, Ts... args) {
return const_cast<T&>((this->*f)(args...));
}
int& get(int i) { return wrapper(&C::get, i); }
int& getr(int const& i) { return wrapper(&C::getr, i); }
};
Run Code Online (Sandbox Code Playgroud)
几乎.
问题是最终方法getr()无法编译,因为传递给的参数列表wrapper()并不意味着传递引用.当我们进入内部时wrapper(),编译器正在寻找一个按值传递的版本getr().
这有诀窍吗?
我希望允许用户使用相同的用户名,但在#XXXX形式中有一些额外的ID,其中X是一个数字(例如,BestUserName#3421),类似于在Battle.net上完成的方式.
没有两个用户应该具有相同的用户名和#id组合.
此外,我不希望我的用户能够轻松预测其他用户的额外ID.所以,我不能只从BestUserName#0000开始,然后是BestUserName#0001,BestUserName#0002,...).
因此,我想为每个用户名生成一个从0000到9999之间的所有数字到0000到9999之间的每个数字的双射f(n).f必须让你很难猜出你知道什么是f(n-1) F(N).此外,对于所有用户名,f(n)必须不相同.
然后第一个用户将是BestUserName#f(0000),第二个用户将是BestUserName #f(0001),依此类推,我的用户将无法猜出彼此的#id.
我怎么能用Java做到这一点?
c++ ×3
algorithm ×2
c ×2
random ×2
anagram ×1
c++14 ×1
gray-code ×1
java ×1
optimization ×1
performance ×1
permutation ×1
templates ×1
x-macros ×1