如何在C++中的单行中返回常量数组中的值



我在讨论C++中针对特定问题的最快执行时间。问题是创建一个函数,该函数接收1到100之间的单个整数,并尽可能快地返回该数字的平方。输入验证将在调用函数之前进行,唯一重要的是执行时间。

我想出了一个2行函数,看起来很快,如下所示:

#include <iostream>
int fastSquare(int i) {
int returnValue[101] = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 
169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 
1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 
2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 
3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 
4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 
5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 
7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 
9216, 9409, 9604, 9801, 10000
};
return returnValue[i];
}
int main()
{
int value = 36;
std::cout << "The square of " << value << " is " << fastSquare(value) << ".n";
}

但是,我希望将它作为一行,不包含变量声明。合适的语法是什么?这是我的最新尝试,不会编译:

#include <iostream>
int fastSquare(int i) {
return int[] {1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 
169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 
1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 
2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 
3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 
4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 
5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 
7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 
9216, 9409, 9604, 9801, 10000
}[i];
}
int main()
{
int value = 36;
std::cout << "The square of " << value << " is " << fastSquare(value) << ".n";
}

答案中建议的每种方法都会在每次调用函数时初始化一个数组。摆脱它:

static const int squares[] = {
0, 1, 4, /* et cetera */, 10000
};
int fast_square(int i) { return squares[i]; }

请注意,这也修复了所有拟议解决方案中的"一个错误"。

诀窍是使用std::array来代替原始数组。使用C++17,该函数将变为

int fastSquare(int i) 
{
return std::array{1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 
169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 
1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 
2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 
3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 
4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 
5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 
7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 
9216, 9409, 9604, 9801, 10000
}[i];
}

如果你不能使用C++17,但可以使用C++11或C++14,那么你仍然可以使用std::array,你只需要提供类似的类型和大小

int fastSquare(int i) 
{
return std::array<int, 101>{1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 
169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 
1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 
2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 
3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 
4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 
5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 
7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 
9216, 9409, 9604, 9801, 10000
}[i];
}

如果您不想使用std::array,那么为了使用原始数组,您需要引入一个=n别名。using int_arr = int[101];在中的应用

int fastSquare(int i) 
{
using int_arr = int[101];
return int_arr{1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 
169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 
1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 
2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 
3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 
4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 
5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 
7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 
9216, 9409, 9604, 9801, 10000
}[i];
}

允许您创建一个临时数组对象,然后可以访问该对象。


请注意,这样做确实会影响性能。他们的编译器无法/可能无法优化数组构建,这可能会超过最初使用表的代码。使用

constexpr int fastSquare(int i) 
{
constexpr std::array arr{1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 
169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 
625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 
1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 
2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 
3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 
4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 
5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 
7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 
9216, 9409, 9604, 9801, 10000
};
return arr[i];
}

节省了创建成本,还可以在编译时使用它。

最新更新