posts - 12,comments - 0,views - 2074

第五节、字符串

第一节 基础知识

1.每个字符都有对应的整数ASCII码,常用ASCII值,’A''Z'是6590,‘a''z'是97122,’0‘’9'是4857,字符可以参与运算,运算时会将其当作整数。(记住)

计算机里面的所有字符是-128~127的数字两者之间可以相互转换。

整数与ASCII码转换的关系

#include <iostream>
using namespace std;
int main()
{
    //强制类型转换
    char c = 'a';
    cout<< (int)c <<endl;
    int a=66;
    cout << (char)a <<endl;
    return 0;
    
	for(int i=1;i<128;i++) printf("%d: %c\n",i,(char)i); 
    printf("%c\n",'a'+3);//输出d
    printf("%d\n",'b'-'a');//输出差,1
    int a='B'-'A';
    int b='A'*'B';
    char c='A'+2;
    cout << a <<endl;//1
    cout << b <<endl;//4290=65*66
    cout << c <<endl;//C
	return 0;
 } 
2.字符数组

字符串就是字符数组加上结束符‘\0’,可以使用字符串来初始化字符数组,但要注意,每个字符串结尾会暗含一个‘\0’字符,因此字符串数组的长度至少比字符串数组的长度多1

#include <string.h>为头文件
char a1[]={'C','+','+'};//列表初始化,没有空字符
char a2[]={'C','+','+','\0'};//列表初始化,含有显示的空字符
char a3[]='C++';//a2[]和a3[]一样都是四个都是字符数组,a1[]是字符串,\0是空字符。自动添加表示字符串结尾的空字符
printf("%s\n",a3);//输出:c++
cout<<a3<<endl;//输出c++

char a2[]={'A','B','C','\0'};
char a3[]="ABCDEF";
cout << a2+1<<endl;//输出BC,从1开始输出
printf("%s\n",a3+2);//输出CDEF,从第二个开始输出,跟指针类似
return 0;

char s[100]
scanf("%s",s);//一定不要加&符号,因为字符串s本身就是一个指针
cout << s <<endl;//读入abcdef,输出abcdef
return 0;

char s[100];
cout << s+2 << endl;//从下标2开始读
cout << s[1] <<endl;//是数组从第一个下标开始
return 0;

char str[100];
cin >> str;//输入字符串时,遇到空格或者回车就会停止。
cout << str <<endl;//输出字符串时,遇到空格和回车不会停止。
printf("%s\n",str);

char s[100];
fgets(s,100000000,stdin);//读入一整个字符串,包括空格
cout << s << endl;
//如果string 的话,这样可以用getline(cin,s)
string s;
getline(cin,s);
cout << s <<endl;
//或者用puts(s)读入
scanf("%s",s);
puts(s);
printf("%s\n",s);
return 0;
3.字符数组常用函数

需要引入头文件#include <string.h>

(1)strlen(s)求字符串长度

(2)strcmp(a,b),比较两个字符串的大小,a<b返回-1,a==b返回0,a>b返回1,这里的比较方式是字典序

(3)strcpy(a,b),将字符串b复制给从a开始的字符串数组

//(2)例如
#include <cstdio>
#include <iostream>
#include <cstring>
int main()
{
    char s1[100],s2[100];
    scanf("%s",s1);
    cout << strcmp(s1,"abc") << endl;//例如输入abc则输出0,输入abb输出-1,输入abd输出1
}
4.string

if(str[i]==c)//判断是否为c,用c而不是'c'

读入字符串,最好不要用scanf报错,输出用printf。

注意:fgets函数会把回车也读进来,getline()会把空格读进来

b.pop_back();是把最后一个字符(空格)删除掉

stringstream ssin(a) ssin和cin等价

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    string s1;//默认空的字符串
    string s2=s1;//s2是s1的一个副本
    string s3="hiya";//s3是该字符串面值的一个副本
	string s4(10,'c');//s4的内容是:ccccccccccc
    string s1,s2;
    cin>>s1;
    printf("%s\n",s1.c_str());//或者puts(s1.c_str())
    return 0;
    
    //读入一行
    string s1,s2;
    getline(cin,s1);
    cout <<s1<<endl;//例如读入23snl skk输出23snl skk,但是如果为cin>>s1;则输出23snl
    s3+="is great";//string 可以直接加字符串
}
string s="Hello World!";
for(char c:s)cout<<c<<endl;
return 0;
这样输出为
    H
    e
    l
    ……
    !
  //或者输出这样写也行
    for(int i=0;i<s.size();i++)
        cout <<s[i]<<endl;
//如果想要改变数组的值
for(char &c:s)
{
    c='a';
}
cout << s <<endl;
//输出全为a了,在char后面加一个&符号
5.双指针

for(int i=0;i<sin;i++)

image-20221204085117893

.back是字符串的最后一个字符

.pop_back()是去掉字符串的最后一个字符

第二节、例题

1.判断只出现一次的字母

image-20221122184134088
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int cnt[26];
char str[100010];
int main()
{
    cin >> str;
    int len=strlen(str);
    for(int i=0;i<strlen(str);i++) cnt[str[i]-'a']++;//读入数组里面每一个字符
    for(int i=0;i<strlen(str);i++)//是不是出现字符只出现了一次
        if(cnt[str[i]-'a']==1)
        {
            cout << str[i] <<endl;
            return 0;
        }
        puts("no");
        return 0;
}

2.判断字符串中数字的个数

#include <cstdio>
int main()
{
    char str[101];//定义字符串
    fgets(str,101,stdin);//读入字符串
    int cnt=0;
    for(int i=0;str[i];i++)
        if(str[i]>='0'&&str[i]<='9')//判断是不是数字
            cnt++;
    printf("%d\n",cnt);
    return 0;
}

