2025.12.02 C语言程序设计上机实习五

2025.11.11 C语言程序设计上机实习五

必做题

image-20251202190228897

选做题

题目源文件实验五.pdf

题目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
int FindSubstring(const char* str, const char* substr)
{
if (!str || !substr) return -1;

int n = strlen(str);
int m = strlen(substr);

if (m == 0) return 0;

for (int i = 0; i <= n - m; i++)
{
int j = 0;
while (j < m && str[i + j] == substr[j])
{
j++;
}
if (j == m)
{
return 1;
}
}

return 0;
}

image-20251202210831577

题目2:字符串替换函数

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
// 字符串替换函数实现
char* ReplaceAll(const char* original, const char* target, const char* replacement)
{
// 检查参数是否为空
if (original == NULL || target == NULL || replacement == NULL)
{
return NULL;
}

// 计算各字符串长度
int orig_len = strlen(original);
int target_len = strlen(target);
int repl_len = strlen(replacement);

// 如果目标字符串为空,返回原字符串的副本
if (target_len == 0)
{
char* result = (char*)malloc((orig_len + 1)*sizeof(char));

if (result == NULL)
{
return NULL;
}

strcpy(result, original);
result[orig_len] = '\0';
return result;
}

// 计算需要替换的次数
int count = 0;
const char* pos = original;

while ((pos = strstr(pos, target)) != NULL) // strstr的用法在课本P486
{
count++;
pos += target_len; // 跳过已找到的目标字符串
}

// 计算新字符串长度
int new_len = orig_len + count * (repl_len - target_len);
char* result = (char*)malloc((new_len + 1)*sizeof(char));

if (result == NULL)
{
return NULL;
}

// 执行替换操作
char* current = result;
const char* start = original;
const char* found;

while ((found = strstr(start, target)) != NULL)
{
// 复制目标字符串之前的部分
int prefix_len = found - start;
if (prefix_len > 0)
{
strncpy(current, start, prefix_len);
current += prefix_len;
}

// 复制替换字符串
if (repl_len > 0)
{
strcpy(current, replacement);
current += repl_len;
}

// 移动到下一个位置
start = found + target_len;
}

// 复制剩余部分
strcpy(current, start);
result[new_len] = '\0';
return result;
}

修改部分:

  • malloc用法,长度*sizeof(类型)
  • strcpy复制位置(原有-1删去)(两处)
  • result字符串末尾要加 ‘\0’ (两处)
  • (无用)加入 repl_len > 0 判断

image-20251202210911428

题目3:回文单词检测函数

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
int HasPalindromeWord(const char* sentence)
{
if (sentence == NULL)
return -1; // 传空参数处理

const char* p = sentence;
while (*p) {

while (*p && !isalnum(*p)) // 字母与数字可过,略过字符
{
p++;
}

if (*p == '\0') // 如果因为上一个while跳到结尾了就该抓紧终止了
{
break;
}

const char* start = p;

while (*p && isalnum(*p)) // 来个字母和数字作为起点,读到不是字母和数字和'\0'就停
{
p++;
}
const char* end = p;

unsigned int len = end - start;
if (len >= 2) {
size_t i = 0, j = len - 1;
int is_pal = 1;
while (i < j) {
char a = (char)tolower(start[i]);
char b = (char)tolower(start[j]);
if (a != b)
{
is_pal = 0;
break;
}
i++;
j--;
}
if (is_pal)
return 1;
}
}

return 0;
}

image-20251202210951504

