【面试题004】c/c++字符串,替换空格

一,c/c++字符串

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

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

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.\n");

}

else

{

printf("str1 and str2 are not same\n");

}

if (str3 == str4)

{

printf("str3 and str4 are same.\n");

}

else

{

printf("str3 and str4 are not same.\n");

}

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] != '\0')

{

++ 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.