【发布时间】:2020-07-15 10:14:14
【问题描述】:
我有一个要求,我必须通过处理给定的动态数组来创建一个新数组。我不知道我的新数组大小是多少。但最大大小是旧数组的 2 倍。
背景: 在函数内部,它应该遍历数组中的每个元素,并根据数量在新数组中添加/删除一个或两个元素。
实施: 我是如何实现上述要求的,我创建了一个链表并根据检查条件添加一两个新节点。
伪代码:
node_t *createNode() {
node_t *temp;
temp = malloc(sizeof(node_t));
if (temp == NULL) {
fputs("Error: Failed to allocate memory for temp.\n", stderr);
exit(1);
}
temp->next = NULL;
return temp;
}
/*
* Function: addNode
* -----------------
* add node to a existing linked list at end
*
* head: original linked list to add additional node at end
* newVal: value of the additional node
*
* return: new linked list that have an additional node
*/
node_t *addNode(node_t *head, double newVal) {
node_t *temp;
node_t *p;
// create additional node
temp = createNode();
temp->val = newVal;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
return head;
}
/*
* Function: lastNodeDeletion
* --------------------------
* delete last node of the linked list
*
* head: linked list
*/
void lastNodeDeletion(node_t *head) {
node_t *toDelLast;
node_t *preNode;
if (head == NULL) {
printf("There is no element in the list.");
} else {
toDelLast = head;
preNode = head;
/* Traverse to the last node of the list */
while (toDelLast->next != NULL) {
preNode = toDelLast;
toDelLast = toDelLast->next;
}
if (toDelLast == head) {
/* If there is only one item in the list, remove it */
head = NULL;
} else {
/* Disconnects the link of second last node with last node */
preNode->next = NULL;
}
/* Delete the last node */
free(toDelLast);
}
}
/*
* Function: calculateLower
* ------------------------
* find the data set of lower tube curve
*
* reference: reference data curve
* tubeSize: data array specifying tube size that includes:
* tubeSize[0], x -- half width of rectangle
* tubeSize[1], y -- half height of rectangle
* tubeSize[2], baseX -- base of relative value is x direction
* tubeSize[3], baseY -- base of relative value is y direction
* tubeSize[4], ratio -- ratio y / x
*
* return : data set defining lower curve of the tube
*/
struct data calculateLower(struct data reference, double *tubeSize) {
int i;
struct data ref_norm;
/*
struct data contains two pointers double *x, double *y, int n;
*/
struct data lower;
node_t *lx = NULL;
node_t *ly = NULL;
// ===== 1. add corner points of the rectangle =====
double m0, m1; // slopes before and after point i of reference curve
double s0, s1; // sign of slopes of reference curve: 1 - increasing, 0 - constant, -1 - decreasing
double mx, my;
int b;
double xLen;
double yLen;
// Normalize data.
mx = fabs(mean(reference.x, reference.n));
my = fabs(mean(reference.y, reference.n));
ref_norm = normalizeData(reference, mx, my);
if equ(mx, 0.0) {
xLen = tubeSize[0];
} else {
xLen = tubeSize[0] / mx;
}
if equ(my, 0.0) {
yLen = tubeSize[1];
} else {
yLen = tubeSize[1] / my;
}
// ----- 1.1 Start: rectangle with center (x,y) = (reference.x[0], reference.y[0]) -----
// ignore identical point at the beginning
b = 0;
while ((b+1 < ref_norm.n) && equ(ref_norm.x[b], ref_norm.x[b+1]) && (equ(ref_norm.y[b], ref_norm.y[b+1])))
b = b+1;
// add down left point
lx = addNode(lx, (ref_norm.x[b] - xLen));
ly = addNode(ly, (ref_norm.y[b] - yLen));
if (b+1 < ref_norm.n) {
// slopes of reference curve (initialization)
s0 = sign(ref_norm.y[b+1] - ref_norm.y[b]);
if (!equ(ref_norm.x[b+1], ref_norm.x[b])) {
m0 = (ref_norm.y[b+1] - ref_norm.y[b]) / (ref_norm.x[b+1] - ref_norm.x[b]);
} else {
m0 = (s0 > 0) ? 1e+15 : -1e+15;
}
if equ(s0, 1) {
// add down right point
lx = addNode(lx, (ref_norm.x[b] + xLen));
ly = addNode(ly, (ref_norm.y[b] - yLen));
}
// ----- 1.2 Iteration: rectangle with center (x,y) = (reference.x[i], reference.y[i]) -----
for (i = b+1; i < ref_norm.n-1; i++) {
// ignore identical points
if (equ(ref_norm.x[i], ref_norm.x[i+1]) && equ(ref_norm.y[i], ref_norm.y[i+1]))
continue;
// slopes of reference curve
s1 = sign(ref_norm.y[i+1] - ref_norm.y[i]);
if (!equ(ref_norm.x[i+1], ref_norm.x[i])) {
m1 = (ref_norm.y[i+1] - ref_norm.y[i]) / (ref_norm.x[i+1] - ref_norm.x[i]);
} else {
m1 = (s1 > 0) ? (1e+15) : (-1e+15);
}
// add no point for equal slopes of reference curve
if (!equ(m0, m1)) {
if (!equ(s0, -1) && !equ(s1, -1)) {
// add down right point
lx = addNode(lx, (ref_norm.x[i] + xLen));
ly = addNode(ly, (ref_norm.y[i] - yLen));
} else if (!equ(s0, 1) && !equ(s1, 1)) {
// add down left point
lx = addNode(lx, (ref_norm.x[i] - xLen));
ly = addNode(ly, (ref_norm.y[i] - yLen));
} else if (equ(s0, -1) && equ(s1, 1)) {
// add down left point
lx = addNode(lx, (ref_norm.x[i] - xLen));
ly = addNode(ly, (ref_norm.y[i] - yLen));
// add down right point
lx = addNode(lx, (ref_norm.x[i] + xLen));
ly = addNode(ly, (ref_norm.y[i] - yLen));
} else if (equ(s0, 1) && equ(s1, -1)) {
// add down right point
lx = addNode(lx, (ref_norm.x[i] + xLen));
ly = addNode(ly, (ref_norm.y[i] - yLen));
// add down left point
lx = addNode(lx, (ref_norm.x[i] - xLen));
ly = addNode(ly, (ref_norm.y[i] - yLen));
}
int len = listLen(ly);
double lastY = getNth(ly, len-1);
// remove the last added points in case of zero slope of tube curve
if equ((ref_norm.y[i+1] - yLen), lastY) {
if (equ(s0 * s1, -1) && equ(getNth(ly, len-3), lastY)) {
// remove two points, if two points were added at last
// ((len-1) - 2 >= 0, because start point + two added points)
lastNodeDeletion(lx);
lastNodeDeletion(ly);
lastNodeDeletion(lx);
lastNodeDeletion(ly);
} else if (!equ(s0 * s1, -1) && equ(getNth(ly, len-2), lastY)) {
// remove one point, if one point was added at last
// ((len-1) - 1 >= 0, because start point + one added point)
lastNodeDeletion(lx);
lastNodeDeletion(ly);
}
}
}
s0 = s1;
m0 = m1;
}
// ----- 1.3. End: Rectangle with center (x,y) = (reference.x[reference.n - 1], reference.y[reference.n - 1]) -----
if equ(s0, -1) {
// add down left point
lx = addNode(lx, (ref_norm.x[ref_norm.n-1] - xLen));
ly = addNode(ly, (ref_norm.y[ref_norm.n-1] - yLen));
}
}
// add down right point
lx = addNode(lx, (ref_norm.x[ref_norm.n-1] + xLen));
ly = addNode(ly, (ref_norm.y[ref_norm.n-1] - yLen));
// ===== 2. Remove points and add intersection points in case of backward order =====
int lisLen = listLen(ly);
double *tempLX = malloc(lisLen * sizeof(double));
if (tempLX == NULL) {
fputs("Error: Failed to allocate memory for tempLX.\n", stderr);
exit(1);
}
double *tempLY = malloc(lisLen * sizeof(double));
if (tempLY == NULL) {
fputs("Error: Failed to allocate memory for tempLY.\n", stderr);
exit(1);
}
tempLX = getListValues(lx);
tempLY = getListValues(ly);
lower = removeLoop(tempLX, tempLY, lisLen, -1);
return denormalizeData(lower, mx, my);
}
它适用于小例子。但是当一个包含 50 万个值的数组作为输入传递给这个函数时,性能会急剧下降。
当指针属于 50 万个数据点的数组时,性能会下降。
对于上述问题是否有任何替代解决方案,或者是否需要进行任何其他修改以提高性能?
谢谢
【问题讨论】:
-
伪代码没有说明问题,它甚至没有调用该代码中的 malloc。
-
即使是这样,您会使用什么替代的动态内存分配方式?
-
你说的是“函数”。哪个是“the”功能?您的问题非常缺乏重点和清晰度。
-
calculateLower() 是函数
-
@rak 功能相当广泛。你不能试着用一个例子来简化你的问题吗?我认为没有必要展示你所拥有的程序的一半。无论如何我无法理解你的问题。我想其他人也有同样的问题。只需创建一个可重现的最小示例并表达您的担忧。
标签: c linked-list malloc dynamic-arrays