【发布时间】:2018-06-16 08:19:09
【问题描述】:
几天前,我请你为我的问题选择最好的数据结构。在那段时间我也解释了我的问题并描述了它:
Self-organising sequence of numbers with big amount of operations on it - best data structure
我已经实现了它,但不幸的是它无法通过一些测试。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int allCharCounter = 0;
struct List_node{
int value;
struct List_node *next;
struct List_node *prev;
};
//inserting at first
void insert(List_node** start, int v){
List_node* newNode = new List_node;
newNode->value = v;
if(*start == NULL){
newNode->next = newNode;
newNode->prev = newNode;
*start = newNode;
}else{
newNode->next = *start;
newNode->prev = (*start)->prev;
(*start)->prev->next = newNode;
(*start)->prev = newNode;
}
}
//getting input
int getNumber(){
int c = getchar_unlocked();
int value = 0;
for(; (c < 48 || c > 57); c = getchar_unlocked());
for(; c > 47 && c < 58 ; c = getchar_unlocked()){
value = 10*value+c-'0';
allCharCounter++;
}
return value;
}
int main(){
int numberOfOperations = getNumber();
struct List_node* list = NULL;
//counter of numbers
int numbersInSeq = 0;
//passing values to list
while(!feof(stdin)){
int number = getNumber();
insert(&list, number);
numbersInSeq++;
}
if(list !=NULL){
while(numberOfOperations-- != 0){
int c = list->value;
//insert - X
if(c & 1){
List_node* newNode = new List_node;
newNode->value = c-1;
newNode->prev = list;
newNode->next = list->next;
list->next->prev = newNode;
list->next = newNode;
numbersInSeq++;
int moveNext = c%numbersInSeq;
//int movePrev = numbersInSeq - moveNext;
for(int i = 0; i < moveNext; i++){
list = list->next;
}
}else{
//remove - R
c = list->next->value;
List_node* tmp = list->next;
list->next = tmp->next;
list->next->prev = list;
tmp->next = NULL;
tmp->prev = NULL;
free(tmp);
numbersInSeq--;
int moveNext = c%numbersInSeq;
//int movePrev = numbersInSeq - moveNext;
//moving my list (POS)
for(int i = 0; i < moveNext; i++){
list = list->next;
}
}
}
//printing output
for(int i = 0; i < numbersInSeq; i++){
fprintf(stdout, "%d",list->value);
if(i != numbersInSeq-1){
fprintf(stdout, "%c",' ');
}
list = list->next;
}
}else{
//in case of empty list return -1
fprintf(stdout, "%d", -1);
}
fprintf(stdout, "%c",'\n');
fprintf(stdout, "%d",allCharCounter);
}
这段代码使用循环双向链表,输出总是正确的,但正如我之前所说,对于某些测试来说它太慢了。您还可能看到我错误地实现了仅使用 next 移动列表(POS)。所以我想出了这个:
int moveNext = c%numbersInSeq;
int movePrev = numbersInSeq - moveNext;
if(moveNext < movePrev){
for(int i = 0; i < moveNext; i++){
list = list->next;
}
}else{
for(int i = 0; i < movePrev; i++){
list = list->prev;
}
}
在 X 和 R 方法中递增和递减 numbersInSeq 后立即注入。变量 moveNext 是使用 next 将指针移动到所需位置所需的迭代次数。所以它和 numbersInSeq 的区别在于 prev 的移动。因此,我知道什么更有效,使用 next 或 prev 移动它。
我已经用 50 位数字对它进行了测试,输出是正确的。迭代次数较少:
无 - 13001
与 - 570
它不仅没有通过一个测试,而且它对于另一个测试来说太慢了(虽然我不知道里面到底有什么,但我可以告诉你那个文件的大小在34mb)。
也许你可以看到我在这里错过的/写得不好/不知道结构的东西。是否可以以某种方式优化我的代码以更快?
【问题讨论】:
-
如果你说这行得通,但不够快,那么也许你想要codereview.stackexchange.com
标签: c++ algorithm performance optimization linked-list