两个字符串题目

水博客,更新两个花了比较长时间的字符串习题,虽然时间主要是花在debug上了

1、字符串乘方

给定两个字符串 a和 b,我们定义 a×b 为他们的连接。

例如,如果 a=abc 而 b=def, 则 a×b=abcdef

如果我们将连接考虑成乘法,一个非负整数的乘方将用一种通常的方式定义:a0=``(空字符串),a(n+1) = a×(an)。

输入格式

输入包含多组测试样例,每组测试样例占一行。

每组样例包含一个由小写字母构成的字符串 s,s 的长度不超过 100,且不包含空格。

最后的测试样例后面将是一个点号作为一行。

输出格式

对于每一个 s,你需要输出最大的 n,使得存在一个字符串 a,让 s=an

输入样例:

1
2
3
4
abcd
aaaa
ababab
.

输出样例:

1
2
3
1
4
3
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
45
46
# include<iostream>
# include<cstdio>
# include<string>

using namespace std;

int main() {

string str;

while (getline(cin, str), str != ".") { //这个判定条件是循环读入str串,如果读入的串是"."则停止,即程序结束

int len = str.size(); //求一下串的长度
string substr;
substr += str[0]; //定义一个子串,子串是str的第一个字符
int n = 1; // n表示子串的长度

for (int i = 0; i < len; i++) {


int time = len / n; //求子串和主串间的倍数关系

string check;

if (len % n == 0) { // 如果存在整数倍关系,则进入下一步检查

for (int j = 0; j < time; j++) {
check += substr; //将当前子串扩写time倍,达到和主串一样的长度
}

if (check == str) { // 检查扩写后是否和主串相同
cout << time << endl;
break;
}

}

substr += str[i + 1]; //如果上一步判定扩写后不等于主串,则将子串后面顺序添加一个主串的字符
n++; //更细子串的长度
}


}

return 0;
}

2、字符串最大跨距

有三个字符串 S,S1,S2,其中,S 长度不超过 300300,S11 和 S22 的长度不超过 1010。

现在,我们想要检测 S1 和 S2 是否同时在 S 中出现,且 S11 位于 S22 的左边,并在 S 中互不交叉(即,S1 的右边界点在 S2的左边界点的左侧)。

计算满足上述条件的最大跨距(即,最大间隔距离:最右边的 S2 的起始点与最左边的 S1 的终止点之间的字符数目)。

如果没有满足条件的 S1,S2 存在,则输出 −1−1。

例如,S= abcd123ab888efghij45ef67kl, S1= ab, S2= ef,其中,S1 在 S中出现了 2 次,S2 也在 S 中出现了 2 次,最大跨距为:18。

输入格式

输入共一行,包含三个字符串 S,S1,S2,字符串之间用逗号隔开。

数据保证三个字符串中不含空格和逗号。

输出格式

输出一个整数,表示最大跨距。

如果没有满足条件的 S1 和 S2 存在,则输出 −1。

输入样例:

1
abcd123ab888efghij45ef67kl,ab,ef

输出样例:

1
18
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# include<iostream>
# include<cstdio>
# include<string>

using namespace std;

int main() {
string s;
string s1;
string s2;
string s3;
int loc = 0;
int distance = 0;
size_t temp_pos2;

getline(cin, s);

for (int i = loc; i < s.size(); i++) {
if (s[i] != ',') {
s1 = s1 + s[i];
}
else {
loc = i + 1;
break;
}
}

for (int i = loc; i < s.size(); i++) {
if (s[i] != ',') {
s2 = s2 + s[i];
}
else {
loc = i + 1;
break;
}
}

for (int i = loc; i < s.size(); i++) {
if (s[i] != ',') {
s3 = s3 + s[i];
}
else {
loc = i + 1;
break;
}
} //上面三个for循环其实是用了读取三个字符串,并且按照要求以','分割
// 看了题解之后发现有更简单的写法
/*
char temp;
string a, b, c;

while (cin >> temp , temp != ',') a += temp;
while (cin >> temp , temp != ',') b += temp;
while (cin >> temp , temp != ',') c += temp;
*/

size_t pos1 = s1.find(s2);
size_t pos2 = s1.find(s3);

if (pos1 == string::npos || pos2 == string::npos) { // 如果有一个子串不存在,就结束程序
cout << -1 << endl;
}
else {
pos1 = pos1 + s2.size() - 1; // 左侧的子串好处理,只需要把pos1的位置定好,要考虑串的长度

temp_pos2 = pos2; // 这个temp_pos2的位置很关键,他妈的debug找了半天才发现是这块出了问题
for (; temp_pos2 != string::npos;) {
pos2 = temp_pos2;
temp_pos2 = s1.find(s3, pos2 + 1); // 依次查找下去,直到找到最后一个右子串,注意pos2 + 1,以防步子太大漏查
}

if (pos1 > pos2) { // 这里的判定条件是防止虽然存在左右子串,但是存在重叠的部分,左串尾和右串头之间不存在其他字符
cout << -1 << endl;
}

else {
distance = pos2 - pos1 - 1 ;
cout << distance << endl;
}
}

// cout << s1 << endl << s2 << endl << s3 << endl;

return 0;
}

关于C++debug

VS studio 用来debug还是方面,虽然已经几百年没用过了

VS code应该也可以用来debug但是配置起来似乎有些麻烦