У меня есть файл, который имеет номер один, и я хочу выполнить алгоритм сканирования (лифт), чтобы вычислить общее расстояние.
размер очереди равен 32, а общая строка данных - 35691
левый конец - 0
и правый конец - 59999
ex:
queue size is 3
start from 0
left end is 0
right end is 255
all request:30, 150, 30, 10, 70
1.
head:0
quene:30, 150, 30
distance:0
2.
head:30
quene:150, 30, 10
distance:30
3.
head:30
quene:150, 10, 70
distance:30
4.
head:70
quene:150, 10
distance:70
5.
head:150
quene:10
distance:150
6.
head:10
quene:
distance:500(150 to right end 255 and come back to 10 --> 150 + (255 - 150) * 2 + (150 - 10))
то, что я делаю, это следующий код, я использую multi set для его сохранения,
the first stage I fill up the queue
the second stage I insert the next element first
if the direction is right now
to see whether there is element next to the current, if not, change the direction, else keep right moving.
if the direction is left now
do the same thing above but go to left
the third stage I will calculate the remaining element in the queue.
Я столкнулся с проблемой - это расстояние, которое я вычисляю в
second stage is larger the result
поэтому может быть что-то не так. И я думаю, что то, что я думаю, прав, и я не могу понять
где ошибка.
Конечным результатом будет 33055962.
И код:
#include <iostream>
#include <fstream>
#include <string>
#include <set>
const int dataSize = 35691;
const int queueSize = 32;
const int minNumber = 0;
const int maxNumber = 59999;
using namespace std;
int number = minNumber;
int direction = 1;// right
int distanceSum = 0;
multiset<int> myset;
multiset<int>::iterator it;
multiset<int>::iterator temp;
multiset<int>::iterator next;
void print(void);
int main(int argc, char const *argv[]){
ifstream myfile("sort");
if (myfile.is_open()){
// ===============================initialization===============================
for(int i = 0; i < queueSize; i ++){
myfile >> number;
myset.insert(number);
}
it = myset.begin();
int last = minNumber;
int current = *it;
// ===============================middle stage===============================
for(int i = 0; i < dataSize - queueSize; i ++){
myfile >> number;
myset.insert(number);
current = *it;
if(direction == 1){// right
next = it;
next ++;
if(next == myset.end()){// right most
direction = 0;// change direction
distanceSum += ((maxNumber - current) * 2 + (current - last));
temp = it;
it --;
myset.erase(temp);
last = current;
}
else{
distanceSum += (current - last);
temp = it;
it ++;
myset.erase(temp);
last = current;
}
}
else if(direction == 0){// left
if(it == myset.begin()){// left most
direction = 1;// change direction
distanceSum += ((current - minNumber) * 2 + (last - current));
temp = it;
it ++;
myset.erase(temp);
last = current;
}
else{
distanceSum += (last - current);
temp = it;
it --;
myset.erase(temp);
last = current;
}
}
}
// ===============================remaining===============================
// for(int i = 0; i < queueSize; i ++){
// current = *it;
// if(direction == 1){// right
// next = it;
// next ++;
// if(next == myset.end()){
// direction = 0;
// if(myset.size() == 1)distanceSum += (current - last);
// else distanceSum += ((maxNumber - current) * 2 + (current - last));
// temp = it;
// it --;
// myset.erase(temp);
// last = current;
// }
// else{
// distanceSum += (current - last);
// temp = it;
// it ++;
// myset.erase(temp);
// last = current;
// }
// }
// else if(direction == 0){
// if(it == myset.begin()){
// direction = 1;
// if(myset.size() == 1)distanceSum += (last - current);
// else distanceSum += ((current - minNumber) * 2 + (last - current));
// temp = it;
// it ++;
// myset.erase(temp);
// last = current;
// }
// else{
// distanceSum += (last - current);
// temp = it;
// it --;
// myset.erase(temp);
// last = current;
// }
// }
// }
myfile.close();
}
else cout << "Unable to open file";
print();
cout << "distanceSum is :" << distanceSum << endl;
return 0;
}
void print(){
cout << "value:" << endl;
for(multiset<int>::iterator it = myset.begin(); it != myset.end(); it ++){
cout << *it << "\t";
}
cout << endl;
cout << "current point to:" << *it << endl;
cout << "total size is:" << myset.size() << endl;
cout << "current distance:" << distanceSum << endl;
}
и тестовые данные:
https://drive.google.com/file/d/0ByMlz1Uisc9ONWJIdFFXaGdpSXM/edit?usp=sharing
вы должны сохранить его как filename 'sort'
Я прочитал ваш алгоритм три раза сейчас, и единственная ошибка, которую я могу найти, - это когда вы читаете одно и то же значение. Учти это,
Вы вставляете новый элемент в очередь, который также является позицией "300".
Now in the multiset implementation according to this SO answer
(http://stackoverflow.com/q/2643473) depending on the implementation
the value can either go right to your present value(C++ 0x) or can go
anywhere(C++03).
Итак, если вы находитесь в позиции 300 и предположите, что новое значение вставлено в правую сторону вашего текущего значения в мультимножестве.
Такая же ошибка возникает, когда вы находитесь на правой стороне, и то же значение вставлено в левой части вашего текущего значения.
Вот иллюстрация этого, используя queuesize of 3.
Рассмотрим, что ваша очередь мультисети имеет значения (300,700,900) и оставшееся направление = 0. Numebr со звездой справа указывает, где итератор. предположим totalSweepDistance = 0 в это время.
Решение
Одним из возможных решений является добавление нового значения в очередь, которое совпадает с текущим значением. Проверяйте одно место справа от текущего положения, когда вы двигаетесь влево, и проверяйте одно место слева от текущей позиции, когда вы двигаетесь вправо для вставки того же значения.