01子串计数
题目
一个字符串的子串表示原字符串中一段连续的部分。例如,字符串”121”的子串总共有六个,它们分别是”1”(前一个),”2”,”1”(后一个),”12”,”21”和”121”。但”11”不是”121”的子串,因为两个’1’在原串中不连续。我们认为空串也不是子串。
现给你一个只含有’0’和’1’两种字符的字符串,问它含有相同’0’和’1’的字串有几个。
例如,字符串”0101”中符合条件的子串有4个。它们分别是”01”(前一个),”10”,”01”(后一个),”0101”;字符串”00110011”中符合条件的子串分别为”01”(前一个),”10”,”01”(后一个),”0011”(前一个),”0110”,”1100”,”1001”,”0011”(后一个),”011001”,”00110011”,共10个。
解答
二重循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<stdio.h> #include<stdlib.h> #include <string.h>
int main(){ char str[1000000]; scanf("%s", str); int count=0; int zero, one; for (int i=0; i<strlen(str); i++){ zero = 0, one = 0; for (int j=i; j<L; j++){ if (str[j] == '0'){ zero++; }else if(str[j] == '1'){ one++; }
if ((j-i)%2==1){ if (one == zero){ count++; } } } } printf("%d\n", count); }
|
一重循环
c++ 版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #define score(ch) (ch == '1' ? 1 : -1) long int count_substring_fast(char *str) { unsigned int n = strlen(str); long int ans = 0; long int *counter = new long int[2 * n + 1](); long int tmp_sum = 0; for (int i = 0; i < n; ++i) { tmp_sum += score(str[i]); if (tmp_sum == 0) { ans++; } printf("%ld, ", tmp_sum); counter[n + tmp_sum]++; } printf("\n"); for (int i = 0; i < 2 * n + 1; ++i) { if (counter[i]) { printf("%d: %ld, %ld\n", i - n, counter[i], ans); ans += ((counter[i]) * (counter[i] - 1) / 2); } } delete[] counter; return ans; }
|
C 版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| long int count_substring_fast(char *str) { int n = strlen(str); long int ans = 0; long int *counter; long int tmp_sum = 0; counter = (long int *)malloc(sizeof(long int) * (2 * n + 1)); for (int i = 0; i < 2 * n + 1; i++) { counter[i] = 0; }
for (int i = 0; i < n; ++i) { if (str[i] == '\0') { break; } if (str[i] == '1') { tmp_sum++; } else if (str[i] == '0') { tmp_sum--; } if (tmp_sum == 0) { ans++; } counter[n + tmp_sum]++; } for (int i = 0; i < 2 * n + 1; ++i) { if (counter[i]) { ans += ((counter[i]) * (counter[i] - 1) / 2); } } free(counter); counter = NULL; return ans; }
|
reference:
https://howardlau.me/programming/zero-one-substring.html