假设我有一个数字列表:[0 0 1 1 1 0 1 1 0 1 0 0 0 1 1]
,它由0或1组成,我的问题是如何在列表中找到数字1
的开始和结束位置。以上面的数字列表为例,1
列表的位置为:
[2 4]
[6 7]
[9 9]
[13 14]
使用C ++,实现了以下方法:
int main()
{
unsigned char charArray[15]={0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1};
std::vector<std::pair<int,int> > posArray;
int begPos=-1;
int endPos=-1;
for(int i=0; i<15; i++)
{
if(charArray[i] ==1)
{
if(begPos!=-1)
{
endPos++;
}
else
{
begPos=i;
endPos=i;
}
}
else
{
if(begPos != -1)
{
posArray.push_back(std::make_pair<int,int>(begPos,endPos));
begPos=-1;
}
}
}
if(charArray[14] == 1)
{
posArray.push_back(std::make_pair<int,int>(begPos,endPos));
}
for(int i=0; i<posArray.size(); i++)
{
std::cout<<"( "<<posArray[i].first<<" , "<<posArray[i].second<<" )"<<std::endl;
}
return 0;
}
这个问题是否有更有效的解决方案(时间或空间)?谢谢。
答案 0 :(得分:4)
我建议的解决方案效率不高但看起来更好。:)
尝试以下
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <utility>
#include <functional>
int main()
{
unsigned char charArray[] =
{
0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1
};
std::vector<std::pair<int,int> > posArray;
auto first = std::begin( charArray );
while ( ( first = std::find( first, std::end( charArray ), 1 ) ) != std::end( charArray) )
{
auto last = std::find_if( first, std::end( charArray ),
std::bind2nd( std::not_equal_to<int>(), 1 ) );
posArray.push_back( { std::distance( charArray, first ),
std::distance( charArray, last ) - 1 } );
first = last;
}
for ( auto &p : posArray ) std::cout << '[' << p.first
<< ' ' << p.second
<< ']' << std::endl;
return 0;
}
输出
[2 4]
[6 7]
[9 9]
[13 14]
如果数组仅包含0和1,那么您可以替换此语句
auto last = std::find_if( first, std::end( charArray ),
std::bind2nd( std::not_equal_to<int>(), 1 ) );
这个
auto last = std::find( first, std::end( charArray ), 0 );
在这种情况下,循环看起来像
while ( ( first = std::find( first, std::end( charArray ), 1 ) ) != std::end( charArray) )
{
auto last = std::find( first, std::end( charArray ), 0 );
posArray.push_back( { std::distance( charArray, first ),
std::distance( charArray, last ) - 1 } );
first = last;
}
要编写更高效的代码,必须为向量保留内存。
例如
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <utility>
#include <functional>
int main()
{
unsigned char charArray[] =
{
0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1
};
std::vector<std::pair<int,int> > posArray;
size_t n = std::inner_product( std::next( std::begin( charArray ) ),
std::end( charArray ),
std::begin( charArray ),
0ul,
std::plus<size_t>(),
std::greater<char>() );
n += charArray[0] == 1;
posArray.reserve( n );
auto first = std::begin( charArray );
while ( ( first = std::find( first, std::end( charArray ), 1 ) ) != std::end( charArray) )
{
auto last = std::find( first, std::end( charArray ), 0 );
posArray.push_back( { std::distance( charArray, first ),
std::distance( charArray, last ) - 1 } );
first = last;
}
for ( auto &p : posArray ) std::cout << '[' << p.first
<< ' ' << p.second
<< ']' << std::endl;
return 0;
}
答案 1 :(得分:1)
无法抗拒。这是我的两个问题:
int main()
{
unsigned char charArray[] = {0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1};
std::vector<std::pair<int,int> > posArray;
size_t found[2];
unsigned char seek = 0;
for(size_t i = 0; i < sizeof(charArray); ++i)
{
if(seek == charArray[i])
continue;
found[seek] = i - seek;
if(!(seek ^= 1))
posArray.push_back(std::make_pair(found[0], found[1]));
}
if(seek)
posArray.push_back(std::make_pair(found[0], sizeof(charArray) - 1));
for(int i = 0; i < posArray.size(); i++)
std::cout << "[" << posArray[i].first
<< " , " << posArray[i].second << "]" << '\n';
}
<强>输出强>
[2 , 4]
[6 , 7]
[9 , 9]
[13 , 14]