练习1
将包含字符数字的字符串分开,使得分开后的字符串前一部分是数字后一部分是字母。
例如“h1ell2o3” ->”123hello”
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *devide(char *str){
//注意这里不能返回temp,因为temp的作用域仅仅只在这个函数内
int temp[50] = { 0 };
int i = 0, j = 0;
for (; str[i] != '\0'; ++i) {
temp[i] = str[i];
str[i] = '\0';
}
for (i = 0; temp[i] != '\0'; ++i) {
if (temp[i] >= '0'&&temp[i] <= '9') {
str[j] = temp[i];
++j;
}
}
for (i = 0; temp[i] != '\0'; ++i) {
if (temp[i] >= 'a'&&temp[i] <= 'z' || temp[i] >= 'A'&&temp[i] <= 'Z') {
str[j] = temp[i];
++j;
}
}
return str;
}
int main() {
char s[50] = { 0 };
gets(s);
puts(devide(s));
system("pause");
}
练习2
此题也可以计算空格个数,计算好位置后从后往前赋值,这样就可以降低算法的空间复杂度
将字符串中的空格替换成“%020”。
例如“hello world how ”->”hello%020%020%020world%020%020%020how%020%020%020%020”
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
char *replace(char *str) {
char temp[50] = { 0 };
//先把字符串复制给temp
strcpy(temp, str);
int i, j; //用i控制temp,用j控制str
for (i = 0,j = 0; temp[i] != '\0'; ++i) {
if (temp[i] == ' ') {
str[j++] = '%';
str[j++] = '0';
str[j++] = '2';
str[j++] = '0';
}
else {
str[j++] = temp[i];
}
}
return str;
}
int main() {
char s[50] = { 0 };
gets(s);
puts(replace(s));
system("pause");
}
练习3
删除字符串中指定的字符。
例如 “abcdaefaghiagkl“ 删除‘a’,以后: “bcdefghigkl”
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *deleteWord(char *str, const char word) {
//记录字符串中指定字母出现的次数
unsigned times = 0;
for (int i = 0; str[i] != '\0'; ++i) {
if (str[i] == word) {
++times;
}
str[i + 1 - times] = str[i + 1];
}
int start;
//通过循环找到第一个出现的'\0'
for (start = 0; str[start] != '\0'; ++start);
//第一个循环中我们已经移进去一个'\0'了,所以这里循环终止条件是times==1
for (; times != 1; --times) {
str[start + 1] = '\0';
++start;
}
return str;
}
int main() {
char s[50] = { 0 };
char w;
gets(s);
scanf("%c", &w);
puts(deleteWord(s,w));
system("pause");
}
练习4
删除一个数组中重复的元素。
例如 1 ,2, 2,2,3,3,3,4,4,5,5,5,6,6,6 -> 1,2,3,4,5,6
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *delRepetition(char *str) {
unsigned counter = 0;
for (int i = 0; str[i] != '\0'; ++i) {
if (str[i] == str[i + 1]) {
++counter;
}
str[i + 1 - counter] = str[i+1];
}
//free部分
int start;
//通过循环找到第一个出现的'\0'
for (start = 0; str[start] != '\0'; ++start);
//第一个循环中我们已经移进去一个'\0'了,所以这里循环终止条件是times==1
for (; counter != 1; --counter) {
str[start + 1] = '\0';
++start;
}
return str;
}
int main() {
char s[50] = { 0 };
gets(s);
puts(delRepetition(s));
system("pause");
}
练习5
将 字 符 串 中 的 相 邻 的 多 余 空 格 去 掉 , 例 如 (空 格 用 下 划 线 表示):
”_hello____world___how_are_you” ->”hello_world_how_are_you”
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *delSpace(char *str) {
//若输入的字符串前面有空格,则先计算出前面的空格数量
unsigned i = 0,counter = 0;
for (; str[i] == ' '; ++i) {
++counter;
}
//接下来处理插在每个单词之间的空格
for (; str[i] != '\0'; ++i) {
//这里充分利用&&短路原则,减少不必要的计算量
if (str[i] == ' ' && str[i] == str[i - 1]) {
++counter;
}
str[i - counter] = str[i];
}
//free
for (int start = i - counter - 1; str[start] != '\0'; ++start) {
if (str[start] != '\0') {
str[start] = '\0';
}
}
return str;
}
int main() {
char s[50] = { 0 };
gets(s);
puts(delSpace(s));
system("pause");
}
练习6
大整数加法。 实现任意范围的两个整数的加法。(50位,只考虑正整数相加的情况)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *add(const char *n1, const char *n2, char *ans) {
//定义一个char变量表示进位
char c = 0;
size_t len1 = strlen(n1), len2 = strlen(n2);
len1 >= len2 ? strcpy(ans, n1) : strcpy(ans, n2);
if (len1 >= len2) {
int pos = len1 - 1,pos2 = len2 -1;
for (int i = pos; i >= 0; --i) {
if (pos2 >= 0) {
ans[i] = ans[i] + n2[pos2] + c;
--pos2;
}
else {
ans[i] = ans[i] + c + 48;
}
if (ans[i] > 105) {
ans[i] -= 58;
c = 1;
}
else {
ans[i] -= 48;
c = 0;
}
}
}
else {
int pos = len2 - 1, pos2 = len1 - 1;
for (int i = pos; i >= 0; --i) {
if (pos2 >= 0) {
ans[i] = ans[i] + n1[pos2] + c;
--pos2;
}
else {
ans[i] = ans[i] + c + 48;
}
if (ans[i] > 105) {
ans[i] -= 58;
c = 1;
}
else {
ans[i] -= 48;
c = 0;
}
}
}
if (c == 1) {
for (unsigned i = strlen(ans); i != 0; --i) {
ans[i] = ans[i - 1];
}
ans[0] = '1';
}
return ans;
}
int main() {
char n1[50] = { 0 }, n2[50] = { 0 }, ans[50] = { 0 };
puts("Please enter two numbers:");
printf("number1 is ");
gets(n1);
printf("number2 is ");
gets(n2);
puts(add(n1, n2, ans));
system("pause");
}
练习7
求一个字符串数组的最大值和次大值
void big(char arr[],int size ,char* big1,char** big2)
puts(big1);
puts(big2);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 5
void big(char *arr[], int size, char** big1, char** big2) {
//只需进行两次冒泡排序就可以找到最大值和次大值了
unsigned times = 1;
for (int i = 0; i < size-times; ++i) {
if (strcmp(arr[i], arr[i + 1]) > 0){
*big1 = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = *big1;
}
}
++times;
for (int i = 0; i < size - times; ++i) {
if (strcmp(arr[i], arr[i + 1]) > 0){
*big2 = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = *big2;
}
}
}
int main() {
char **pArr = (char**)malloc(sizeof(char*)*N);
char **b1 = (char**)malloc(sizeof(char*));
char **b2 = (char**)malloc(sizeof(char*));
puts("Please enter strings: ", N);
char arr[N][50] = { 0 };
for (int i = 0; i < N; ++i) {
gets(arr[i]);
}
for (int i = 0; i < N; ++i) {
pArr[i] = arr[i];
}
big(pArr, N, b1, b2);
puts("---------------------------------------------------");
puts("The maximum and sub-maximum values are respectively:");
puts(*b1);
puts(*b2);
system("pause");
}