字符串高频面试题。

(一)

题目:把一个01(只包含0和1的串)串进行排序。  可以交换任意两个位置,求最少交换的次数。

方法:仿造快速排序里面的partition的过程。。。最左边的0和1是没有意义的,从左到右扫到第一个1,从右到左扫到第一个0,然后交换,然后继续扫下去,就ok啦。。

代码:

#include <iostream>
#include <string>

#define MAXN 1000

using namespace std;

int main(int argc, const char * argv[]) {
    int a[MAXN];
    int n;
    cin >> n;
    for(int i = 0; i < n; ++i) cin >> a[i];
    int answer = 0;
    for(int i = 0, j = n - 1; i < j; ++i, --j) {
        for(; (i < j) && (a[i] == '0'); ++i);
        for(; (i < j) && (a[j] == '1'); --j);
        if(i < j) answer++;
    }
    cout << answer << endl;
    return 0;
}

(二)

题目:给定一个字符串,删除里面所有的a,并且复制里面所有的b,注意:字符串数组足够大。

方法:所有的操作都在原先的字符床上进行,在删除a的过程中记录下字符b的个数,然后在复制b的时候,为了减小复杂度,采用倒着复制的方法。

代码:

#include <iostream>
#include <cstdio>
#include <string>

#define MAXN 1000

using namespace std;

int main(int argc, const char * argv[]) {
    char str[MAXN];
    scanf("%s", str);
    int n = 0, numb = 0;
    for(int i = 0; str[i]; ++i) {
        if(str[i] != 'a') str[n++] = str[i];
        if(str[i] == 'b') numb++;
    }
    str[n] = '\0';
    int newLength = n + numb;
    str[newLength] = '\0';
    for(int i = newLength - 1, j = n - 1; j >= 0; --j) {
        str[i--] = str[j];
        if(str[j] == 'b') str[i--] = 'b';
    }
    printf("%s\n", str);
    return 0;
}

(三)

题目:给定一个字符串,里面只包含*号还有数字,把*全部放到开头。

方法(1):利用快速排序里面的partition的思想,但是这种方法会使数字的相对位置发生变化,是不稳定的

方法(2):利用前面一个题目的思想,也就是倒着复制的思想。这种方法,算法前跟算法后,数字的相对顺序是不变的,是稳定的。

方法一的代码:

    for(int i = 0, j = 0; i < n; ++i) {
        if(a[i] == '*') swap(a[j++], a[i]);
    }

方法二的代码:

    int j = n-1;
    for(int i = n-1; i >= 0; --i) {
        if(isdigit(s[i])) s[j--] = s[i];
    }
    for(; j >= 0; --j) {
        s[j] = '*';
    }

(四)

题目:单词翻转,意思就是一句英文,然后要让所有单词的顺序倒过来,第一个单词变成最后一个,然后倒数第二个变成顺数第二个。

方法:先针对整个句子,全部翻转一遍,然后再针对翻转后的句子里面的每个单词,分别翻转一次。

代码:

#include <iostream>
#include <cstdio>
#include <string>

#define MAXN 1000

using namespace std;

int main(int argc, const char * argv[]) {
    string  str;
    getline(cin, str);
    int x = 0, y = str.length() - 1;
    while(x < y) swap(str[x++], str[y--]);
    cout << str << endl;
    cout << str.length() << endl;
    for(int i = 0, j = 0; i <= str.length(); ++i) {
        while(str[j] != ' ' && str[j] != '\0') j++;
        j--;
        int n = j;
        while(i < j) swap(str[i++], str[j--]);
        i = n + 1;
        j = n + 2;
    }
    cout << str << endl;
    return 0;
}

(五)

题目:给定一个字符串,长度为n,向右移动m次,然后求移动以后的结果。

方法:不管他们的大小关系,最后的结果都是移动m%n的结果。

     移动前跟移动后是有两段的顺序是不变的,所以可以把这两段看成两个整体

  右移m位的过程就是把数组的两部分交换一下。

交换的过程:(1)逆序排列第一部分

      (2)逆序排列第二部分

      (3)再全部逆序!

代码:

#include <iostream>
#include <cstdio>
#include <string>

#define MAXN 1000

using namespace std;

void swap(char *A, int x, int y) {
    while(x < y) {
        char temp = A[x];
        A[x] = A[y];
        A[y] = temp;
        x++;
        y--;
    }
}

int main(int argc, const char * argv[]) {
    char str[MAXN];
    scanf("%s", str);
    int n, m;
    n = strlen(str);
    cin >> m;
    //向右翻转m位
    swap(str, 0, n-m-1);
    swap(str, n-m, n-1);
    swap(str, 0, n-1);
    cout << str << endl;
    return 0;
}

    原文作者:It_Ds_N_cpp
    原文地址: https://blog.csdn.net/u010470972/article/details/45218055
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