面试考题之9.1:数组与字符串(C/C++版)
来源:互联网 发布:米尔网 知乎 编辑:程序博客网 时间:2024/05/23 12:21
1.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
#include <cstring> // strlen()
#include <cstdio> // getchar()
using namespace std;
/************************************************************************/
// 函数名称:isUniqueChars_1 (使用字符数组实现)
// 函数目的:判断字符串中所有字符是否全部不同
// 函数参数:str
// 函数返回:true:字符全部不同
// 使用条件:字符集为ASCII
/************************************************************************/
bool isUniqueChars_1(const char* str)
{
if (strlen(str) > 256) return false;
char strFlag[256] = {0};
for (size_t i = 0; i < strlen(str); i++){
int val = *(str + i);
if (!strFlag[val]) strFlag[val] = 1;
else return false;
}
return true;
}
/************************************************************************/
// 函数名称:isUniqueChars_2 (使用位向量实现)
// 函数目的:判断字符串中所有字符是否全部不同
// 函数参数:str
// 函数返回:true:字符全部不同
// 使用条件:字符集为ASCII
/************************************************************************/
bool isUniqueChars_2(const char* str)
{
if (strlen(str) > 256) return false;
char strBit[256/8 + 1] = {0};
for (size_t i = 0; i < strlen(str); i++){
int val = *(str + i);
int index = val / 8;
int mod = val % 8;
if ( (strBit[index] & (1 << mod)) > 0 ){
return false;
}
strBit[index] |= (1 << mod);
}
return true;
}
int main()
{
char str[] = "MyNameisJoh";
char str2[] = "MyNameisJohnnyHu";
cout << str << " is " << (isUniqueChars_1(str) ? "true" : "false") << endl;
cout << str2 << " is " << (isUniqueChars_1(str2) ? "true" : "false") << endl;
cout << str << " is " << (isUniqueChars_2(str) ? "true" : "false") << endl;
cout << str2 << " is " << (isUniqueChars_2(str2) ? "true" : "false") << endl;
getchar();
return 0;
}
思考体会:
1、 是否询问 “字符范围” ?
2、分析及计算(时间\空间)复杂度;
3、如果是Unicode字符该如果处理?
4、其他常规解法: 双for循环、排序等,他们复杂度多少
1.2 用C/C++实现void reverse(char* str)函数,即反转一个null结尾的字符串。
解决方案:
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
#include <cstring> // strlen()
#include <cstdio> // getchar()
using namespace std;
/************************************************************************/
// 函数名称:reverse
// 函数目的:反转一个null结尾的字符串
// 函数参数:str
// 函数返回:无
// 使用条件:
/************************************************************************/
void reverse(char* str)
{
size_t length = strlen(str);
for (size_t i = 0; i < length; i++){
if ( i < length -1 - i ){
char ch = *(str + i);
*(str + i ) = *(str + length -1 - i);
*(str + length -1 - i) = ch;
}
else { return; }
}
return;
}
int main()
{
char str[] = "MyNameisJohnnyHu";
cout << "str = "<< str << endl;
cout << "call reverse() function, The result is:" << endl;
reverse(str);
cout << "str = " << str << endl;
getchar();
return 0;
}
运行结果:
思考体会:
1、如果不使用任何其他函数(比如:strlen)该怎么做?
2、注意对null字符的利用。
1.3 给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。
解决方案:
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
#include <string>
#include <algorithm> // std::sort
using namespace std;
/************************************************************************/
// 函数名称:permutation
// 函数目的:确定两个字符串中字符是否相同(忽略顺序)
// 函数参数:s, t
// 函数返回:true:字符串中字符相同; false:不相同
// 使用条件:
/************************************************************************/
bool permutation(const string& s, const string& t)
{
string ss = s, tt = t;
sort( ss.begin(), ss.end() );
sort( tt.begin(), tt.end() );
return ss == tt;
}
int main()
{
char str[] = "MyNameisJohnnyHu";
char str2[] = "NameisMyHuJohnny";
cout << "str = "<< str << endl;
cout << "str2 = " << str2 << endl;
cout << "call permutation() function, The result is:" << endl;
cout << ( permutation(str, str2) ? "true" : "false" ) << endl;
getchar();
return 0;
}
运行结果:
思考体会:
1、其他方法:可以检查两个字符串中各个字符数是否相同。字符集假设为ASCII。
2、用纯C语言去实现,使用qsort去排序。
2、最此题之前应确认一些细节。
1.4 . 编写一个方法,将字符串中的空格全部替换为“%20”。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。
示例:
输入: "Mr John Smith"
输出:Mr%20John%20Smith“
解决方案:
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
#include <string>
#include <algorithm> // std::replace
using namespace std;
/************************************************************************/
// 函数名称:replaceChars
// 函数目的:确定两个字符串中字符是否相同(忽略顺序)
// 函数参数:str字符串,s原字符子串, t要替换的字符子串
// 函数返回:true:字符串中字符相同; false:不相同
// 使用条件:
/************************************************************************/
string replaceChars(const string& str, const string& s, const string& t)
{
string strNew = str;
while (strNew.find(s) != std::string::npos){
strNew.replace(strNew.find(s),s.length(), t);
}
return strNew;
}
int main()
{
string str;
cout << "Please enter a string: " << endl;
getline(std::cin, str);
cout << "call replaceChars() function, The result is:" << endl;
cout << replaceChars(str, " ", "%20") << endl;
getchar();
return 0;
}
运行结果:
思考体会:
1、用纯cC去怎么完成?
2、其他解法?
1.5 利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。比如,字符串“aabcccccaaa”会变成"a2b1c5a3"。 若“压缩”后的字符串没有变短,则返回原来的字符串。
解决方案:
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
#include <sstream> // std::stringstream
#include <string>
#include <cstdio> // getchar()
using namespace std;
/************************************************************************/
// 函数名称:compressChars
// 函数目的:基本字符串压缩功能
// 函数参数:str要压缩的字符串
// 函数返回:压缩操作过的字符串
// 使用条件:
/************************************************************************/
string compressChars(const string& str)
{
if (str.size() <= 2) return str;
string strPress;
size_t sz = 0;
char ch = str[0];
for (size_t i = 0; i < str.size(); i++){
if (ch == str[i]){
ch = str[i]; sz += 1;
}
else {
stringstream ss; ss << sz; // std::to_string在MinGW下有Bug
strPress += ch + ss.str();
ch = str[i]; sz = 1;
}
if (i == str.size() - 1){
stringstream ss; ss << sz;
strPress += ch + ss.str();
}
}
return ( (strPress.size() < str.size()) ? strPress : str);
}
int main()
{
char str[] = "aaaaabbccdddddeeeefgg";
char str2[] = "MyNameisJohnnyHuuu";
cout << "str = "<< str << " ---->> " << compressChars(str) << endl;
cout << "str2 = "<< str2 << " ---->> " << compressChars(str2) << endl;
getchar();
return 0;
}
运行结果:
思考体会:
1、其他解法?
2、分析(时间/空间)复杂度
1.6 给定一幅由NxN矩阵表示的图像,其中每个像素的大小为4字节,编写一个方法,将图像旋转90度,不占用额外的内存空间能否做到?
解决方案:
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
#include <sstream> // std::stringstream
#include <string>
#include <cstdio> // getchar()
#define N 4
using namespace std;
/************************************************************************/
// 函数名称:rotateMatrix
// 函数目的:顺时针90度转置矩阵
// 函数参数:matrix
// 函数返回:无
// 使用条件:
/************************************************************************/
void rotateMatrix(int matrix[][N], int rows = N)
{
for (size_t layer = 0; layer < rows / 2; ++layer){
size_t first = layer;
size_t last = rows - 1 -layer;
for (size_t i = first; i < last; ++i){
size_t offest = i - first;
// 存储上边
int top = matrix[first][i];
// 左到上
matrix[first][i] = matrix[last - offest][first];
// 下到左
matrix[last - offest][first] = matrix[last][last - offest];
// 右到下
matrix[last][last - offest] = matrix[i][last];
// 上到右
matrix[i][last] = top;
}
}
return;
}
int main()
{
int matrix[N][N] = {
{1, 2, 3, 4 },
{5, 6, 7, 8 },
{9, 10, 11, 12},
{13, 14, 15, 16}
};
cout << "初始矩阵:" << endl;
for (size_t i = 0; i < N; i++){
for (size_t j = 0; j < N; j++){
cout << matrix[i][j] << "\t";
}
cout << endl;
}
rotateMatrix(matrix, N);
cout << "顺时针转置90度后矩阵:" << endl;
for (size_t i = 0; i < N; i++){
for (size_t j = 0; j < N; j++){
cout << matrix[i][j] << "\t";
}
cout << endl;
}
getchar();
return 0;
}
运行结果:
思考体会:
1、该算法是参考的算法,算法设计很精妙,值得研究掌握。
2、本算法从外向内旋转,又如何从内向外旋转?
3、本算法的时间复杂度O(N^2),
1.7 编写一个算法,若MxN矩阵中某个元素为0,则将其所在的行与列清零。
解决方案:
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
#include <sstream> // std::stringstream
#include <string>
#include <cstdio> // getchar()
#define N 4
using namespace std;
/************************************************************************/
// 函数名称:setZero
// 函数目的:把矩阵中元素为0的行/列清零
// 函数参数:matrix
// 函数返回:无
// 使用条件:row <= N
void setZero(int matrix[][N], size_t rows = N)
{
int flag[N][N] = { {0} };
for (size_t row = 0; row < rows; row++){
for (size_t col = 0; col < N; col++)
if (matrix[row][col] == 0) flag[row][col] = 1;
}
// 行/列清零
for (size_t row = 0; row < rows; row++){
for (size_t col = 0; col < N; col++)
if (flag[row][col] == 1) {
for (size_t c = 0; c < N; c++) matrix[row][c] = 0;
for (size_t r = 0; r < rows; r++) matrix[r][col] = 0;
}
}
return;
}
int main()
{
int matrix[N][N] = {
{1, 2, 3, 4 },
{5, 0, 7, 8 },
{9, 0, 11, 12},
{13, 14, 15, 16}
};
cout << "初始矩阵:" << endl;
for (size_t i = 0; i < N; i++){
for (size_t j = 0; j < N; j++){
cout << matrix[i][j] << "\t";
}
cout << endl;
}
setZero(matrix, N);
cout << "调用setZero后:" << endl;
for (size_t i = 0; i < N; i++){
for (size_t j = 0; j < N; j++){
cout << matrix[i][j] << "\t";
}
cout << endl;
}
getchar();
return 0;
}
运行结果:
思考体会:
1、注意题设的陷阱。
2、计算时间空间复杂度。
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
#include <string>
#include <cstdio> // getchar()
using namespace std;
/************************************************************************/
// 函数名称:isRotation_2
// 函数目的:判断字符串是否是转换字符串
// 函数参数:s1 s2
// 函数返回:true:是转置字符串
// 使用条件:
/************************************************************************/
bool isRotation_2(const string& s1, const string& s2)
{
size_t len = s1.length();
if (len == s2.length() && len > 0){
string s1s1 = s1 + s1; // the key point
size_t found = s1s1.find(s2);
if ( found != std::string::npos ) return true;
}
return false;
}
int main()
{
char s1[] = "waterbottle";
char s2[] = "erbottlewat";
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "调用转换字符函数isRotation_2()判断之后:" << endl;
cout << (isRotation_2(s1, s2) ? "true" : "false") << endl;
getchar();
return 0;
}
- 面试考题之9.1:数组与字符串(C/C++版)
- 面试考题之9.2:链表(C/C++版)
- C++ 面试常考题
- C#—考题字符串2
- 小小C语言之数组与字符串
- C:数组与字符串
- C数组与字符串
- C/C++面试总结必考题
- C/C++面试总结必考题 2
- c语言面试之字符串
- C考题
- C语言--数组与字符串
- c语言数组与字符串
- C字符数组与字符串
- C语言 数组与字符串
- Object-c字符串与数组
- Objective-C字符串与数组
- Linux c --- 数组与字符串
- Unable to resolve address ' ' service ' ': Name or service not known
- MySql 与C# 乱码问题处理
- iframe自适应(去除滚动条)
- 读stalendp文章的笔记之【Shader实例分析(一)-Wave】
- 关于ECSHOP模板架设的服务器php版本过高报错的解决方法集合
- 面试考题之9.1:数组与字符串(C/C++版)
- Spark学习之15:Spark Streaming执行流程(1)
- ubuntu中解决android studio 不能输入中文
- 旋转数组的最小数字
- 关键字:linux,Kill,多个进程kill
- jQuery下通过$.browser来判断浏览器
- Spring下载地址
- IBATIS两种in查询
- 烧写Openwrt固件