将长链接生成短链接同时短链接不重复
时间: 2023-08-05 12:03:10 浏览: 65
可以使用一个算法来将长链接生成短链接,同时保证短链接不重复。一种常见的算法是使用哈希函数,将长链接映射成一个短字符串,比如使用MD5哈希函数将长链接转换为32位的字符串,然后再将该字符串截取一部分作为短链接。
为了保证短链接不重复,可以使用一个数据库来保存已经生成的短链接和对应的长链接。每次生成新的短链接时,先在数据库中查询该短链接是否已经存在,如果已经存在,则重新生成一个新的短链接,直到生成的短链接没有重复为止。
相关问题
预处理 编译 汇编 链接
预处理、编译、汇编和链接是软件开发中的四个重要步骤。
预处理(Preprocessing)是在编译之前对源代码进行处理的阶段。在这个阶段,预处理器会根据预处理指令(以 # 开头)对代码进行修改。常见的预处理指令包括宏定义、条件编译等。预处理的目的是为了减少重复代码、提高代码可读性和可维护性。
编译(Compilation)是将源代码转换为机器可执行的形式的过程。编译器会将高级语言(如C、C++、Java等)的源代码翻译成低级语言(如汇编语言)的中间代码。
汇编(Assembly)是将汇编语言翻译成机器码的过程。汇编器会将汇编语言中的指令和操作数转化为二进制形式,以供计算机直接执行。
链接(Linking)是将多个目标文件(经过编译和汇编生成的文件)合并成一个可执行文件的过程。在链接过程中,链接器会解决函数和变量之间的引用关系,将它们正确地连接在一起。
综上所述,预处理、编译、汇编和链接是软件开发中不可或缺的步骤,它们共同构成了将源代码转化为可执行文件的过程。
生成图数据 使用随机数生成器生成300个不重复的顶点坐标,然后对于每个顶点,随机选择1-5个其他顶点,计算与它们之间的路径权值,并将这些信息存储到sqlite数据库中。 存取图数据 使用QT提供的QSqlite类库连接到sqlite数据库,读取和写入图数据。 使用QT代码实现
生成图数据的代码如下:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <sqlite3.h>
struct Point {
int x;
int y;
};
struct Edge {
int u;
int v;
int weight;
};
int main() {
const int n = 300;
const int m = 5;
std::vector<Point> points(n);
std::vector<std::vector<int>> adj(n);
std::vector<Edge> edges;
// 生成顶点坐标
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(0, 1000);
for (int i = 0; i < n; ++i) {
points[i] = {dist(gen), dist(gen)};
}
// 构造邻接表和边集
for (int i = 0; i < n; ++i) {
std::vector<int> neighbors;
std::sample(points.begin(), points.end(), std::back_inserter(neighbors), m, gen);
std::sort(neighbors.begin(), neighbors.end());
neighbors.erase(std::unique(neighbors.begin(), neighbors.end()), neighbors.end());
adj[i] = neighbors;
for (int j : neighbors) {
if (i < j) {
edges.push_back({i, j, abs(points[i].x - points[j].x) + abs(points[i].y - points[j].y)});
}
}
}
// 存入sqlite数据库
sqlite3* db;
int rc = sqlite3_open("graph.db", &db);
if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
return 1;
}
rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS points (id INTEGER PRIMARY KEY, x INTEGER, y INTEGER)", nullptr, nullptr, nullptr);
if (rc) {
std::cerr << "Can't create table: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS edges (u INTEGER, v INTEGER, weight INTEGER)", nullptr, nullptr, nullptr);
if (rc) {
std::cerr << "Can't create table: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
sqlite3_stmt* stmt;
rc = sqlite3_prepare_v2(db, "INSERT INTO points (id, x, y) VALUES (?, ?, ?)", -1, &stmt, nullptr);
if (rc) {
std::cerr << "Can't prepare statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
for (int i = 0; i < n; ++i) {
rc = sqlite3_bind_int(stmt, 1, i);
rc |= sqlite3_bind_int(stmt, 2, points[i].x);
rc |= sqlite3_bind_int(stmt, 3, points[i].y);
if (rc) {
std::cerr << "Can't bind values: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
std::cerr << "Can't execute statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
rc = sqlite3_reset(stmt);
if (rc) {
std::cerr << "Can't reset statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
}
rc = sqlite3_prepare_v2(db, "INSERT INTO edges (u, v, weight) VALUES (?, ?, ?)", -1, &stmt, nullptr);
if (rc) {
std::cerr << "Can't prepare statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
for (const auto& e : edges) {
rc = sqlite3_bind_int(stmt, 1, e.u);
rc |= sqlite3_bind_int(stmt, 2, e.v);
rc |= sqlite3_bind_int(stmt, 3, e.weight);
if (rc) {
std::cerr << "Can't bind values: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
std::cerr << "Can't execute statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
rc = sqlite3_reset(stmt);
if (rc) {
std::cerr << "Can't reset statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
```
存取图数据的代码如下:
```cpp
#include <iostream>
#include <vector>
#include <map>
#include <sqlite3.h>
#include <QtSql>
struct Point {
int x;
int y;
};
int main() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("graph.db");
if (!db.open()) {
std::cerr << "Can't open database: " << db.lastError().text().toStdString() << std::endl;
return 1;
}
QSqlQuery query(db);
if (!query.exec("SELECT COUNT(*) FROM points")) {
std::cerr << "Can't execute query: " << query.lastError().text().toStdString() << std::endl;
db.close();
return 1;
}
query.next();
int n = query.value(0).toInt();
std::vector<Point> points(n);
std::map<std::pair<int, int>, int> weights;
if (!query.exec("SELECT id, x, y FROM points")) {
std::cerr << "Can't execute query: " << query.lastError().text().toStdString() << std::endl;
db.close();
return 1;
}
while (query.next()) {
int id = query.value(0).toInt();
int x = query.value(1).toInt();
int y = query.value(2).toInt();
points[id] = {x, y};
}
if (!query.exec("SELECT u, v, weight FROM edges")) {
std::cerr << "Can't execute query: " << query.lastError().text().toStdString() << std::endl;
db.close();
return 1;
}
while (query.next()) {
int u = query.value(0).toInt();
int v = query.value(1).toInt();
int weight = query.value(2).toInt();
weights[{u, v}] = weight;
weights[{v, u}] = weight;
}
// 进行图算法操作,这里只是打印邻接表和边权值
for (int i = 0; i < n; ++i) {
std::cout << i << ": ";
for (int j : adj[i]) {
std::cout << j << "(" << weights[{i, j}] << ") ";
}
std::cout << std::endl;
}
db.close();
return 0;
}
```
注意事项:
1. 生成图数据的代码需要链接sqlite3库。
2. 存取图数据的代码需要链接QtSql库,并在运行前将sqlite3.dll放到可执行文件所在目录(Windows平台)。