回文及字符串相关

22 篇文章 0 订阅

回文字符串


  • 给定一个字符串,首尾两端没有空格,判断它是否为回文字符串。 回文字符串,就是正过来读、反过来读都一样的字符串。 “abcdcba”是回文字符串,“abcdeba”不是回文字符串。 额外要求:时间复杂度为O(N),空间复杂度为O(1)。

代码


#include <stdio.h>
#include <string>

using namespace std;

int main() {

    char a[100];
//    scanf("%s", a);
//    printf("%d", strlen(a));
    while (scanf("%s", a)!=EOF) {
        bool flag = true;
        for (int i=0, j=(strlen(a)-1); i<j; i++, j--){
            if (a[i]==a[j]) {
                continue;
            }
            flag = false;
            printf("no\n");
            break;
        }
        if(flag==true)printf("yes\n");

    }
    return 0;
}

字符串输入输出问题

字符串的输入

1. scanf:

char name[81];
scanf(“%s”,name);
  • 注意:不能使用:
char *name;
scanf(“%s”,name);//错误:因为这样声明的话,不知道name的值,即不知道name到底指向那块内存。
  • scanf输入时,会跳过前面所有空白字符,直到再次遇到空白字符才会结束输入,并在读入的字符串后面自动加一个’\0’。同时会将后面的空白字符留在输入流中。
  • scanf用%s接收字符串的时候,遇到空格就会停止。如果想输入多个单词,需要多次调用scanf()

2. gets:

char name[81];
gets(name);

或者:

   char *ps;
   ps= gets(name);
  1. gets()函数以换行符作为结束的标记;
  2. 它会将换行符前面的所有字符读入,并在字符串后面自动加一个’\0’
  3. 换行符将被丢弃,换行符后面的仍留在输入流。
  4. gets()函数就是可以无限制地读入,多出来的字符会溢出到相邻的内存。
  5. gets()在现在机器上,如果输入ctrl+Z会返回NULL,但注意,此时name没读到值,但其地址不变,也就是说,gets()的返回值不是赋给name的。
  6. gets函数的参数必须是一个已分配内存的地址。
  7. 返回一个char型指针,指向字符串(首字符)地址,如果输入ctrl+Z,返回值是一个NULL,但name仍是原来的地址。

    • 说明:name是gets的参数,所以必须是已分配内存的。而一个数组一旦声明了,系统会自动分配内存,因此可以做参数。但ps就不行,因为ps没有初始化,不知道它指向哪块内存。
      ps可以用来接受gets(name)的返回值,如果读入成功,就返回字符串地址,这时ps就是name的地址。如果读入不成功,name还是原先地址,但ps变成了NULL。

3. fgets:

  • 需要制定最大字符读入数,是为文件I/O设计的,处理键盘输入时不如gets()方便。
  • 它需要第二个参数来制定最大读入字符数。如果读入字符数达到这个值,或者遇到一个换行度,就停止读入;
  • 如果遇到换行符,该换行符将被读入字符串,再在换行符后加一’\0’;
  • 还需要第三个参数指定读哪个文件。如果是从键盘上读入数据,就用stdin。
  • 该函数返回一个char型指针,指向字符串(首字符)地址
例子:
标准输入:
    char name[80];
    char *ptr;
    ptr=fgets(name,81,stdin);
    printf("name: %s,  ptr: %s\n",name,ptr);
从文件输入:
    FILE *fp=fopen("E:\\code\\wordcopys.txt","r");
    char name[80];
    char *ptr;
    ptr=fgets(name,81,fp);
    printf("name: %s,  ptr: %s\n",name,ptr);
  • “E:\code\wordcopys.txt”一定要用\,不能用一个.
  • 如果wordcopys.txt和程序在同一个目录下,也可直接写为
    FILE *fp=fopen(“wordcopys.txt”,”r”);
  • 还有一点要注意的是:scanf会忽略前面所有的空白字符,但gets和fgets不会。

字符串的输出

1. scanf:

printf (“%s”,name);
  • name是字符串的地址。

2. puts():

  • 给出字符串的地址即可,与printf不同的是,这个函数会在字符串后面自动添加换行符。
  • 我们并不一定要给一个字符串的首地址,只要是一个char型地址就行,函数会从这个地址的字符开始输出,直到遇到空字符’\0’。

3. fputs():

  • fputs需要第二个参数来说明要写的文件,如果输出到屏幕上,就用参数stdout;
  • fputs不会自动添加换行符。
  • 注意,gets()会丢掉换行符,但puts()会自动添加换行符;
    fgets()会加上换行符,但fputs()不会添加换行符。

字符串大小写转换问题

tolower(c)

该函数把大写字母转换为小写字母。

toupper(c)

该函数把小写字母转换为大写字母。

字符是否为字母或数字问题

#include <ctype.h>
isalnum(c);
isalpha(c);
isdigit(c);
isupper(c);
islower(c);

回文串的加强版

这里写图片描述

思路

定义两个指针分别指向头尾,然后让头指针指向第一个字母或数字(函数isalnum),当头指针指向的不是字母或数字时则往后移动(保证小于尾指针的条件下),直到指向字母或者数字;然后尾指针也做同样的工作,指向最后面那个字母或者数字。然后比较这两个字符是否相等,相等则循环;否则不是回文。

代码

    bool isPalindrome(string s) {
        for(int i=0, j=s.size()-1; i<j; i++,j--){
        while (!isalnum(s[i])&&i<j) i++;//指向前端字母或数字
        while (!isalnum(s[j])&&i<j) j--;//指向尾部字母或数字
        if (toupper(s[i])!=toupper(s[j])) return false;//不相等则说明不是回文
        }
        return true;//比较完没发现不相等,则说明是回文
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值