HENAU字符串专题

A题雷同检测

B - 首字母大写

C大小写转换

D数字反转

E - 删除单词后缀

F - 判断字符串是否为回文

G - 基础数据结构——栈(1)

H - 字典序

I - 验证子串

J - 子串查找

K - 剪花布条

L - 最长回文子串

A题雷同检测

思路:暴力
代码:

#include<iostream>
using namespace  std;
int count=0;
int main()
{
	string s1,s2;
	getline(cin,s1);//读取两段字符串。 
	getline(cin,s2);
	int l=(s1.size()>s2.size())?s2.size():s1.size();//比较俩字符串的长度并把最长的赋值给l 
	int a[l];
	for(int i=0;i<l;i++)
	{
		if(s1[i]==s2[i])
		a[i]=1;
		else
		a[i]=0;
	}
	for(int i=0;i<l;i++)
	   if(a[i]==1)
	    cout<<i+1<<" ";
}

B - 首字母大写

思路:暴力
代码:

***解法一:***
#include<iostream>
using namespace std;
int main(){
	string a;
	int i;
	getline(cin,a);
	int l=a.size();
	if(a[0]>=97&&a[0]<=122)a[0]-=32;
	for(i=0;i<=l;i++){
		if(a[i]>=97&&a[i]<=122&&a[i-1]==' ')
			a[i]=a[i]-32;
	}
	cout<<a<<endl;
	return 0;
}
**解法二:**
#include <stdio.h>
#include <stdlib.h>

int islittle (char ch);
int main()
{
    char str[100];
    gets(str);
    int i;
    for(i = 0;str[i] != '\0';i++)
    {
        if(str[i] == ' ' && str[i+1] != ' ')///少了一种,如果开头为字母
        {
            if(islittle(str[i+1]))///如果是小写
            str[i+1] -= 32;
        }
    }
    if (str[0] != ' ' &&islittle(str[0]))
    str[0] -= 32;
    printf("%s",str);
    return 0;
}
int islittle(char ch)
{
    if(ch>='a' && ch <= 'z')
    return 1;
    else
    return 0;
}

C大小写转换

思路:暴力
代码:

#include<iostream>
#include<string.h>
using namespace std;
int main()
{
	char s[81];
	int n=0;
	while(scanf("%s", s) == 1)//输入多行字符串 
	{
		int len=strlen(s);
		for (int i = 0; i <len; i++) {
        		if ('a' <=s[i] && s[i] <= 'z') {  // 判断是否为小写字母 
        			s[i] = s[i] - ('a' - 'A');  // 转成大写字母 
        		}
        		cout << s[i];
        	}cout<<endl;
	}
}

D数字反转

思路:模拟
代码

解法一:
#include <stdio.h>
#include <string.h>
int main()
{
	char s[100];
	gets(s);
	int n,f=0,t;
	n=strlen(s)-1;    //统计字符串有多长,注意下标是从0开始的,值要减1
	while(s[n]=='0')  //计算第一个非’0’位置
	{
		n--;
		t=n;
	}
	if(s[0]=='-')     //符号特判
	{
		f=1;
		printf("-");
	}
	for(int i=n;i>=1;i--)    //从非’0’位置倒序输出
	{
		printf("%c",s[i]);
	}
	if(f==0)               //单独输出
	{
		printf("%c",s[0]);
	}
	return 0;
}
解法二:
#include<iostream>
using namespace std;
int main (){
	int n;
	int s=0; 
	cin>>n;  
	while(n!=0){
		int ge=n%10;//把n的最后一位重新定义并赋值
		s=s*10+ge;// 核心代码
		n/=10;//去掉n的最后一位
	}
	cout<<s;//输出结果
	return 0;
}

E - 删除单词后缀

思路:直接判断
代码:

#include<iostream>
#include<string.h>
using namespace std;
int main()
{
	char s[33];
	gets(s);
	int l=strlen(s);
	if(s[l-1]=='r'&&s[l-2]=='e') s[l-2]='\0';
	if(s[l-1]=='y'&&s[l-2]=='l') s[l-2]='\0';
	if(s[l-1]=='g'&&s[l-2]=='n'&&s[l-3]=='i') s[l-3]='\0';
    cout<<s;
}

F - 判断字符串是否为回文

思路:模拟
代码:

解法一:
#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s;
	cin>>s;
	char a[100];
	int n=0;
	for(int i=0;i<s.size();i++ )
	{
		a[++n]=s[i];//赋值给a数组 
	}
	for(int i=0;i<s.size();i++)
	{
		if(a[n]!=s[i])
		{
			cout<<"no";
			return 0;
		}
		n--;
	}
	cout<<"yes";
}
解法二:
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
	char a[100];
	int i, j;
	gets(a);			
	j = strlen(a) - 1;			//将字符串的长度-1之后赋值给j
	for (i = 0; i < j; i++, j--)			//将字符从两侧开始逐渐对比是否相同
		if (a[i] != a[j]) break;		
	if (a[i] == a[j])
		printf("yes");			
	else printf("no");		
	return 0;
}

G - 基础数据结构——栈(1)

