我试图返回子数组中的索引,在此之前,子数组中的所有元素都可以被某个大数K(long long类型)整除。我已经设法编写了正确的代码,但是复杂度不是很高。谁能建议一种更好的方法来优化运行时间?
long long solve (vector<long long> A, long long K, int R, int L) {
int index=L-1;
int count=0;
while(A[index]%K==0 && index<=R-1){
if(A[index]%K==0){
count++;
}
index++;
}
if(count!=0){
return (L+count-1);
}
else{
return -1;
}
}
此处,参数为: L是子数组的最左边界 R是子数组的最右边界 A是一个包含整个数组的向量。 A = {1,2,4,5,7,9}
例如,如果我通过L=2, R=4, K=2
,它将返回index=3
(索引从1开始)。
换句话说,从向量的索引1到3,我们正在检查从L
到R
哪个元素可以被K
整除。我们继续前进,直到此序列中的某个元素不能满足可除性标准为止。然后,我们打印其结束索引。否则,如果没有这样的元素满足条件,我们将返回-1
答案 0 :(得分:2)
该函数的设计很糟糕,不符合C ++概念。
对于C ++中的入门索引,从0开始。其次,范围指定为[start, end)
,而该范围中不包含end
。
该函数应该返回std::vector<long long>::size_type
类型的对象。如果在该范围内找不到满足条件的元素,则该函数应返回end
的值。
我将按照演示程序中所示的以下方式编写函数
#include <iostream>
#include <vector>
#include <algorithm>
auto solve( const std::vector<long long> &v,
std::vector<long long>::size_type first,
std::vector<long long>::size_type last,
long long value )
{
last = std::min( last, v.size() );
first = std::min( first, last );
auto current = first;
while ( ( current != last ) && ( v[current] % value == 0 ) ) ++current;
return current == first ? last : current - 1;
}
int main()
{
using size_type = std::vector<long long>::size_type;
std::vector<long long> v = { 1, 2, 4, 5, 7, 9 };
size_type first = 1;
size_type last = 3;
long long divisor = 2;
auto i = solve( v, first, last, divisor );
if ( i != last )
{
std::cout << "The last element divisible by " << divisor
<< " in the range [" << first
<< ", " << last
<< ") is at position " << i << '\n';
}
else
{
std::cout << "There is no element divisible by " << divisor
<< " in the range [" << first
<< ", " << last << ")\n";
}
}
其输出为
The last element divisible by 2 in the range [1, 3) is at position 2
您可以使用迭代器编写相同的函数。在这种情况下,函数声明看起来会更简单。
例如
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
auto solve( std::vector<long long>::const_iterator first,
std::vector<long long>::const_iterator last,
long long value )
{
auto it = std::find_if_not( first, last,
[&value]( const long long &item ) { return item % value != 0; } );
return it == first ? last : std::prev( first );
}
int main()
{
std::vector<long long> v = { 1, 2, 4, 5, 7, 9 };
auto first = std::next( std::cbegin( v ), 1 );
auto last = std::next( std::cbegin( v ), 3 );
long long divisor = 2;
auto it = solve( first, last, divisor );
if ( it != last )
{
std::cout << "The last element divisible by " << divisor
<< " in the range [" << std::distance( std::cbegin( v ), first )
<< ", " << std::distance( std::cbegin( v ), last )
<< ") is at position " << std::distance( std::cbegin( v ), it ) << '\n';
}
else
{
std::cout << "There is no element divisible by " << divisor
<< " in the range [" << std::distance( std::cbegin( v ), first )
<< ", " << std::distance( std::cbegin( v ), last ) << ")\n";
}
}
答案 1 :(得分:0)
您的逻辑存在缺陷,因为它不会在其他情况下脱离循环。我建议不要改用修正的方法,而建议改用标准算法,而不是编写自己的算法,例如:
const auto start = next(cbegin(A), L - 1);
const long long finish = distance(start, find_if(start, next(cbegin(A), R - 1), bind(modulus<int>(), placeholders::_1, K)));
const auto result = finish == 0 ? -1 : finish;
与mentioned by Vlad from Moscow一样,基于1的索引会增加复杂性。如果您愿意使用基于0的索引,请返回0而不是-1,然后使用lambda可以做到:
const auto result = count_if(next(cbegin(A), L), next(cbegin(A), R), [=](const auto i) { return i % K == 0; })