zoukankan      html  css  js  c++  java
  • 【面试题004】c/c++字符串,替换空格

     

    一,c/c++字符串

    1.C/C++中每个字符串都以字符’‘作为结尾,这样我们就能很方便地找到字符串的最后尾部。

    由于这个原因每个字符串都有一个额外的开销,注意字符串越界的问题;

    2.C/C++内存模型把字符串常量放到单独的一个内存区域;

    当几个指针指向相同的字符串常量的时候,他们实际上会指向常量区那个的内存地址;

    但是用字符串常量初始化数组,情况却不一样,这点很重要,考察你C能力的筹码;

    test.c:

    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
     
    #include <stdio.h>

    int main()
    {
        char str1[] = "hello world";
        char str2[] = "hello world";

        char *str3 = "hello boy";
        char *str4 = "hello boy";

        if(str1 == str2)
        {
            printf("str1 and str2 are same. ");
        }
        else
        {
            printf("str1 and str2 are not same ");
        }

        if (str3 == str4)
        {
            printf("str3 and str4 are same. ");
        }
        else
        {
            printf("str3 and str4 are not same. ");
        }
        return 0;
    }

     

    运行结果:

    str1 and str2 are not same
    str3 and str4 are same.

     

    Makefile:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    .PHONY:clean  
    CC=gcc  
    CFLAGS=-Wall -g  
    BIN=test  
    OBJS=test.o  
    LIBS=  
    $(BIN):$(OBJS)  
        $(CC) $(CFLAGS) $^ -o $@ $(LIBS)  
    %.o:%.c  
        $(CC) $(CFLAGS) -c $< -o $@  
    clean:  
        rm -f *.o $(BIN)  

     

    str1和str2是两个字符串数组,我们会为他们分配两个长度为12个字节的空间(在栈区),

    并且把常量区的“hello world”的内容分别拷贝的数组当中。

    这是两个初始地址不同的数组;

    str3和str4是两个指针,我们无须为她们分配内存来存储字符串的内容,而只需要把他们指向“hello boy”在常量区中的地址就可以了,“hello world”这个字符串常量在内存中只有一个拷贝,因此str3与str4的值是一样的。

     

    二,替换空格

    给定字符串中的空格替换成 ’%20‘

    思路就是计算出替换后的字符串的长度,利用两个指针,一个指向就字符串的末尾一个指向新字符串的末尾

    进而从后往前面遍历,这样子节约时间,移位的效率高,因为没有做多余的移位操作;

    space.cpp:

     C++ Code 
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    #include <iostream>
    #include <cstring>
    #include <cstdio>

    using namespace std;

    /*length 为字符数组string的总的容量*/
    void ReplaceBlank(char string[], int length)
    {

        if(string == NULL && length <= 0)
        {
            return;
        }

        /*originalLength为字符串string的实际长度*/
        int originalLength = 0;
        int numberOfBlank = 0;
        int i = 0;
        while(string[i] != '')
        {
            ++ originalLength;

            if(string[i] == ' ')
            {
                ++ numberOfBlank;
            }

            ++ i;
        }

        /*newLength为把空格替换成‘%20’后的长度*/
        int newLength = originalLength + numberOfBlank * 2;
        if (newLength > length)
        {
            return ;
        }

        int indexOforiginal = originalLength;
        int indexOfNew = newLength;
        while(indexOforiginal >= 0 && indexOfNew > indexOforiginal)
        {
            if(string[indexOforiginal] == ' ')
            {
                string[indexOfNew --] = '0';
                string[indexOfNew --] = '2';
                string[indexOfNew --] = '%';
            }
            else
            {
                string[indexOfNew --] = string[indexOforiginal];
            }
            -- indexOforiginal;
        }

    }

    void Test(char *testName, char string[], int length, char expected[])
    {
        if(testName != NULL)
            printf("%s begins: ", testName);

        ReplaceBlank(string, length);

        if(expected == NULL && string == NULL)
        {
            cout << "passed." << endl;
        }
        else if(expected == NULL && string != NULL)
        {
            cout << "failed." << endl;
        }
        else if(strcmp(string, expected) == 0)
        {
            cout << "passed." << endl;
        }
        else
        {
            cout << "failed." << endl;
        }
    }

    int main()
    {
        const int length = 100;

        char string[length] = "hello world";
        char expected[] = "hello%20world";

        ReplaceBlank(string, length);

        if(strcmp(string, expected) == 0)
        {
            cout << "passed." << endl;
        }
        else
        {
            cout << "failed." << endl;
        }

        return 0;
    }

    运行结果:

    passed.  

     

    Makefile:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    .PHONY:clean  
    CPP=g++  
    CFLAGS=-Wall -g  
    BIN=test  
    OBJS=space.o  
    LIBS=  
    $(BIN):$(OBJS)  
        $(CPP) $(CFLAGS) $^ -o $@ $(LIBS)  
    %.o:%.cpp  
        $(CPP) $(CFLAGS) -c $< -o $@  
    clean:  
        rm -f *.o $(BIN)Test1 begins: passed.  
  • 相关阅读:
    [编程题] 数组中重复的数字
    [编程题] 用两个栈实现队列
    杜教筛学习笔记
    二次剩余学习小记
    Burnside引理和Polya定理简单入门
    6553. 【GDOI2020模拟4.11】人生
    6545. 【GDOI2020模拟4.8】 Exercise
    2020.4.5学军信友队趣味网络邀请赛总结
    51 Nod 1287 加农炮(单调队列思想+二分)
    51 Nod 1070 Bash游戏v4(斐波那契博弈)
  • 原文地址:https://www.cnblogs.com/codemylife/p/3660036.html
Copyright © 2011-2022 走看看