简体   繁体   中英

Using struct with an insertion sort

I'm having some trouble with an insertion sort, passing in data from a struct. It's returning the error: |98| cannot convert 'store' to 'int' in assignment.

struct store{
    char tag[5];
    int cost;
    long int volume;
};


void costSort(store storedEntries[], int count);
void volumeSort(store storedEntries[], int count);

int main(){

    store record[100];
    ifstream fin;
    char choice;
    int count = 0;

    fin.open("stockdata.txt");

    //file read in
    if(fin.good())
    {
        while(!fin.eof())
        {
            fin >> record[count].tag;
            fin >> record[count].cost;
            fin >> record[count].volume;
            count++;
        }
    count--;
    }


    cout << "Main Menu:" << endl;
    cout << "c: sort data by Cost\nv: sort data by trade Volume\nq: Quit\nEnter Choice: ";

    cin >> choice;

    switch(choice)
    {
        case 'C':
        case 'c': //costSort(record, count);
            break;
        case 'V':
        case 'v': volumeSort(record, count);
            break;
        case 'q':
        case 'Q': return 0;
            break;
    }
   return 0;
}

void volumeSort(store record[], int count)
{
    int p = 0, item = 0;

    for(int i=1; i<count; i++){
    cout << "test";
        item = record[i];
        p = (i - 1);
        while(p>=0 && item < record[p]){
            record[p+1] = record[p];
            p--;
        }
        record[p+1] = item;
        cout << record[i].tag << " " << record[i].volume << endl;
    }

}

The insertion sort is in the function void volumeSort(). Any advice would be appreciated, i haven't had any issues up until now :S

You are trying to compare a int with a store .

This will not work unless you overload < operator to compare a int and a store .

store record[];
int p = 0, item = 0;
//[...]
while (p >= 0 && item < record[p])
//Neither can you assign that
record[p + 1] = item;

Operator example:

bool operator<(const int &left, const store &s)
{
    //You could also do some calculation in here,
    //if you want to compare a value inside the struct
    //like this:
    return left < s.cost;
    //Please... do it in place.
    //item < record[p].cost;
}

You're comparing non-like types with no operator provided to support the comparison (and none needed if this is done correctly). Currently you're comparing int to store . What you should be comparing is two volume members of two store objects.

A simple loop that is probably closer to what you want would be something like this:

// note: count is size_t, an unsigned magnitude. only used signed
//  integer types where it makes sense a negative integer will be
//  plausible input.
void volumeSort(store record[], size_t count)
{
    for(size_t i=1; i<count; ++i)
    {
        // compare current element to one below us, swapping if needed
        // and stopping as soon as we reach an equal or lesser record
        size_t j=i;
        while(j>0 && record[j].volume < record[j-1].volume)
        {
            std::swap(record[j-1], record[j]);
            --j;
        }
    }
}

Or something similar. Note the comparison of:

record[j].volume < record[j-1].volume

in the while condition. Apples to apples...


For an interesting insertion_sort that utilizes two wonderful features of the standard library, std::upper_bound and std::rotate , a rather dense version of the function can be created, looking something like this:

void insertion_sort(store record[], size_t len)
{
    for (auto it = record; it != record+len; ++it)
    {
        std::rotate(std::upper_bound(record, it, *it,
            [](const store& lhs, const store& rhs) { return lhs.volume < rhs.volume; }),
            it, std::next(it));
    }
}

This is considerably more efficient than it first may seem, as the search for the proper placement of the prospect element is done in O(logN) using std::upper_bound . Then std::rotate opens the hole where the element goes and it is swapped into place.

Just some food for thought. Coupled with the comparator that is going to inlined by even remedial optimization and it has a lot more punch than you may first think. Still not as kick-ass as std::sort , usually highly optimized utilizing multiple algorithms, but still good brain food.

Best of luck.

if you want to sort by volume you should take record[i].volume even when comparing...the types should be same when comparing values..

Similarly for other cases..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM