1.字符串和上学期在c语言学习的问题不大,主要算法思想有双指针,滑动窗口等,而这个部分的关键就在于记忆经典题目并会简单的c++vector操作
2.
【问题描述】如果字符串的一个子串(其长度大于1)的各个字符均相同,则称之为等值子串。试设计一算法,求出串S中一个长度最大的等值子串;如果串S 中不存在等值子串,则输出信息no
【输入形式】输入一个字符串,并以!结束
【输出形式】输出第一个出现的最长字符串,如果没有输出no
【样例输入】aabc123abc123cc!
【样例输出】aa
【样例输入】abceebccadddddaaadd!
【样例输出】ddddd
这道题目不需要使用滑动窗口,只需要直接计算,每次记录最长子串起始点的信息以及最长子串的长度即可
#include<iostream>
#include<string>
using namespace std;
void found(string s)
{
int len = 0;
int ret = 0;
int start = 0;
for (int i = 1; i < s.size(); i++)
{
if (s[i] == s[i - 1])
{
len++;
}
else
{
len = 1;
}
if (ret < len)
{
ret = len;
start = i - ret + 1;
}
}
if (ret > 1)
{
for (int j = 0; j < ret; j++)
{
cout << s[start + j];
}
}
else
{
printf("no");
}
}
int main()
{
string a;
int i = 0;
while (1)
{
char d;
cin >> d;
if (d == '!')
{
break;
}
else
{
a.push_back(d);
}
}
found(a);
return 0;
}
3.
【问题描述】判断两个字符串是否匹配,其中一个字符串中包括通配符*或?(串)。*代表0个或多个字符,?代表一个字符
【输入形式】分两行入两个字符串,以#结束,其中一个字符串中包括通配符*或?(串),另一个为不包含*和?的确定字符串
【输出形式】判断两个字符串是否匹配,若匹配,输出yes,不匹配输出no
【样例输入】
da?a*tu*e#
datastructure#
【样例输出】
yes
【样例说明】 第一个字符串中包含通配符,第二个字符串为确定字符串。字符串中可能有空格,字母均为小写字母。
【评分标准】 请尽量使用效率高的算法,如结合KMP算法的思想。
提示:?可看做对任一字符的匹配,*可看做对给出的有效字符(串)的匹配。
首先这道题可以使用递归的思想,递归出口为s1遍历完成,如果s2也遍历完成,则返回true,,没有则返回false,然后执行操作,如果字母为*,则有两种情况,一种是空字符,则直接在s1字符串把这个字符跳过,如果代表多个字母的情况,则s2字符串往后一位进行递归,如果是?,则s1,s2同时跳过一位,如果是普通字符,则进行正常比较
#include<iostream>
#include<string>
using namespace std;
bool match(string s1, int start1, string s2, int start2)
{
if (start1 == s1.size() && start2 == s2.size())
{
return true;
}
if (start1 == s1.size() && start2 != s2.size())
{
return false;
}
char p = s1[start1];
if (p == '*')
{
return match(s1, start1 + 1, s2, start2) || (start2 < s2.size()) && (s1, start1, s2, start2 + 1);
}
else if(p=='?')
{
return match(s1, start1 + 1, s2, start2 + 1);
}
else
{
return start2 < s2.size() && p == s2[start2] && match(s1, start1 + 1, s2, start2 + 1);
}
}
int main()
{
string s1;
string s2;
cin >> s1;
cin >> s2;
if (match(s1, 0, s2, 0))
{
cout << 'Yes';
}
else
{
cout << 'No';
}
return 0;
}
3.
【问题描述】给定一个字符串s,找出s里第一次出现的最长的回文子串。
【样例输入1】babad
【样例输出1】bab
【样例输入2】cbbd
【样例输出2】bb
回文子串就是典型的双指针算法,左右指针同时向中间移动,如果出现不同则不是,但是这里介绍一种新颖的算法,用于寻找回文子串
本题思路:本题采用一种简单的方法寻找子串,即从中间一点或两点(字符串长度为奇数为一点,偶数为两点,为了节省讨论直接全部试一遍),一个向左一个向右移动,直到越界或者不构成回文条件为止,注意截取时由于left越界需要加1,为什么截取长度为right-left-1,由于此时left为左边界的左侧元素,right为有边界的右侧元素,按照传统的长度计算right-left+1,而此时right和left的越界导致长度增加了2,所以right-left+1-2=right-left-1
#include<iostream>
#include<string>
using namespace std;
string find(string& s, int left, int right)
{
while (left >= 0 && right < s.size() && s[left] == s[right])
{
left--;
right++;
}
return s.substr(left + 1, right - left-1);
}
string findmax(string s)
{
if (s.empty())
{
return "";
}
string ret = "";
for (int i = 0; i < s.size(); i++)
{
string s1 = find(s, i, i);
string s2 = find(s, i, i + 1);
if (s1.size() > ret.size())
{
ret = s1;
}
if (s2.size() > ret.size())
{
ret = s2;
}
}
return ret;
}
int main()
{
string s;
cin >> s;
cout<<findmax(s);
return 0;
}