思路:首先利用栈结构保存相关符号,并不断消去配对的符号,判断最后是否为空。注意输入的时候可以是空格
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1e5+100;
char str[1000];
 int judge(char c)
 {
    if(c=='{'||c=='}')return 1;
    if(c=='('||c==')')return 1;
    if(c=='['||c==']')return 1;
    return 0;
}
int main()
{
	while(cin.getline(str,1000,'\n'))
	{
		stack <char> st;//栈st 
		ll l=strlen(str);
		  for(int i=0;i<l;i++)
		  {
		     if(judge(str[i]))
		         {
		         	if(st.empty())//是否为空栈
		         	{
		         		st.push(str[i]);//将数组元素入栈 
					}
					else 
					{
						char c=st.top();//栈顶.
						st.pop();//出栈 
						if(str[i]=='}')
						{
							if(c!='{')
							{
								st.push(c);
								st.push(str[i]);
							}
						}
						else if(str[i]==']')
						{
							if(c!='[')
							{
								st.push(c);
								st.push(str[i]);
							}
						}
						else if(str[i]==')')
						{
							if(c!='(')
							{
								st.push(c);
								st.push(str[i]);
							}
						}
						else
						{
							st.push(c);
							st.push(str[i]);
						}
					}
             	 }
            }
	  if(st.empty())//所有括号都匹配成功 
	    {
            printf("yes\n");
        }
	  else
		{
            printf("no\n");
        }
}
	return 0;
}
	

H - 字典序

思路:可以直接用字符串比较函数。
代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
	char s1[10000];
	char s2[10000];
	gets(s1);
	gets(s2);
	int t;
	t=strcmp(s1,s2);
	if(t<0)
	{
		printf("YES");
	}
	else if(t>0) 
	{
		printf("NO");
	}
 } 

I - 验证子串

思路:首先范围比较小可以进行暴力回溯,这里用kmp进行求解,算是复习。对kmp的直接应用。
代码:

#include<iostream>
#include<string>
using namespace std;

int main()
{
	string a,b;
	getline(cin,a);
	getline(cin,b);
	if(a.find(b)!=string::npos )//查找匹配 ,当a.find(b)==string::npos时说明字符串a中不存在b这个字符串。 
	    cout<<b<<" is substring of " <<a;
	else if(b.find(a)!=string::npos)
	    cout<<a<<" is substring of " <<b;
	    else
	    cout<<"No substring";
}

J - 子串查找

思路:模板题目,对kmp算法的直接应用
代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
using namespace std;
int s[1000100],l1,l2;
char a[1000100],b[1000100];
void get_next()
{
	int i=0,j=-1;
	s[0]=-1;
	while(i<l2)
	{
		if(j==-1||b[i]==b[j])
		{
			i++;
			j++;
			s[i]=j;
		}
		else
		j=s[j];
	}
}
void kmp()
{
	int i=0,j=0;
	int ans=0;
	while(i<l1)
	{
		if(j==-1||a[i]==b[j])
		{
			++i;
			++j;
		}
		else
		j=s[j];
		if(j==l2)
		{
			j=s[j];
			ans++;
		}
	}
	printf("%d\n",ans);
}
int main()
{
	
	scanf("%s %s",a,b);
	l1=strlen(a);
	l2=strlen(b);
	if(l2>l1)
	   printf("0\n");
	
	get_next();//调用俩函数 
	kmp();
}

K - 剪花布条

思路:oj原题,直接暴力模拟也可以做,就是当匹配成功后不进行回溯,让变量变为零,其余和上一个·题目差不多
代码:

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define maxn 1010
char s[maxn];
char t[maxn];
int next[maxn];
int a,b;
void get_next()
{
	next[0]=0;
	int i=1,j=0;
	while(i<b)
	{
		if(t[i]==t[j])
		{
			next[i++]=++j;
		}
		else if(!j){
			i++;
		}
		else
		{
			j=next[j-1];
		}
	}
	
}
int kmp()
{
	int i=0,j=0,ans=0;
	while(i<a&&j<b)
	{
		if(s[i]==t[j])
		{
			i++;j++;
		}
		else if(!j)
		{
			i++;
		}
		else{
			j=next[j-1];
		}
		if(j==b)
		{
			j=0;ans++;
		}
	}
	return ans;
}
int main()
{
	while(scanf("%s",s))
	{
		if(strcmp(s,"#")==0)
		{
			break;
		}
		scanf("%s",t);
		a=strlen(s);
		b=strlen(t);
		get_next();
		printf("%d\n",kmp());
	}
	return 0;
}

L - 最长回文子串

思路:经典题目,用动态规划,其中是用已经确定的结果来进行推,第一层循环是倒着的,第二层是正的,原因是dp[i][j]的结果是从dp[i+1][j-1]推出的因此第一层是需要先推大的i值,第二层j需要的是小的j值
代码:

#include<bits/stdc++.h>
#include<string.h>
#include<cmath>
using namespace std;
char *longestPalindrome(char * s)
{
    int n = strlen(s);
    int dp[n][n];
    int l, i;
    static char ans[100];
    for(i=0; i<n; i++)
        for(l=0; l<n; l++)
            dp[i][l]=0;
    for(l=0; l<n; l++)  //子串长度
    {
        for(i=0; i+l<n; i++) //子串起始位置
        {
            int j = i+l; //子串末尾位置
            if(l==0)
                dp[i][j]=1;
            else if(l==1)
                dp[i][j]=(s[i]==s[j]);
            else
            {
                dp[i][j] = ((s[i]==s[j]) && dp[i+1][j-1]);
            }
            if(dp[i][j] && l+1>strlen(ans))
            {
                strncpy(ans,s+i,l+1);
            } 
        }
    }  
    return ans;
}
int main()
{
	char str[1010];
	int count;
	gets(str);
	 
	cout<<strlen(longestPalindrome(str));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木雨杨华!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值