-3

我正在制作一个程序来分析“道路”(图形的边缘)和“城市”(图形中的节点),然后为图形的每个连接子组件打印出最小生成树。

我不允许使用 STL 库,所以我必须实现自己的最小堆。我实现了一个模板最小堆,所以我可以创建一个最低成本道路的优先级队列。在堆的弹出操作中,它还对树进行重组,使顶部最小。当我制作一个 minHeap 时它工作得很好,但是现在我试图制作一个 minHeap 的道路,它给了我以下错误:

error: no match for 'operator<=' in 'lastE <= *(((minHeap<Road>*)this)->minHeap<Road>::heap + ((sizetype)(((unsigned int)child) * 16u)))'|

以及大量警告(见下文)。

下面是 minHeap 的代码:

#ifndef MIN_HEAP
#define MIN_HEAP

template<class T>
class minHeap{

public:
    minHeap(int);
    void push(const T&);
    void pop();
    T top();
    void doubleHeapCap();
    bool isEmpty();
    T *heap;
    int heapSize;
    int capacity;

};

#endif

template<class T>
minHeap<T>::minHeap(int theCapacity = 10){

    if(theCapacity < 1) throw "Capacity must be >=1.";
    capacity = theCapacity;
    heapSize = 0;
    heap = new T[capacity + 1]; //heap [0] is not used

}

template<class T>
void minHeap<T>::push(const T& e){
//inserts e into min heap
    if(heapSize == capacity){ //doubles capacity if Heap is too small
        this->doubleHeapCap();
        this->capacity *=2;
    }

    int currentNode = ++heapSize;

    while(currentNode != 1 && heap[currentNode/2] > e){
        //bubble up node
        heap[currentNode] = heap[currentNode/2]; //moves parent down
        currentNode /= 2; //moves current node
    }

    heap[currentNode] = e;

}

template<class T>
void minHeap<T>::pop(){
//Deletes smallest element from heap and restructures heap
    if(isEmpty()) throw "Heap is empty. Cannot delete.";

    //deelt smallest element
    heap[1].~T();

    //remove last element from heap
    T lastE = heap[heapSize--];

    //trickle down to restructure heap
    int currentNode = 1; //root of heap
    int child = 2; // first child of heap

    while(child <= heapSize){

        //set child to smaller child of currentNode
        if(child < heapSize && heap[child] > heap[child+1]) child++;

        //can we put lastE in currenNode?
        if(lastE <= heap[child]) break; //yes we can

        //no we can't, Obama
        heap[currentNode] = heap[child]; //move child up
        currentNode = child; child *= 2; // move a level down
    }

    //after you finally find one, place the node in the corrent position
    heap[currentNode] = lastE;
}

template<class T>
T minHeap<T>::top(){
    return heap[1];
}

template<class T>
bool minHeap<T>::isEmpty(){
//says whether or not hear is empty
    if(heapSize == 0) return 1;
    else return 0;
}

template<class T>
void minHeap<T>::doubleHeapCap(){

    int currentcapacity = this->capacity;
    int newCapacity = (this->capacity)*2;
    T *temp;
    T *newHeap;

    //create a new heap with twic the size
    newHeap = new T[newCapacity + 1];

    //copy elements over
    for(int i=0; i<=capacity; i++){
        newHeap[i] = this->heap[i];
    }

    //delete the old heap
    temp = heap;
    heap = newHeap;
    newHeap = 0;

    delete[] temp;
}

这是 main.cpp 的代码:

#include <iostream>
#include"road.h"
#include"region.h"
#include"minHeap.h"

using namespace std;

int main()
{

    int numCities;
    int numOldRoads;

    cin >> numCities;
    cin >> numOldRoads;

    minHeap<Road> roadHeap(numOldRoads);
    minHeap<Region> regionHeap(numCities);

    for(int i=0; i<numOldRoads; i++){
        int tempCityA, tempCityB;
        double tempLength;

        cin >> tempCityA;
        cin >> tempCityB;
        cin >> tempLength;

        cout << "NEW ROAD: " << tempCityA << " " << tempLength << " " << tempCityB << endl;

        Road *road = new Road;

        road->setCityA(tempCityA);
        road->setLength(tempLength);
        road->setCityB(tempCityB);

        roadHeap.push(*road);
    }

    for(int i=1; i<=roadHeap.heapSize; i++){
        Road tempRoad;

        tempRoad = roadHeap.top();
        roadHeap.pop();

        cout << "ROAD: " << tempRoad.getCityA() << " " << tempRoad.getLength() << " " << tempRoad.getCityB();
    }

    return 0;
}

