用c语言写一个sqrt函数,时间复杂度和空间复杂度要小
时间: 2023-05-15 18:07:02 浏览: 146
以下是一个用C语言编写的sqrt函数,时间复杂度为O(logn),空间复杂度为O(1):
```c
double my_sqrt(double x) {
if (x == 0) return 0;
double l = 0, r = x;
while (true) {
double mid = (l + r) / 2;
if (mid == l || mid == r) return mid;
if (mid * mid > x) r = mid;
else l = mid;
}
}
```
这个函数使用二分法来逼近x的平方根,每次将搜索区间缩小一半,因此时间复杂度为O(logn),同时只使用了常数级别的额外空间,因此空间复杂度为O(1)。
相关问题
用c写一个求一个数质因数的个数的函数,要求最大化减小函数的时间复杂度
以下是用C语言实现求一个数质因数个数的函数:
```c
#include <stdio.h>
int countPrimeFactors(int n) {
int count = 0, i;
while(n % 2 == 0) {
count++;
n /= 2;
}
for(i = 3; i * i <= n; i += 2) {
while(n % i == 0) {
count++;
n /= i;
}
}
if(n > 2)
count++;
return count;
}
int main()
{
int n;
printf("Enter an integer: ");
scanf("%d", &n);
printf("The number of prime factors of %d is %d\n", n, countPrimeFactors(n));
return 0;
}
```
这个函数通过从小到大枚举可能的因子来找到质因数并计数。其中,程序首先把2作为n的因子进行处理,然后从3开始枚举所有奇数作为可能的因子,只要能整除就继续除以该因子,并将计数器加1。最后,如果n大于2,说明n本身也是一个质因数,因此需要把计数器加1。这样,我们可以在O(sqrt(n))的时间复杂度内找到n的所有质因数,并计算其数量。
编写一段C语言代码要求计算输出n个点中距离最近的两个点的距离,要求时间复杂度低于O(n^2)
这道题可以使用分治法来解决,时间复杂度为O(nlogn)。具体实现如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct point {
double x, y;
};
int cmp_x(const void* a, const void* b) { // 按x坐标升序排序
struct point* p1 = (struct point*)a;
struct point* p2 = (struct point*)b;
return (p1->x > p2->x);
}
int cmp_y(const void* a, const void* b) { // 按y坐标升序排序
struct point* p1 = (struct point*)a;
struct point* p2 = (struct point*)b;
return (p1->y > p2->y);
}
double distance(struct point p1, struct point p2) { // 计算两个点之间的距离
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
double brute_force(struct point* p, int n) { // 暴力求解,时间复杂度为O(n^2)
double min_dist = INFINITY;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
double d = distance(p[i], p[j]);
if (d < min_dist) {
min_dist = d;
}
}
}
return min_dist;
}
double strip_closest(struct point* strip, int size, double d) { // 计算跨越两个部分的点对之间的最小距离
double min_dist = d;
qsort(strip, size, sizeof(struct point), cmp_y);
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size && (strip[j].y - strip[i].y) < min_dist; j++) {
double dist = distance(strip[i], strip[j]);
if (dist < min_dist) {
min_dist = dist;
}
}
}
return min_dist;
}
double closest_util(struct point* px, struct point* py, int n) { // 分治求解
if (n <= 3) { // 当点数小于等于3时,暴力求解
return brute_force(px, n);
}
int mid = n / 2;
struct point mid_point = px[mid];
struct point pyl[mid + 1];
struct point pyr[n - mid - 1];
int li = 0, ri = 0;
for (int i = 0; i < n; i++) { // 将点按照中位数分成两部分
if (py[i].x <= mid_point.x) {
pyl[li++] = py[i];
} else {
pyr[ri++] = py[i];
}
}
double dl = closest_util(px, pyl, mid); // 递归求解左半部分的最小距离
double dr = closest_util(px + mid, pyr, n - mid); // 递归求解右半部分的最小距离
double d = fmin(dl, dr); // 取左右两部分的最小距离
struct point strip[n];
int j = 0;
for (int i = 0; i < n; i++) { // 找到跨越两个部分的点对
if (fabs(py[i].x - mid_point.x) < d) {
strip[j++] = py[i];
}
}
return fmin(d, strip_closest(strip, j, d)); // 取跨越两个部分的点对之间的最小距离
}
double closest(struct point* p, int n) {
struct point px[n];
struct point py[n];
for (int i = 0; i < n; i++) {
px[i] = p[i];
py[i] = p[i];
}
qsort(px, n, sizeof(struct point), cmp_x); // 按x坐标排序
qsort(py, n, sizeof(struct point), cmp_y); // 按y坐标排序
return closest_util(px, py, n); // 分治求解
}
int main() {
int n;
scanf("%d", &n);
struct point p[n];
for (int i = 0; i < n; i++) {
scanf("%lf%lf", &p[i].x, &p[i].y);
}
printf("%.2f\n", closest(p, n));
return 0;
}
```
上述代码中,`cmp_x`和`cmp_y`分别是按x坐标和y坐标进行比较的函数,`distance`用于计算两个点之间的距离,`brute_force`用于暴力求解两个点之间的最小距离,`strip_closest`用于计算跨越两个部分的点对之间的最小距离,`closest_util`递归求解两个部分的最小距离,`closest`是对外的接口函数,用于调用`closest_util`进行分治求解。
阅读全文