题目4:礼貌数判断函数(被放弃的期中考试题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int IsPoliteNumber(int n)
{
int test = n, sum = 0;
for (int i = 1; i <= test; i++)
{
for (int j = i; j < test; j++)
{
sum += j;
if (sum == test)
{
return 1;
}
else if (sum > test)
{
break;
}
}
sum = 0;
}
return 0;
}

image-20251202211032319

题目5:矩阵转置函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int** TransMat(int** matrix, int m, int n)
{
int **arr;
arr = (int **)malloc(n * sizeof(int *));
for(int i = 0; i < n; i++)
{
arr[i] = (int *)malloc(m * sizeof(int));
if(arr[i] == NULL)
return NULL;
for(int j = 0; j < m; j++)
{
arr[i][j] = matrix[j][i];
}
}
return arr;
}

image-20251202211104822

附:完整代码

TestFindSubstr.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
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
103
104
105
106
#include <stdio.h>
#include <string.h>

// 字符串查找函数声明
int FindSubstring(const char* str, const char* substr);
// 测试函数
void run_tests();

int main() {
run_tests();
return 0;
}

// 测试函数
void run_tests()
{
printf("=== 字符串查找函数测试 ===\n\n");

int pass_count = 0;
int total_count = 0;

// 测试用例1:正常情况
printf("测试1: 正常查找\n");
int result1 = FindSubstring("Hello world", "world");
int expected1 = 1;
printf(" 输入: str=\"Hello world\", substr=\"world\"\n");
printf(" 预期: %d, 实际: %d - %s\n", expected1, result1,
result1 == expected1 ? "通过" : "失败");
if (result1 == expected1)
pass_count++;
total_count++;

// 测试用例2:不存在的情况
printf("\n测试2: 子串不存在\n");
int result2 = FindSubstring("Hello world", "test");
int expected2 = 0;
printf(" 输入: str=\"Hello world\", substr=\"test\"\n");
printf(" 预期: %d, 实际: %d - %s\n", expected2, result2,
result2 == expected2 ? "通过" : "失败");
if (result2 == expected2)
pass_count++;
total_count++;

// 测试用例3:部分匹配但最后一个字符不匹配
printf("\n测试3: 部分匹配(最后一个字符不匹配)\n");
int result3 = FindSubstring("hello world", "hella");
int expected3 = 0;
printf(" 输入: str=\"hello world\", substr=\"hella\"\n");
printf(" 预期: %d, 实际: %d - %s\n", expected3, result3,
result3 == expected3 ? "通过" : "失败");
if (result3 == expected3)
pass_count++;
total_count++;

// 测试用例4:开头匹配
printf("\n测试4: 子串在开头\n");
int result4 = FindSubstring("hello world", "hello");
int expected4 = 1;
printf(" 输入: str=\"hello world\", substr=\"hello\"\n");
printf(" 预期: %d, 实际: %d - %s\n", expected4, result4,
result4 == expected4 ? "通过" : "失败");
if (result4 == expected4)
pass_count++;
total_count++;

// 测试用例5:结尾匹配
printf("\n测试5: 子串在结尾\n");
int result5 = FindSubstring("hello world", "world");
int expected5 = 1;
printf(" 输入: str=\"hello world\", substr=\"world\"\n");
printf(" 预期: %d, 实际: %d - %s\n", expected5, result5,
result5 == expected5 ? "通过" : "失败");
if (result5 == expected5)
pass_count++;
total_count++;

// 汇总结果
printf("\n=== 测试结果 ===\n");
printf("通过: %d/%d (%.1f%%)\n", pass_count, total_count,
(float)pass_count/total_count*100);
}

int FindSubstring(const char* str, const char* substr)
{
if (!str || !substr) return -1;

int n = strlen(str);
int m = strlen(substr);

if (m == 0) return 0;

for (int i = 0; i <= n - m; i++)
{
int j = 0;
while (j < m && str[i + j] == substr[j])
{
j++;
}
if (j == m)
{
return 1;
}
}

return 0;
}

TestReplaceAll.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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 函数原型声明
char* ReplaceAll(const char* original, const char* target, const char* replacement);
int StringsEqual(const char* str1, const char* str2);
void RunTests();
void TestMemoryLeak();

int main()
{
RunTests();
TestMemoryLeak();

printf("\n按任意键退出...");
getchar();

return 0;
}

// 辅助函数:比较两个字符串是否相等
int StringsEqual(const char* str1, const char* str2)
{
if (str1 == NULL && str2 == NULL)
{
return 1;
}

if (str1 == NULL || str2 == NULL)
{
return 0;
}

return strcmp(str1, str2) == 0;
}

// 测试函数
void RunTests()
{
printf("=== 字符串替换函数测试 ===\n\n");

int pass_count = 0;
int total_count = 0;
char* result = NULL;
char* expected = NULL;

// 测试用例1:正常情况 - 单次替换
printf("测试1: 正常替换(单次出现)\n");
result = ReplaceAll("I like apples", "apples", "oranges");
expected = "I like oranges";
printf(" 输入: original=\"I like apples\", target=\"apples\", replacement=\"oranges\"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 测试用例2:多次替换
printf("\n测试2: 多次替换\n");
result = ReplaceAll("I like apples, apples are delicious.", "apples", "oranges");
expected = "I like oranges, oranges are delicious.";
printf(" 输入: original=\"I like apples, apples are delicious.\", target=\"apples\", replacement=\"oranges\"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 测试用例3:目标子串不存在
printf("\n测试3: 目标子串不存在\n");
result = ReplaceAll("I like apples", "bananas", "oranges");
expected = "I like apples";
printf(" 输入: original=\"I like apples\", target=\"bananas\", replacement=\"oranges\"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 测试用例4:原始字符串为空
printf("\n测试4: 原始字符串为空\n");
result = ReplaceAll("", "apples", "oranges");
expected = "";
printf(" 输入: original=\"\", target=\"apples\", replacement=\"oranges\"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 测试用例5:替换为空字符串(删除操作)
printf("\n测试5: 替换为空字符串(删除)\n");
result = ReplaceAll("Hello World", "o", "");
expected = "Hell Wrld";
printf(" 输入: original=\"Hello World\", target=\"o\", replacement=\"\"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 测试用例6:连续出现目标子串(重点测试)
printf("\n测试6: 连续出现目标子串\n");
result = ReplaceAll("aaaa", "aa", "b");
expected = "bb";
printf(" 输入: original=\"aaaa\", target=\"aa\", replacement=\"b\"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 测试用例7:特殊字符
printf("\n测试7: 特殊字符\n");
result = ReplaceAll("a-b-c-d", "-", " ");
expected = "a b c d";
printf(" 输入: original=\"a-b-c-d\", target=\"-\", replacement=\" \"\n");
printf(" 预期: \"%s\"\n", expected);
printf(" 实际: \"%s\"\n", result ? result : "NULL");
printf(" 结果: %s\n", StringsEqual(result, expected) ? "通过" : "失败");

if (StringsEqual(result, expected))
{
pass_count++;
}
total_count++;
result = NULL;

// 汇总结果
printf("\n=== 测试结果 ===\n");
printf("通过: %d/%d (%.1f%%)\n", pass_count, total_count,
(float)pass_count / total_count * 100);

if (pass_count == total_count)
{
printf("所有测试通过!\n");
}
else
{
printf("有 %d 个测试失败\n", total_count - pass_count);
}
}

// 内存泄漏检查辅助函数
void TestMemoryLeak()
{
printf("\n=== 内存泄漏检查 ===\n");

// 测试多次替换,检查是否有内存泄漏
char* results[3];

results[0] = ReplaceAll("test test test", "test", "TEST");
results[1] = ReplaceAll("hello world", "hello", "Hi");
results[2] = ReplaceAll("a b c d", " ", "");

printf("替换结果:\n");

for (int i = 0; i < 3; i++)
{
printf(" 结果%d: %s\n", i + 1, results[i] ? results[i] : "NULL");
free(results[i]); // 正确释放内存
results[i] = NULL;
}

printf("若results均能正常输出,则释放基本正确\n");
}

// 字符串替换函数实现
char* ReplaceAll(const char* original, const char* target, const char* replacement)
{
// 检查参数是否为空
if (original == NULL || target == NULL || replacement == NULL)
{
return NULL;
}

// 计算各字符串长度
int orig_len = strlen(original);
int target_len = strlen(target);
int repl_len = strlen(replacement);

// 如果目标字符串为空,返回原字符串的副本
if (target_len == 0)
{
char* result = (char*)malloc((orig_len + 1)*sizeof(char));

if (result == NULL)
{
return NULL;
}

strcpy(result, original);
result[orig_len] = '\0';
return result;
}

// 计算需要替换的次数
int count = 0;
const char* pos = original;

while ((pos = strstr(pos, target)) != NULL) // strstr的用法在课本P486
{
count++;
pos += target_len; // 跳过已找到的目标字符串
}

// 计算新字符串长度
int new_len = orig_len + count * (repl_len - target_len);
char* result = (char*)malloc((new_len + 1)*sizeof(char));

if (result == NULL)
{
return NULL;
}

// 执行替换操作
char* current = result;
const char* start = original;
const char* found;

while ((found = strstr(start, target)) != NULL)
{
// 复制目标字符串之前的部分
int prefix_len = found - start;
if (prefix_len > 0)
{
strncpy(current, start, prefix_len);
current += prefix_len;
}

// 复制替换字符串
if (repl_len > 0)
{
strcpy(current, replacement);
current += repl_len;
}

// 移动到下一个位置
start = found + target_len;
}

// 复制剩余部分
strcpy(current, start);
result[new_len] = '\0';
return result;
}

TestPalindromeWord.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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

// 函数原型声明
int HasPalindromeWord(const char* sentence);
void RunTests();

int main()
{
RunTests();
printf("\n按任意键退出...");
getchar();
return 0;
}

// 测试函数
void RunTests()
{
printf("=== 回文单词检测函数测试 ===\n\n");

int pass_count = 0;
int total_count = 0;
int result = 0;

// 测试用例1:包含回文单词
printf("测试1: 包含回文单词\n");
result = HasPalindromeWord("Madam,this is a test.");
printf(" 输入: \"Madam,this is a test.\"\n");
printf(" 预期: 1 (Madam是回文)\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例2:不包含回文单词
printf("\n测试2: 不包含回文单词\n");
result = HasPalindromeWord("Hello world,this is a test.");
printf(" 输入: \"Hello world,this is a test.\"\n");
printf(" 预期: 0\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 0 ? "通过" : "失败");

if (result == 0) pass_count++;
total_count++;

// 测试用例3:多个回文单词
printf("\n测试3: 多个回文单词\n");
result = HasPalindromeWord("mem level");
printf(" 输入: \"mem level\"\n");
printf(" 预期: 1\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例4:空句子
printf("\n测试4: 空句子\n");
result = HasPalindromeWord("");
printf(" 输入: \"\"\n");
printf(" 预期: 0\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 0 ? "通过" : "失败");

if (result == 0) pass_count++;
total_count++;

// 测试用例5:只有标点符号
printf("\n测试5: 只有标点符号\n");
result = HasPalindromeWord("!@#$%^&*()");
printf(" 输入: \"!@#$%%^&*()\"\n");
printf(" 预期: 0\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 0 ? "通过" : "失败");

if (result == 0) pass_count++;
total_count++;

// 测试用例6:单个回文单词
printf("\n测试6: 单个回文单词\n");
result = HasPalindromeWord("racecar");
printf(" 输入: \"racecar\"\n");
printf(" 预期: 1\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例7:混合大小写的回文
printf("\n测试7: 混合大小写的回文\n");
result = HasPalindromeWord("LeVel is important");
printf(" 输入: \"LeVel is important\"\n");
printf(" 预期: 1 (Level是回文)\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例8:数字和字母混合
printf("\n测试8: 数字和字母混合\n");
result = HasPalindromeWord("This is 12321 number");
printf(" 输入: \"This is 12321 number\"\n");
printf(" 预期: 1 (12321是回文)\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 汇总结果
printf("\n=== 测试结果 ===\n");
printf("通过: %d/%d (%.1f%%)\n", pass_count, total_count,
(float)pass_count / total_count * 100);

if (pass_count == total_count)
{
printf("所有测试通过!\n");
}
else
{
printf("有 %d 个测试失败\n", total_count - pass_count);
}
}

int HasPalindromeWord(const char* sentence)
{
if (sentence == NULL)
return -1; // 传空参数处理

const char* p = sentence;
while (*p) {

while (*p && !isalnum(*p)) // 字母与数字可过,略过字符
{
p++;
}

if (*p == '\0') // 如果因为上一个while跳到结尾了就该抓紧终止了
{
break;
}

const char* start = p;

while (*p && isalnum(*p)) // 来个字母和数字作为起点,读到不是字母和数字和'\0'就停
{
p++;
}
const char* end = p;

unsigned int len = end - start;
if (len >= 2) {
size_t i = 0, j = len - 1;
int is_pal = 1;
while (i < j) {
char a = (char)tolower(start[i]);
char b = (char)tolower(start[j]);
if (a != b)
{
is_pal = 0;
break;
}
i++;
j--;
}
if (is_pal)
return 1;
}
}

return 0;
}

TestPoliteNumber.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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 函数原型声明
int IsPoliteNumber(int n);
void RunTests();

int main()
{
RunTests();
printf("\n按任意键退出...");
getchar();
return 0;
}

// 测试函数
void RunTests()
{
printf("=== 礼貌数判断函数测试(必须使用循环实现) ===\n\n");
printf("注意:本题必须使用循环方法实现,直接使用2的幂判断将不予通过!\n\n");

int pass_count = 0;
int total_count = 0;
int result = 0;
clock_t start, end;
double cpu_time_used;

// 测试用例1:明显的礼貌数
printf("测试1: 明显的礼貌数\n");
result = IsPoliteNumber(9); // 9 = 4+5 或 2+3+4
printf(" 输入: 9\n");
printf(" 预期: 1\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例2:2的幂次方(非礼貌数)
printf("\n测试2: 2的幂次方(非礼貌数)\n");
result = IsPoliteNumber(8); // 8 = 2^3
printf(" 输入: 8\n");
printf(" 预期: 0\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 0 ? "通过" : "失败");

if (result == 0) pass_count++;
total_count++;

// 测试用例3:边界值1
printf("\n测试3: 边界值1\n");
result = IsPoliteNumber(1);
printf(" 输入: 1\n");
printf(" 预期: 0(不能表示为两个或更多连续正整数之和)\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 0 ? "通过" : "失败");

if (result == 0) pass_count++;
total_count++;

// 测试用例4:边界值3
printf("\n测试4: 边界值3\n");
result = IsPoliteNumber(3);
printf(" 输入: 3\n");
printf(" 预期: 1(3=1+2)\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例5:较大的礼貌数
printf("\n测试5: 较大的礼貌数\n");
result = IsPoliteNumber(15); // 15=7+8 或 4+5+6 或 1+2+3+4+5
printf(" 输入: 15\n");
printf(" 预期: 1\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例6:质数(通常是礼貌数,除了2)
printf("\n测试6: 质数(礼貌数)\n");
result = IsPoliteNumber(7); // 7=3+4
printf(" 输入: 7\n");
printf(" 预期: 1\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 1 ? "通过" : "失败");

if (result == 1) pass_count++;
total_count++;

// 测试用例7:较大的2的幂次方
printf("\n测试7: 较大的2的幂次方\n");
result = IsPoliteNumber(32); // 32=2^5
printf(" 输入: 32\n");
printf(" 预期: 0\n");
printf(" 实际: %d\n", result);
printf(" 结果: %s\n", result == 0 ? "通过" : "失败");

if (result == 0) pass_count++;
total_count++;

// 测试用例8:大数测试 - 礼貌数
printf("\n测试8: 大数测试 - 礼貌数\n");
start = clock();
result = IsPoliteNumber(1000000); // 1000000是礼貌数
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC * 1000; // 转换为毫秒

printf(" 输入: 1000000\n");
printf(" 预期: 1\n");
printf(" 实际: %d\n", result);
printf(" 运行时间: %.2f 毫秒\n", cpu_time_used);

// 检查结果和运行时间
int time_check = (cpu_time_used > 0.1); // 运行时间应大于0.1毫秒
int result_check = (result == 1);

if (result_check && time_check)
{
printf(" 结果: 通过(结果正确且使用了循环)\n");
pass_count++;
}
else if (result_check && !time_check)
{
printf(" 结果: 失败(结果正确但运行时间过短,可能使用了直接判断)\n");
}
else
{
printf(" 结果: 失败(结果错误)\n");
}
total_count++;

// 测试用例9:大数测试 - 非礼貌数
printf("\n测试9: 大数测试 - 非礼貌数\n");
start = clock();
result = IsPoliteNumber(1048576); // 1048576=2^20,不是礼貌数
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC * 1000; // 转换为毫秒

printf(" 输入: 1048576\n");
printf(" 预期: 0\n");
printf(" 实际: %d\n", result);
printf(" 运行时间: %.2f 毫秒\n", cpu_time_used);

// 检查结果和运行时间
time_check = (cpu_time_used > 0.1); // 运行时间应大于0.1毫秒
result_check = (result == 0);

if (result_check && time_check)
{
printf(" 结果: 通过(结果正确且使用了循环)\n");
pass_count++;
}
else if (result_check && !time_check)
{
printf(" 结果: 失败(结果正确但运行时间过短,可能使用了直接判断)\n");
}
else
{
printf(" 结果: 失败(结果错误)\n");
}
total_count++;

// 汇总结果
printf("\n=== 测试结果 ===\n");
printf("通过: %d/%d (%.1f%%)\n", pass_count, total_count,
(float)pass_count / total_count * 100);

if (pass_count == total_count)
{
printf("所有测试通过!\n");
}
else
{
printf("有 %d 个测试失败\n", total_count - pass_count);
}

// 特别说明
if (pass_count >= 7 && pass_count < total_count)
{
printf("\n注意:部分测试失败可能是因为使用了直接判断方法(检查2的幂次方)。\n");
printf("本题要求必须使用循环实现,请检查您的实现方法。\n");
}
}

int IsPoliteNumber(int n)
{
int test = n, sum = 0;
for (int i = 1; i <= test; i++)
{
for (int j = i; j < test; j++)
{
sum += j;
if (sum == test)
{
return 1;
}
else if (sum > test)
{
break;
}
}
sum = 0;
}
return 0;
}

TestMatrixTranspose.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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#include <stdio.h>
#include <stdlib.h>

// 函数原型声明
int** TransMat(int** matrix, int m, int n);
int** CreateMatrix(int m, int n);
void FreeMatrix(int** matrix, int m);
void PrintMatrix(int** matrix, int m, int n);
int CompareMatrices(int** mat1, int m1, int n1, int** mat2, int m2, int n2);
void RunTests();

int main()
{
RunTests();
printf("\n测试完成,按任意键退出...");
getchar();
return 0;
}

// 创建指定大小的矩阵并填充测试数据
int** CreateMatrix(int m, int n)
{
if (m <= 0 || n <= 0) return NULL;

int** matrix = (int**)malloc(m * sizeof(int*));
if (matrix == NULL) return NULL;

for (int i = 0; i < m; i++)
{
matrix[i] = (int*)malloc(n * sizeof(int));
if (matrix[i] == NULL)
{
// 分配失败,释放已分配的内存
for (int j = 0; j < i; j++)
{
free(matrix[j]);
}
free(matrix);
return NULL;
}

// 填充测试数据:matrix[i][j] = i * n + j + 1
for (int j = 0; j < n; j++)
{
matrix[i][j] = i * n + j + 1;
}
}

return matrix;
}

// 释放矩阵内存
void FreeMatrix(int** matrix, int m)
{
if (matrix == NULL) return;

for (int i = 0; i < m; i++)
{
free(matrix[i]);
}
free(matrix);
}

// 打印矩阵
void PrintMatrix(int** matrix, int m, int n)
{
if (matrix == NULL)
{
printf("矩阵为空\n");
return;
}

for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%4d", matrix[i][j]);
}
printf("\n");
}
}

// 比较两个矩阵是否相等
int CompareMatrices(int** mat1, int m1, int n1, int** mat2, int m2, int n2)
{
if (m1 != m2 || n1 != n2) return 0;
if (mat1 == NULL || mat2 == NULL) return 0;

for (int i = 0; i < m1; i++)
{
for (int j = 0; j < n1; j++)
{
if (mat1[i][j] != mat2[i][j])
{
return 0;
}
}
}
return 1;
}

// 测试函数
void RunTests()
{
printf("=== 矩阵转置函数测试 ===\n\n");

int pass_count = 0;
int total_count = 0;

// 测试用例1:2x3矩阵转置
printf("测试1: 2x3矩阵转置\n");
int** original1 = CreateMatrix(2, 3);
printf("原始矩阵(2x3):\n");
PrintMatrix(original1, 2, 3);

int** result1 = TransMat(original1, 2, 3);
printf("转置结果(3x2):\n");
PrintMatrix(result1, 3, 2);

// 验证结果:创建期望的转置矩阵
int** expected1 = CreateMatrix(3, 2);
if (expected1 != NULL)
{
expected1[0][0] = 1; expected1[0][1] = 4;
expected1[1][0] = 2; expected1[1][1] = 5;
expected1[2][0] = 3; expected1[2][1] = 6;
}

int test1_pass = CompareMatrices(result1, 3, 2, expected1, 3, 2);
printf("结果: %s\n\n", test1_pass ? "通过" : "失败");

if (test1_pass) pass_count++;
total_count++;

// 释放内存
FreeMatrix(original1, 2);
FreeMatrix(result1, 3);
FreeMatrix(expected1, 3);

// 测试用例2:1x1矩阵转置
printf("测试2: 1x1矩阵转置\n");
int** original2 = CreateMatrix(1, 1);
printf("原始矩阵(1x1):\n");
PrintMatrix(original2, 1, 1);

int** result2 = TransMat(original2, 1, 1);
printf("转置结果(1x1):\n");
PrintMatrix(result2, 1, 1);

int test2_pass = (result2 != NULL) && (result2[0][0] == original2[0][0]);
printf("结果: %s\n\n", test2_pass ? "通过" : "失败");

if (test2_pass) pass_count++;
total_count++;

// 释放内存
FreeMatrix(original2, 1);
FreeMatrix(result2, 1);

// 测试用例3:3x1矩阵转置(列向量)
printf("测试3: 3x1矩阵转置(列向量)\n");
int** original3 = CreateMatrix(3, 1);
printf("原始矩阵(3x1):\n");
PrintMatrix(original3, 3, 1);

int** result3 = TransMat(original3, 3, 1);
printf("转置结果(1x3):\n");
PrintMatrix(result3, 1, 3);

// 验证结果
int test3_pass = 1;
if (result3 != NULL)
{
test3_pass = (result3[0][0] == 1) && (result3[0][1] == 2) && (result3[0][2] == 3);
}
else
{
test3_pass = 0;
}
printf("结果: %s\n\n", test3_pass ? "通过" : "失败");

if (test3_pass) pass_count++;
total_count++;

// 释放内存
FreeMatrix(original3, 3);
FreeMatrix(result3, 1);

// 测试用例4:1x4矩阵转置(行向量)
printf("测试4: 1x4矩阵转置(行向量)\n");
int** original4 = CreateMatrix(1, 4);
printf("原始矩阵(1x4):\n");
PrintMatrix(original4, 1, 4);

int** result4 = TransMat(original4, 1, 4);
printf("转置结果(4x1):\n");
PrintMatrix(result4, 4, 1);

// 验证结果
int test4_pass = 1;
if (result4 != NULL)
{
test4_pass = (result4[0][0] == 1) && (result4[1][0] == 2) &&
(result4[2][0] == 3) && (result4[3][0] == 4);
}
else
{
test4_pass = 0;
}
printf("结果: %s\n\n", test4_pass ? "通过" : "失败");

if (test4_pass) pass_count++;
total_count++;

// 释放内存
FreeMatrix(original4, 1);
FreeMatrix(result4, 4);

// 测试用例5:方阵转置(3x3)
printf("测试5: 3x3方阵转置\n");
int** original5 = CreateMatrix(3, 3);
printf("原始矩阵(3x3):\n");
PrintMatrix(original5, 3, 3);

int** result5 = TransMat(original5, 3, 3);
printf("转置结果(3x3):\n");
PrintMatrix(result5, 3, 3);

// 验证方阵转置:对角线不变,其他元素对称交换
int test5_pass = 1;
if (result5 != NULL)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (result5[i][j] != original5[j][i])
{
test5_pass = 0;
break;
}
}
if (!test5_pass) break;
}
}
else
{
test5_pass = 0;
}
printf("结果: %s\n\n", test5_pass ? "通过" : "失败");

if (test5_pass) pass_count++;
total_count++;

// 释放内存
FreeMatrix(original5, 3);
FreeMatrix(result5, 3);

// 汇总结果
printf("=== 测试结果汇总 ===\n");
printf("通过测试: %d/%d\n", pass_count, total_count);
printf("成功率: %.1f%%\n", (float)pass_count / total_count * 100);

if (pass_count == total_count)
{
printf("🎉 所有测试通过!\n");
}
else
{
printf("❌ 有 %d 个测试失败\n", total_count - pass_count);
}
}

int** TransMat(int** matrix, int m, int n)
{
int **arr;
arr = (int **)malloc(n * sizeof(int *));
for(int i = 0; i < n; i++)
{
arr[i] = (int *)malloc(m * sizeof(int));
if(arr[i] == NULL)
return NULL;
for(int j = 0; j < m; j++)
{
arr[i][j] = matrix[j][i];
}
}
return arr;
}