这是 road.h 的代码:

#ifndef ROAD_H
#define ROAD_H

class Road{

public:
    void setCityA(int);
    const int getCityA() const;

    void setCityB(int);
    const int getCityB() const;

    void setLength(double);
    const double getLength() const;

    friend bool operator<(const Road&, const Road&);
    friend bool operator>(const Road&, const Road&);
    friend bool operator>=(const Road&, const Road&);
    friend bool operator>=(const Road&, const Road&);

private:
    int cityA;
    int cityB;
    double length;



};

#endif

这是 road.cpp 的代码(我重载了它说我没有的运算符):

#include"road.h"

void Road::setCityA(int x){
    this->cityA = x;
}

const int Road::getCityA() const{
    return this->cityA;
}

void Road::setCityB(int x){
    this->cityB = x;
}

const int Road::getCityB() const{
    return this->cityB;
}

void Road::setLength(double x){
    this->length = x;
}

const double Road::getLength() const{
    return this->length;
}

bool operator<(const Road &lhs, const Road &rhs)
{
    if(lhs.getLength() < rhs.getLength()) return 1;
    else return 0;
}

bool operator>(const Road &lhs, const Road &rhs)
{
    if(lhs.getLength() > rhs.getLength()) return 1;
    else return 0;
}

bool operator<=(const Road &lhs, const Road &rhs)
{
    if(lhs.getLength() <= rhs.getLength()) return 1;
    else return 0;
}
bool operator>=(const Road &lhs, const Road &rhs)
{
    if(lhs.getLength() >= rhs.getLength()) return 1;
    else return 0;
}

我只是努力让操作员工作(不得不处理 const 错误和诸如“cv-qualifiers and junk”之类的东西)。无论如何,在最终让它工作之后,我认为这将是复制、粘贴和修改的问题在长度上操作的运算符,但它给了我这个奇怪的错误,说我没有定义 <= 运算符

它似乎也奇怪地引用了右手边,为什么它会这样引用它?

*(((minHeap<Road>*)this)->minHeap<Road>::heap + ((sizetype)(((unsigned int)child) * 16u)))

最后这里是完整的构建消息,我觉得这里有很多信息,但是太新了,我似乎无法解析它:

warning: 'bool operator>=(const Road&, const Road&)' is already a friend of class 'Road' [enabled by default]
In instantiation of 'void minHeap<T>::pop() [with T = Road]':
|required from here
error: no match for 'operator<=' in 'lastE <= *(((minHeap<Road>*)this)->minHeap<Road>::heap + ((sizetype)(((unsigned int)child) * 16u)))'
note: candidates are:
note: template<class _T1, class _T2> bool std::operator<=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
note:   template argument deduction/substitution failed:
note:   'Road' is not derived from 'const std::pair<_T1, _T2>'
note: template<class _Iterator> bool std::operator<=(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
note:   template argument deduction/substitution failed:
note:   'Road' is not derived from 'const std::reverse_iterator<_Iterator>'
note: template<class _IteratorL, class _IteratorR> bool std::operator<=(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
note:   template argument deduction/substitution failed:
note:   'Road' is not derived from 'const std::reverse_iterator<_IteratorL>'
note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<=(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
note:   template argument deduction/substitution failed:
note:   'Road' is not derived from 'const std::basic_string<_CharT, _Traits, _Alloc>'
note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<=(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
note:   template argument deduction/substitution failed:
note:   'Road' is not derived from 'const std::basic_string<_CharT, _Traits, _Alloc>'
note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<=(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
note:   template argument deduction/substitution failed:
note:   mismatched types 'const _CharT*' and 'Road'
In instantiation of 'void minHeap<T>::doubleHeapCap() [with T = Road]':
required from 'void minHeap<T>::push(const T&) [with T = Road]'
required from here
warning: unused variable 'currentcapacity' [-Wunused-variable]
4

1 回答 1

2

您的标题有:

friend bool operator>=(const Road&, const Road&);
friend bool operator>=(const Road&, const Road&);

其中之一应该是<=

编者按:这个问题是制作SSCCE会立即向您显示问题并保存您在此处发布问题的问题。

于 2013-07-20T06:08:28.623 回答