跳到主要内容
C++ 基础教程:从 for 循环到算法初步 | 极客日志
C++ 算法
C++ 基础教程:从 for 循环到算法初步 C++ 基础教程涵盖循环结构、函数模块化编程、结构体定义、字符串处理及递归回溯算法。内容包含 for 循环计数器用法、斐波那契数列实现、多重循环模板、while 循环逻辑。深入讲解结构体初始化、嵌套、运算符重载及动态内存管理。此外涉及 ASCII 码转换、string 类型操作、高精度加减法模拟竖式计算。适合初学者系统掌握 C++ 核心语法与基础算法思想。
星辰大海 发布于 2026/3/30 更新于 2026/4/23 1 浏览C++ 基础教程:从 for 循环到算法初步
for 循环计数器
for (定义计数变量; 定义结束条件; 每次循环所做的动作)
示例
for (int i = 1 ; i <= 10 ; i++)
而计数器就是在 for 循环有了一定执行范围的基础上创建了一个数组,进行 ++ 计数。
示例
#include <iostream>
using namespace std;
int main () {
int n;
cin >> n;
int cnt = 0 ;
for (int i = 1 ; i <= n; i++) {
cnt++;
}
cout << cnt;
}
练习题目 1
题目描述
斐波那契数列是一个特殊的数列:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55……
数列的第一项和第二项都是 1,从第三项开始,每一项是其前面两项之和。输入正整数 n,编程输出该数列的第 n 项。
输入描述
一个整数 n。
输出描述
一个整数,斐波那契数列的第 n 项。
#include <iostream>
using namespace std;
long long a[55 ];
int {
n;
cin >> n;
a[ ] = , a[ ] = ;
( i = ; i <= n; i++) {
a[i] = a[i - ] + a[i - ];
}
cout << a[n];
;
}
main
()
int
1
1
2
1
for
int
3
1
2
return
0
函数与模块化编程 #include <iostream>
using namespace std;
long long a[55 ];
int fbnq (int n) {
a[1 ] = 1 , a[2 ] = 1 ;
for (int i = 3 ; i <= n; i++) {
a[i] = a[i - 1 ] + a[i - 2 ];
}
return a[n];
}
int main () {
int n;
cin >> n;
cout << fbnq (n);
return 0 ;
}
各种函数特点与用法 函数类型 特点 用法 int 返回值为 int 类型 int 函数名(int 新创建变量的名称) long long 返回值为 long long 类型 long long 函数名(long long 新创建变量的名称) bool 返回值类型为 bool,即不是 true 就是 false bool 函数名 (bool 新创建的变量名称 void 无返回值,函数内不要有 return,若有,请注意很有可能报错,强制停止此函数运行请写"return;" void 函数名 (int 新创建的变量名)
小提示:类型 函数名(int/long long/bool/其他类型 新创建的变量名)输入变量名的类型 void 是不合法的!若使用了会报错。
练习题目 1 #include <cstdio>
#include <cmath>
using namespace std;
int express (double w) {
int money;
w = round (w * 10 ) / 10 ;
if (w <= 1 ) {
money = 13 ;
} else {
w = ceil ((w - 1 ) / 0.5 );
money = 13 + w;
}
return money;
}
int main () {
double w;
scanf ("%lf" , &w);
printf ("%d\n" , express (w));
return 0 ;
}
建议:可以在洛谷上寻找一些简单题目专门用函数来写,进行练习。
多重循环(for 循环 plus 版) for (int i = 1 ; i <= n; i++) {
for (int j = 1 ; j <= n; j++) {
}
}
练习题目 1 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int main () {
int a, b, c;
cin >> a >> b >> c;
int a1, b1, c1; cin >> a1 >> b1 >> c1;
int a2, b2, c2; cin >> a2 >> b2 >> c2;
int a3, b3, c3; cin >> a3 >> b3 >> c3;
for (int i = 0 ; i < 100 ; i++)
{
for (int j = 0 ; j < 100 ; j++)
{
for (int k = 0 ; k < 100 ; k++) {
if (!i && !j && !k) {
continue ;
}
int x = a1 * i + a2 * j + a3 * k;
int y = b1 * i + b2 * j + b3 * k;
int z = c1 * i + c2 * j + c3 * k;
if (x * b == y * a && y * c == b * z && x % a == 0 ) {
cout << i << " " << j << " " << k << " " << x / a << endl;
return 0 ;
}
}
}
}
cout << "NONE" ;
return 0 ;
}
练习题目 2
while 循环
while (true )
{
cout << "作者真帅" ;
}
练习题目 1
练习题目 2 数根可以通过把一个数的各个位上的数字加起来得到。如果得到的数是一位数,那么这个数就是数根。如果结果是两位数或者包括更多位的数字,那么再把这些数字加起来。如此进行下去,直到得到是一位数为止。
比如,对于 24 来说,把 2 和 4 相加得到 6,由于 6 是一位数,因此 6 是 24 的数根。再比如 39,把 3 和 9 加起来得到 12,由于 12 不是一位数,因此还得把 1 和 2 加起来,最后得到 3,这是一个一位数,因此 3 是 39 的数根。
结构体
C++ 结构体的基本概念 在 C++ 中,结构体得到了极大的增强,几乎和类一样强大,唯一区别是默认访问权限为 public(类为 private)。
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
float score;
};
int main () {
Student stu1;
stu1. name = "张三" ;
stu1. age = 20 ;
stu1. score = 85.5 ;
cout << "姓名:" << stu1. name << endl;
cout << "年龄:" << stu1. age << endl;
cout << "成绩:" << stu1. score << endl;
return 0 ;
}
结构体的定义方式
基本定义 #include <iostream>
#include <string>
using namespace std;
struct Person {
string name;
int age;
string phone;
};
struct Car {
string brand;
string model;
int year;
} car1, car2;
int main () {
typedef struct {
string city;
string street;
int number;
} Address;
Address addr = {"北京" , "长安街" , 1 };
Person p;
Car myCar;
return 0 ;
}
结构体的初始化
多种初始化方法 #include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
float score;
};
int main () {
Student stu1 = {"张三" , 20 , 85.5 };
Student stu2 = {.name = "李四" , .age = 21 , .score = 92.0 };
Student stu3 ("王五" , 22 , 88.5 ) ;
Student stu4{};
Student stu5;
stu5. name = "赵六" ;
stu5. age = 23 ;
stu5. score = 90.5 ;
cout << stu1. name << " " << stu1. age << " " << stu1. score << endl;
cout << stu4. name << " " << stu4. age << " " << stu4. score << endl;
return 0 ;
}
结构体成员访问 #include <iostream>
#include <string>
using namespace std;
struct Point {
int x;
int y;
void display () {
cout << "Point(" << x << ", " << y << ")" << endl;
}
double distance () {
return sqrt (x * x + y * y);
}
};
int main () {
Point p1 = {3 , 4 };
cout << "x = " << p1. x << ", y = " << p1. y << endl;
p1. display ();
cout << "到原点的距离:" << p1. distance () << endl;
Point *ptr = &p1;
ptr->x = 5 ;
ptr->y = 12 ;
cout << "修改后:" ;
ptr->display ();
return 0 ;
}
结构体数组 #include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct Student {
string name;
int age;
float score;
};
int main () {
Student class1[3 ] = {{"张三" , 20 , 85.5 }, {"李四" , 21 , 92.0 }, {"王五" , 22 , 88.5 }};
cout << "班级学生信息:" << endl;
cout << setw (10 ) << "姓名" << setw (6 ) << "年龄" << setw (8 ) << "成绩" << endl;
cout << "------------------------" << endl;
for (int i = 0 ; i < 3 ; i++) {
cout << setw (10 ) << class1[i].name << setw (6 ) << class1[i].age << setw (8 ) << fixed << setprecision (1 ) << class1[i].score << endl;
}
Student* class2 = new Student[2 ];
class2[0 ] = {"赵六" , 19 , 78.5 };
class2[1 ] = {"孙七" , 20 , 95.0 };
delete [] class2;
return 0 ;
}
结构体嵌套 #include <iostream>
#include <string>
using namespace std;
struct Address {
string city;
string street;
int number;
void show () {
cout << city << " " << street << " " << number << "号" ;
}
};
struct Contact {
string phone;
string email;
};
struct Student {
string name;
int age;
Address addr;
Contact contact;
void showInfo () {
cout << "姓名:" << name << endl;
cout << "年龄:" << age << endl;
cout << "地址:" ;
addr.show ();
cout << "\n电话:" << contact.phone << endl;
cout << "邮箱:" << contact.email << endl;
}
};
int main () {
Student stu = {"张三" , 20 , {"北京" , "长安街" , 1 }, {"13800138000" , "[email protected] " }};
stu.showInfo ();
cout << "\n城市:" << stu.addr.city << endl;
cout << "电话:" << stu.contact.phone << endl;
return 0 ;
}
结构体与函数 #include <iostream>
#include <string>
using namespace std;
struct Rectangle {
double width;
double height;
double area () {
return width * height;
}
};
void printRect1 (Rectangle r) {
cout << "宽:" << r.width << ",高:" << r.height << ",面积:" << r.area () << endl;
}
void printRect2 (const Rectangle &r) {
cout << "宽:" << r.width << ",高:" << r.height << ",面积:" << r.area () << endl;
}
void modifyRect (Rectangle *r, double w, double h) {
r->width = w;
r->height = h;
}
Rectangle createRect (double w, double h) {
return {w, h};
}
int main () {
Rectangle r1 = {10 , 5 };
printRect1 (r1);
printRect2 (r1);
modifyRect (&r1, 20 , 10 );
cout << "修改后:" ;
printRect2 (r1);
Rectangle r2 = createRect (15 , 8 );
cout << "新矩形:" ;
printRect2 (r2);
return 0 ;
}
结构体与运算符重载 #include <iostream>
using namespace std;
struct Vector2 {
float x, y;
Vector2 (float x = 0 , float y = 0 ) : x (x), y (y) {}
Vector2 operator +(const Vector2& other) const {
return Vector2 (x + other.x, y + other.y);
}
Vector2 operator *(float scalar) const {
return Vector2 (x * scalar, y * scalar);
}
friend ostream& operator <<(ostream& os, const Vector2& v) {
os << "(" << v.x << ", " << v.y << ")" ;
return os;
}
};
int main () {
Vector2 v1 (3 , 4 ) ;
Vector2 v2 (1 , 2 ) ;
Vector2 v3 = v1 + v2;
Vector2 v4 = v1 * 2 ;
cout << "v1 = " << v1 << endl;
cout << "v2 = " << v2 << endl;
cout << "v1 + v2 = " << v3 << endl;
cout << "v1 * 2 = " << v4 << endl;
return 0 ;
}
结构体与动态内存 #include <iostream>
#include <string>
using namespace std;
struct Node {
int data;
Node* next;
Node (int val) : data (val), next (nullptr ) {}
};
struct DynamicArray {
int * arr;
int size;
DynamicArray (int n) : size (n) {
arr = new int [size];
for (int i = 0 ; i < size; i++) {
arr[i] = i * 10 ;
}
}
~DynamicArray () {
delete [] arr;
cout << "内存已释放" << endl;
}
void display () {
for (int i = 0 ; i < size; i++) {
cout << arr[i] << " " ;
}
cout << endl;
}
};
int main () {
Node* head = new Node (1 );
head->next = new Node (2 );
head->next->next = new Node (3 );
Node* current = head;
while (current) {
cout << current->data << " " ;
current = current->next;
}
cout << endl;
while (head) {
Node* temp = head;
head = head->next;
delete temp;
}
DynamicArray da (5 ) ;
da.display ();
return 0 ;
}
结构体 vs 类的对比 #include <iostream>
using namespace std;
struct MyStruct {
int a;
void func () {
cout << "Struct function" << endl;
}
};
class MyClass {
int a;
public :
void func () {
cout << "Class function" << endl;
}
};
struct Point {
int x, y;
};
class Shape {
private :
Point center;
public :
virtual void draw () = 0 ;
};
int main () {
MyStruct s;
s.a = 10 ;
s.func ();
MyClass c;
c.func ();
return 0 ;
}
实用示例:学生成绩管理系统 #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Student {
string id;
string name;
int age;
double score;
Student (string id, string name, int age, double score) : id (id), name (name), age (age), score (score) {}
void display () const {
cout << "学号:" << id << ",姓名:" << name << ",年龄:" << age << ",成绩:" << score << endl;
}
};
struct Class {
string className;
vector<Student> students;
void addStudent (const Student& stu) {
students.push_back (stu);
}
void showAll () {
cout << "\n=== " << className << " 学生列表 ===" << endl;
for (const auto & stu : students) {
stu.display ();
}
}
double getAverageScore () {
if (students.empty ()) return 0 ;
double sum = 0 ;
for (const auto & stu : students) {
sum += stu.score;
}
return sum / students.size ();
}
void sortByScore () {
sort (students.begin (), students.end (), [](const Student& a, const Student& b) {
return a.score > b.score;
});
}
};
int main () {
Class c1 = {"计算机 1 班" };
c1. addStudent ({"2024001" , "张三" , 20 , 85.5 });
c1. addStudent ({"2024002" , "李四" , 21 , 92.0 });
c1. addStudent ({"2024003" , "王五" , 20 , 78.5 });
c1. addStudent ({"2024004" , "赵六" , 22 , 95.0 });
c1. showAll ();
cout << "\n班级平均分:" << c1. getAverageScore () << endl;
c1. sortByScore ();
cout << "\n=== 按成绩排序后 ===" ;
c1. showAll ();
return 0 ;
}
ASCII 码 ASCII 码就像一个字符的身份证,每一个字符都有一个数字来代表,而怎么判断一个字符的'身份证'是多少呢,请看下面示例。
#include <iostream>
using namespace std;
int main () {
char s = 'A' ;
int a = s;
cout << a;
return 0 ;
}
有一个小提示,字符 A-Z 是挨在一起的,所以我们知道了 A 的身份证是 65,就可以推出 B 的字符是 66,以此类推,注意,小写字符和大写字符不是挨在一起的,所以需要记好'a'的身份证是 97。
string 类型 不知道大家是否学过 Python 的字符串,在 Python 中,字符串是可以像数组那样进行下表操作的。而不幸的是,C++ 中正常的 char 类型字符串无法进行下表操作,而 string 类型可以。不过请注意,string 类型没有负索引这个东西。
练习题目 1 有 N 只史莱姆排成一排,每只的颜色用一个英文小写字母表示,所有史莱姆的颜色排列成一个字符串 S。接下来同样颜色的史莱姆会融合成一只,直到所有相邻的史莱姆颜色都不同。问最后剩下几只史莱姆?
第 1 行,1 个正整数 N
第 2 行,字符串 S,表示每只史莱姆的颜色
#include <iostream>
using namespace std;
int main () {
int n;
cin >> n;
string s;
cin >> s;
int count = 1 ;
for (int i = 1 ; i < n; i++) {
if (s[i] != s[i - 1 ])
{
count++;
}
}
cout << count << endl;
return 0 ;
}
string 字符串操作
字符串拼接 string s = "作者" ;
string n = "真帅" ;
string m = s + n;
cout << m;
练习题目 1 #include <bits/stdc++.h>
using namespace std;
map<string, int > money;
int n, l, have;
string name[105 ], x, buddy;
int main () {
cin >> n;
for (int i = 1 ; i <= n; i++) cin >> name[i];
for (int i = 1 ; i <= n; i++) {
cin >> x >> have >> l;
if (l == 0 ) continue ;
money[x] -= have;
int give = floor (have / l);
money[x] += (have - l * give);
for (int i = 1 ; i <= l; i++) {
cin >> buddy;
money[buddy] += give;
}
}
for (int i = 1 ; i <= n; i++) cout << name[i] << " " << money[name[i]] << endl;
return 0 ;
}
递归初步
1.1 递归的含义与历史 递归是计算机科学的一个不可分割的算法。就像西方不能失去耶路撒冷一样。递归指的是一个函数直接或间接读取自己的过程。但在我们使用递归的时候要注意不要写成死循环,并且我们也要明确我们写这个递归的目的,要逐步地把问题缩小化。
1.2 举个栗子
在小明小的时候听过这样的一个故事:从前有座山,山中有座庙,庙里有个老和尚,老和尚在讲故事,讲的是什么呀?从前有座山,山中有座庙,庙里有个老和尚在讲故事……
像这样的故事没有丝毫特点,就像你写死循环的时候重复给机器讲一个'故事',机器就会困得睡着了,因此就'睡着了'。
1.3 代码示例 int dg (int n) {
if (n == 87 )
{
return 1 ;
}
return dg (n + 1 );
}
练习题目 1 #include <bits/stdc++.h>
using namespace std;
int gcd (int a, int b) {
if (a % b == 0 ) {
return b;
} else {
return gcd (b, a % b);
}
}
int main () {
int a, b;
cin >> a >> b;
cout << gcd (a, b);
return 0 ;
}
拔高题目 1 这道题难度较高,使用了我们还未学到的回溯算法,可以自己深研以下。
#include <iostream>
using namespace std;
int n, m, p[15 ], ans;
bool vis[15 ];
void dfs (int step) {
if (step == n + 1 ) {
int sum = 0 ;
for (int i = 1 ; i <= n; i++) {
if (vis[i] == 1 ) {
sum += p[i];
}
}
if (sum == m) {
ans++;
}
return ;
}
vis[step] = 1 ;
dfs (step + 1 );
vis[step] = 0 ;
dfs (step + 1 );
}
int main () {
cin >> n >> m;
for (int i = 1 ; i <= n; i++) {
cin >> p[i];
}
dfs (1 );
cout << ans << endl;
return 0 ;
}
回溯法
1.1 前言 在上一个知识点递归初步里的拔高题目 AC 代码使用了回溯法,在这个知识点部分我们来学习回溯法。
1.1.1 什么是回溯法?
小明:老师,回溯法是啥捏,是时空大回溯吗。
老师:对也不完全对,回溯指的是在做题时一种试错过程中不可缺少的部分。比如说……
小明:老师!也就是说回溯就是一种不撞南墙不回头的做法 呗。
老师:对了,我们如果发现一种路线不可行,那么我们立即使用下一条路线,而回到原来选择的那个分支的方法,我们称为回溯法 ,或者说这也是种枚举的过程
1.1.2 回溯法有什么用呢 有人说,回溯法的底层逻辑就是递归,有回溯的地方就有递归。而回溯在做背包一类的题目中有显著优势,背包这个东西我们后文会提到。
2. 回溯模板 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
bool vis[10 ];
int plan[10 ];
int n;
void dfs (int step) {
if (step == n + 1 ) {
for (int i = 1 ; i <= n; i++) {
cout << plan[i] << " " ;
}
cout << endl;
return ;
}
for (int i = 1 ; i <= n; i++) {
if (vis[i] == 1 ) {
continue ;
}
plan[step] = i;
vis[i] = 1 ;
dfs (step + 1 );
vis[i] = 0 ;
}
}
int main () {
cin >> n;
dfs (1 );
return 0 ;
}
高精度算法
1. 加法
1.1 前言 在大家的小学时期怎样计算两个数相加呢,想必有的人会使用竖式的方法,而高精度就是来模拟竖式加法。
1.2 代码逻辑 我们知道了高精度加法的具体逻辑,就是模拟人类计算多位数加多位数时使用的竖式计算方式,而在加的时候就会出现多一位的情况。
有时我们就会出现这种尴尬的方式,数组下表 0 的那个部分给到了数字 9,而多的那一位就没有地方了。也许有的人会说,那把 9 的下表设为 1 不就行了,但是有时数位不会多出来一位,若是这样的话有时输出就会出现前导 0,所以,我们就要请出这个方法了——逆序存储。因为这样的话若是没有多出来的那一位就不会出现前导 0 了,因为逆序输出的时候记好是否有多出来的那一位就可以了。
1.3 逆序存储代码: void add (string s, int a[]) {
a[0 ] = s.size ();
for (int i = 1 ; i <= a[0 ]; i++)
a[i] = s[a[0 ] - i] - '0' ;
}
1.4 核心代码 在我们加法运算的过程中,一定会出现进位的情况,而我们就要推出进位变量 carry,核心代码实现如下:
void addBIG (int a[], int b[], int c[]) {
c[0 ] = max (a[0 ], b[0 ]);
int carry = 0 ;
for (int i = 1 ; i <= c[0 ]; i++) {
int t = a[i] + b[i] + carry;
c[i] = t % 10 ;
carry = t / 10 ;
}
if (carry > 0 ) {
c[++c[0 ]] = carry;
}
}
1.5 输出 最后一步也是最重要的一步——逆序输出。因为我们前文说到是逆序存入,so 我们要逆序输出,这样才能输出正确。
1.6 整体代码 #include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
void s2BIG (string s, int a[]) {
a[0 ] = s.size ();
for (int i = 1 ; i <= a[0 ]; i++)
a[i] = s[a[0 ] - i] - '0' ;
}
void printBIG (int a[]) {
for (int i = a[0 ]; i >= 1 ; i--)
cout << a[i];
cout << endl;
}
void addBIG (int a[], int b[], int c[]) {
c[0 ] = max (a[0 ], b[0 ]);
int u = 0 ;
for (int i = 1 ; i <= c[0 ]; i++) {
int t = a[i] + b[i] + u;
c[i] = t % 10 ;
u = t / 10 ;
}
if (u > 0 ) {
c[++c[0 ]] = u;
}
}
int a[1000005 ], b[100005 ], c[100005 ];
string sa, sb;
int main () {
cin >> sa >> sb;
s2BIG (sa, a);
s2BIG (sb, b);
addBIG (a, b, c);
printBIG (c);
return 0 ;
}
2. 高精度减法
1.1 前言 高精减和高精加区别并没有那么大,因为这个仅仅把加变为减,把进位改为退位,因此原理还是模拟人类竖式计算。
1.2 示例 #include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
void s2BIG (string s, int a[]) {
a[0 ] = s.size ();
for (int i = 1 ; i <= a[0 ]; i++)
a[i] = s[a[0 ] - i] - '0' ;
}
void printBIG (int a[]) {
for (int i = a[0 ]; i >= 1 ; i--)
cout << a[i];
cout << endl;
}
void addBIG (int a[], int b[], int c[]) {
c[0 ] = max (a[0 ], b[0 ]);
int u = 0 ;
for (int i = 1 ; i <= c[0 ]; i++) {
int t = a[i] + b[i] + u;
c[i] = t % 10 ;
u = t / 10 ;
}
if (u > 0 ) c[++c[0 ]] = u;
}
bool cmpBIG (int a[], int b[]) {
if (a[0 ] != b[0 ]) return a[0 ] < b[0 ];
for (int i = a[0 ]; i >= 1 ; i--)
if (a[i] != b[i]) return a[i] < b[i];
return false ;
}
void subBIG (int a[], int b[], int c[]) {
c[0 ] = max (a[0 ], b[0 ]);
int u = 0 ;
for (int i = 1 ; i <= c[0 ]; i++) {
int t = a[i] - b[i] - u;
if (t < 0 ) {
c[i] = t + 10 ;
u = 1 ;
} else {
c[i] = t;
u = 0 ;
}
}
while (c[c[0 ]] == 0 && c[0 ] > 1 ) c[0 ]--;
}
int a[1005 ], b[1005 ], c[1005 ];
string sa, sb;
int main () {
cin >> sa >> sb;
s2BIG (sa, a);
s2BIG (sb, b);
if (cmpBIG (a, b) == true )
subBIG (b, a, c);
else
subBIG (a, b, c);
printBIG (c);
return 0 ;
}
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online