3.字符串插入

image-20221125140811223
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    string a,b;
    while(cin>>a>>b)
    {
        int p=0;
        for(int i=1;i<a.size();i++)
         if(a[i]>a[p])
            p=i;//先找出最大的
        cout<<a.substr(0,p+1)+b+a.substr(p+1)<<endl;//从0到p+1,加b加p+1到最后
    }
    return 0;
}

4.忽略大小写比较字符串大小(较难)

image-20221125143638217
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
    char a[100],b[100];
    fgets(a,100,stdin);
    fgets(b,100,stdin);
    if (a[strlen(a) - 1] == '\n') a[strlen(a) - 1] = 0;  // 去掉末尾回车
    if (b[strlen(b) - 1] == '\n') b[strlen(b) - 1] = 0;  // 去掉末尾回车
    for(int i=0;a[i];i++)
        if(a[i]>='A'&&a[i]<='Z')
            a[i]+=32;
    for(int i=0;b[i];i++)
        if(b[i]>='A'&&b[i]<='Z')
            b[i]+=32;
    int t=strcmp(a,b);
    if(t==0)puts("=");
    else if(t<0)puts("<");
    else puts(">");
    return 0;
}

5.去掉多余的空格

image-20221129141804680
#include <iostream>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    string r;
    for(int i=0;i<s.size();i++)
        if(s[i]!=' ')r+=s[i];//当前不是空格
        else
        {
            r+=' ';
            int j=i;//双指针算法
            while(j<s.size()&&s[j]==' ')j++;//来辨别是否是当前连续的空格
            i=j-1;
        }
        cout << r <<endl;
}

6.字符串移位 难!!(没有思路)

image-20221204105232878
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    string a, b;

    cin >> a >> b;
    if (a.size() < b.size()) swap(a, b);

    for (int i = 0; i < a.size(); i ++ )//每循环一次移位一次
    {
        a = a.substr(1) + a[0];

        for (int j = 0; j + b.size() <= a.size(); j ++ )//找起点每一段都枚举一遍
        {
            int k = 0;
            for (; k < b.size(); k ++ )
                if (a[j + k] != b[k])
                    break;
            if (k == b.size())
            {
                puts("true");
                return 0;
            }
        }
    }

    puts("false");

    return 0;
}

7.字符串乘方 难!!!(没有思路)

image-20221204110612140

输出 1 4 3

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    string str;
    while (cin>>str,str != ".")
    {
        int len=str.size();
        for(int n=len;n;n--)
        if(len%n==0)//一定要满足n是len的约数
        {
            int m=len/n;//先枚举len与n的约数
            string s=str.substr(0,m);
            string r;//在用一个字符串,用str的前m个字符拼接n次得到新的字符串与原来字符串进行比较看是否相等
            for(int i=0;i<n;i++) r+=s;//重复n次拼接起来
            if(r==str)
            {
                cout<<n<<endl;
                break;
            }
        }
    }
    return 0;
}

7.字符串最大跨距 难!!

image-20221204111541575

输出18

#include <iostream>

using namespace std;

int main()
{
    string s, s1, s2;

    char c;
    while (cin >> c, c != ',') s += c;//只要不属于,就加过去
    while (cin >> c, c != ',') s1 += c;
    while (cin >> c) s2 += c;//当文件没有结束一直读下去

    if (s.size() < s1.size() || s.size() < s2.size()) puts("-1");//如果字符串较小则没有相应的字符串可以找到
    else
    {
        int l = 0;//设置一个起点,从l开始的这一段是否与s1相等
        while (l + s1.size() <= s.size())
        {
            int k = 0;
            while (k < s1.size())//当k小于这一段时
            {
                if (s[l + k] != s1[k]) break;//不等于时break,一直加
                k ++ ;
            }
            if (k == s1.size()) break;//如果等于的话就是一样了,break
            l ++ ;
        }

        int r = s.size() - s2.size();//定义r从起点开始枚举
        while (r >= 0)
        {
            int k = 0;
            while (k < s2.size())
            {
                if (s[r + k] != s2[k]) break;
                k ++ ;
            }
            if (k == s2.size()) break;//相等
            r -- ;
        }

        l += s1.size() - 1;//第一个字符串最后一个位置

        if (l >= r) puts("-1");//s1不完全在s2左边,说明不能输出相差多少个
        else printf("%d\n", r - l - 1);//反之输出多少个
    }

    return 0;
}

8.最长公共字符串后缀 难!!

image-20221204162041354
输出ba
    
    a
#include <iostream>
using namespace std;
const int N = 200;//const 是N的值不能变,是个常量。

int n;//枚举字符串的后n个字符
string str[N];

int main()
{
    while (cin >> n, n)
    {
        int len = 1000;
        for (int i = 0; i < n; i ++ )
        {
            cin >> str[i];
            if (len > str[i].size()) len = str[i].size();
        }

        while (len)//枚举后面是否一样
        {
            bool success = true;
            for (int i = 1; i < n; i ++ )
            {
                bool is_same = true;
                for (int j = 1; j <= len; j ++ )
                    if (str[0][str[0].size() - j] != str[i][str[i].size() - j])
                    {//如果不等于则输出false
                        is_same = false;
                        break;
                    }
                if (!is_same)
                {//如果不一样时的输出
                    success = false;
                    break;
                }
            }

            if (success) break;
            len -- ;
        }

        cout << str[0].substr(str[0].size() - len) << endl;//输出最长的公共后缀
    }

    return 0;
}
posted on   cathyd  阅读(80)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

点击右上角即可分享
微信分享提示