简单的算法题求指点
题目是这样的:
Description
计算机世界是0和1的世界,所有我们看到的数字、字符、图形,实际上都是以0和1的形式在存储在计算机中的。对于具有一定模式的字符串,常使用正则表达式予以描述。例如[01]+表示由字符集合{0,1}组成的所有不为空的串,如0,1,01,10,00000,111,11001001等等。而(01)+则表示由一个或多个01串接的串,如01,0101,010101,0101(01)+等都是(01)+串。对于给定的[01]+串,计算其中包含的所有的(01)+子串的个数。例如0101011111101中,有4个01串,2个0101子串,1个010101子串。一共有7个(01)+子串。
Input
第一行是测试数据的组数n(0 < n <= 100)。紧接着是n组测试数据,每组一行。每一组测试数据长度大于0,且小于等于100。
Output
输出其中(01)+子串的个数。
Sample Input
4
11111111100000000
01011111101
0001001000101010
1010000000
Sample Output
0
4
8
1
下面是我写的代码,提交是wrong answer:
#include <iostream>
using namespace std;
int main()
{
int n, nums, res;
char a[101];
char *p1, *p2;
cin>>n;
cin.ignore();
while(n--)
{
cin.getline(a, 101);
res = nums = 0;
for(p1 = a, p2 = p1+1; *p2 != '\0'; p1++, p2++)
{
if(*p1 == '0' && *p2 == '1')
{
nums++;
}
else if(nums != 0)
{
if(*p1 != '1' || *p2 != '0')
{
res += nums*(nums+1)/2;
nums = 0;
}
}
}
res += nums*(nums+1)/2;
cout<<res<<endl;
}
return 0;
}
求指点,谢谢。
[解决办法]
算法没看出来啥毛病,于是使用最直接的方式检查了下,也没发现有错的。源码如下:
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
int fast_count(const char* a)
{
int res = 0, nums = 0;
for (const char* p1 = a, *p2 = p1 + 1; *p2 != '\0'; p1++, p2++)
{
if (*p1 == '0' && *p2 == '1')
{
nums++;// 匹配01
}
else if (nums != 0)
{
if (*p1 != '1'
[解决办法]
*p2 != '0')
{
res += nums * (nums + 1) / 2;
nums = 0;
}
}
}
res += nums * (nums + 1) / 2;
return res;
}
// 统计字符串s中pattern出现的总次数
int count_pattern(const string& s, const string& pattern)
{
int n = 0;
string::size_type pos = 0;
while ((pos = s.find(pattern, pos)) != string::npos)
{
++n;
++pos;
}
return n;
}
int slow_count(const char* p)
{
const string s(p);
string pattern("01");
int count = 0;
while (s.find(pattern) != string::npos)
{
count += count_pattern(s, pattern);
pattern += "01";
}
return count;
}
// 整数转换为二进制格式的字符串
string int_to_binary_string(int m)
{
char buf[33] = {0};
for (int i = 31, j = 0; i >= 0; --i, ++j)
{
buf[j] = (m & (1 << i)) ? '1' : '0';
}
return string(buf);
}
int main()
{
assert(fast_count("11111111100000000") == 0);
assert(fast_count("01011111101") == 4);
assert(fast_count("0001001000101010") == 8);
assert(fast_count("1010000000") == 1);
assert(fast_count("0101011111101") == 7);
assert(slow_count("11111111100000000") == 0);
assert(slow_count("01011111101") == 4);
assert(slow_count("0001001000101010") == 8);
assert(slow_count("1010000000") == 1);
assert(slow_count("0101011111101") == 7);
for (int i = 0; i < 65535; ++i)
{
const string s = int_to_binary_string(i);
if (fast_count(s.c_str()) != slow_count(s.c_str()))
{
cerr << s << endl;
throw 0;
}
}
cout << "all are ok" << endl;
return 0;
}
[解决办法]
我明明有加"["code=c"]""["/code"]"的。。
[解决办法]
楼主试试这个,我尽量写得简单了 对于这种串匹配的问题,最好就是状态机
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[]){
int total;
int has01Count = 0;
int subTotal = 0;
char buf[128];
enum {
none,pre0,pre1
} state;
cin>>total;
while(total--){
has01Count = 0;
subTotal = 0;
state = none;
cin>>buf;
char* p = buf;
char c;
while( (c = *p++) ){
switch(c){
case '0':{
if(state == none){
state = pre0;
}else if(state == pre0){
has01Count = 0;
state = pre0;
}else if(state == pre1){
state = pre0;
}
break;
}
case '1':{
if(state == none){
state = pre1;
}else if(state == pre0){
has01Count++;
subTotal += has01Count;
state = pre1;
}else if(state == pre1){
has01Count = 0;
state = pre1;
}
break;
}
}/* switch */
}/* while(*p != '\n') */
cout<<subTotal<<endl;
}
return 0;
}
[解决办法]
这就是用状态机的好处啦,可以防止你出现思维的死角。。说实话你那代码我也看不出什么问题。。