您在C ++中打高尔夫球有哪些一般技巧?我正在寻找可以应用于一般高尔夫问题代码的想法,这些想法至少在某种程度上是C ++特有的(例如,“删除注释”不是答案)。请为每个答案发布一个提示。
您在C ++中打高尔夫球有哪些一般技巧?我正在寻找可以应用于一般高尔夫问题代码的想法,这些想法至少在某种程度上是C ++特有的(例如,“删除注释”不是答案)。请为每个答案发布一个提示。
Answers:
三元有条件的经营者?:
往往可以用作简单的一个立场if
- else
语句在相当大的节约。
它具有特殊的价值,因为它可用于选择备用左值,如
#include <iostream>
#include <cstdlib>
int main(int c, char**v){
int o=0,e=0,u;
while(--c) ((u=atoi(v[c]))%2?o:e)+=u;
std::cout << "Sum of odds " << o <<std::endl
<< "Sum of evens " << e <<std::endl;
}
e
和o
。请注意,这与该运算符在c中的工作方式不同,在c中此技巧不起作用,因为它不能为左值。
std::endl
用'\n'
,节省了5个字符
一些编译器(例如GCC)支持多字符常量。当需要大整数值时,这可以节省一些字符。例:
int n=' ';
该值是特定于实现的。通常,'ab'
is 256*'a'+'b'
或的值'a'+256*'b'
。引号之间最多可以指定4个字符。
我觉得很方便的一个:
利用非零值true
在布尔表达式中x&&y
求值,以及x*y
在处理布尔值时求值的事实
(x!=0 && y!=0)
评估为
(x*y)
您只需要注意溢出,如下所述。
x!=0 && y!=0
。但是在使用乘法时,您需要小心溢出。当使用32位整数x = y = 65536(以及其他两种幂的组合)时,x * y = 0。
&&
短路行为*
缺乏。例如,您不能将替换i++!=0&&j++!=0
为i++*j++
。
使用以下类型:
u64, s64, u32, s32 (or int)
对于重复的单词/类型,请使用#defines
:
#define a while
仅当您使用while
大量字符来弥补额外的10个字符时才值得。(约4个。)
由于数组元素彼此紧接着直接存储在内存中,而不是像这样的东西:
for(int x = 0; x < 25; x++) {
for(int y = 0; y < 25; y++)
array[x][y] = whatever;
}
您可以执行以下操作:
int* pointer = array;
for(int i = 0; i < 25*25; i++, pointer++)
*pointer = whatever;
显然,上述两种方法都不易理解,但是为了明确起见,使用指针可以节省大量空间。
for(int* i=array; i<array+25*25; i++)
呢?然后,您只需要跟踪一个变量即可。
很明显,但是您使用了很多标准库,using namespace std;
可能会节省一些字符。
using std::name;
可能会更短。
std::
五次或更多次,这只会保存字符。
不用写10的大幂,而是使用e表示法。例如,a=1000000000
长于a=1e9
。可以扩展到其他数字,例如a=1e9+24
优于a=1000000024
。
1e9/x
与1000000000/x
或不同int(1e9)/x
。
您可以?:
在true块中使用不带任何表达式的三元运算符(节省一个字节)
#include <iostream>
int foo()
{
std::cout << "Foo\n";
}
int main()
{
1?foo():0; // if (true) foo()
0?:foo(); // if (!false) foo()
}
这是GCC特有的,它可以扩展到其他编译器。
在G ++ bits/stdc++.h
中,预编译头由所有其他头组成。如果您需要import
2种不同的产品,则可以使用它。
这是http://en.cppreference.com/w/cpp/header上列出的所有标题:
按长度的升序排序。
其中有些已经比更长bits/stdc++.h
,有些还需要C ++ 17支持。TIO G ++不支持其他一些(出于我不知道的原因)。过滤掉它们,我们有:
可能发生其中一些可以被较短的替换的情况。只是二进制搜索,是否可以替换您需要的那个。尤其是:
cstdio -> ios (-3 bytes)
algorithm -> regex (-4 bytes)
vector -> queue (-1 byte)
string -> map (-3 bytes)
bitset -> regex (-1 byte)
numeric -> random (-1 byte)
布尔运算:
虽然
a*=b>0?.5:-.5
胜过
if(b>0)a*=.5;else a*=-.5;
它不如
a*=(b>0)-.5
另外,对经常使用的任何东西使用#define。它通常比使用函数短,因为不需要类型名称。
尽可能多地组合:
a+=a--;
是相同的
a=2*a-1;
对于以外的类型int
,将它们用作函数参数可能会很昂贵。但是,引入了通用Lambda(在C ++ 14中),并且允许将任何Lambda用作模板- auto
用于参数类型可以节省字节。相比:
double f(double x, double y)
[](auto x, auto y)
通用的lambda也用于接受迭代器很方便-可能在C ++接受阵列输入的最好的方法是[](auto a, auto z)
,其中,a
与z
作为传递begin()
和end()
阵列/向量/列表/等。
在我第一次尝试通过代码高尔夫完成“减去下一个数字”任务时,我从功能(58字节)开始
int f(int N, int P){int F;for(F=N;P;F-=++N,P--);return F;}
然后安全地转移到lambda并将初始化从for
(53)中移出,这是5个字节
[](int N,int P){int F=N;for(;P;F-=++N,P--);return F;}
最后从切换for
到后,while
我得到了51个字节:
[](int N,int P){int F=N;while(P--)F-=++N;return F;}
取消测试的代码如下所示:
#include <iostream>
int main(void)
{
int N, P;
std::cin >> N >> P;
auto f = [](int N,int P)
{
int F = N;
while (P--)
F -= ++N;
return F;
};
std::cout << f(N, P) << std::endl;
return 0;
}
更新:
实际上for
可以达到以下长度while
:
[](int N,int P){int F=N;for(;P--;F-=++N);return F;}
我想晚会有点晚...
如果要将表达式转换为-1和1而不是0和1,请执行以下操作:
int x;
if (a * 10 > 5)
x = 1;
else
x = -1;
做这个:
int x = (a * 10 > 5) * 2 - 1;
根据使用情况,它可以节省一些字节。
int x=(a*10>5)*2-1;
,您不能做吗int x=a*10>5?1:-1;
,那要短1个字节?
如果要交换两个整数变量a和b,
a^=b^=a^=b;
可以使用,比标准方式节省5个字符
a+=b;
b=a-b;
a-=b;
,t
在较早创建的int处,然后t=a;a=b;b=t;
将比a+=b;b=a-b;a-=b;
。短3个字节。不过,您a^=b^=a^=b;
的身材比这还矮,所以请+1。我不懂C ++,但确实可以。作为Java代码访问者,我感到遗憾的是,那里似乎不起作用。:(
a^=b;b^=a;a^=b;
在Java中运行良好。
a^=b;b^=a;a^=b;
确实有效,但比,t
+长t=a;a=b;b=t;
。抱歉提到Java,因为它不在这里。但是对于C ++代码编写者来说是一个不错的提示!
不要用string("")
,用""
。节省8个字节。
"" + 'a'
是char* + char
,它是指针此外,虽然std::string("") + 'a'
是std::string + char
-字符串连接。string()
会工作。