简体   繁体   中英

c++: how to shuffle a dynamic array of pointers?

I am shuffling songs for my program but im a little confused because when I try the compiler tells me I cant compare my struct to an int. Im wondering what yall might think?

struct Songs                 //my struct
{
string title;     
string artist;
string mem;  
};

Songs *ptr;
ptr = new Songs[25];    //dynamic array

so i told u the struct and ptr well heres the function im experiencing trouble..

void shuffle (Songs song[], Songs *ptr, string title, string mem, string  artist, int num)
{

 for (int i=0; i<(num); i++) 
 {
     int r = i + (rand() % (num-i)); // Random remaining position.
     int temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;  //this isnt working
 }                                                     //but its logically sound?   

 for (int c=0; c<n; c++) 
 {
     cout << ptr[c] << " ";  // Just print 
 }      
}

The offending code is at int temp = ptr[i]; ... ptr[r] = temp; int temp = ptr[i]; ... ptr[r] = temp; , you're assigning Song and int which is not possible.

Additionally , I strongly suggest using std::vector< Song > for storage. Your code is more robust and will crash less likely, plus the vector always knows the number of Songs it contains. Example

#include <vector>
...
struct Song { ... };
...
void shuffle(std::vector< Song >& mySongs, ...)
{
   /* shuffle mySongs somehow. */
   ...
}

mySongs.size() contains the number of songs, and you can access each song with mySongs[index] (or better mySongs.at(index) ) as expected. Adding new songs is done by mySongs.push_back(someSong) .

Now to your question : How do I shuffle my vector of songs. Well ...

/* at start of program. */
srand(unsigned(time(NULL)));
...
void shuffle(std::vector< Song >& mySongs)
{
    std::random_shuffle(mySongs.begin(), mySongs.end());
}

does the trick. See here .

Writing a song to a stream can be done by defining a function like this:

std::ostream& operator << (std::ostream& osr, const Song& mySong)
{
    osr << mySong.title << ' ' << mySong.artitst << ' ' << mySong.mem;
    return osr;
}

Now you can happily do std::cout << mySong << std::endl .

You should really try to use more out of the standard library. With std::vector and std::random_shuffle this would be so much cleaner. Edit: Code now with output.

#include <iostream>
#include <ostream>
#include <algorithm>
#include <string>
#include <vector>

struct song
{
    std::string title;     
    std::string artist;
    std::string mem;  
};

std::ostream& operator << (std::ostream& stream, const song& s)
{
    return stream << "Song: { Title: " << s.title 
        << ", Artist: " << s.artist << ", Mem: " << s.mem;
}

template <typename T>
std::ostream& operator << (std::ostream& stream, const std::vector<T>& v)
{
    stream << '[';
    for (auto i = v.begin(); i != v.end(); ++i)
        stream << *i << ", \n";
    return stream << ']';
}
int main()
{
    std::vector<song> songs;
    // .push_back your songs
    std::random_shuffle(songs.begin(), songs.end());
    std::cout << songs;
}

You are trying to assign a Songs object to an int ( int temp = ptr[i]; ), and then you try to assign an int to a Songs ( ptr[r] = temp; ). That will not work. To make it work, I suggest you change the line to: Songs temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp; Songs temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;

Change:

int temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;

to

Songs temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;

Your original code tries to assign a Songs to an integer. You need to create a temporary of the same type as the object you are trying to assign it.

Well, why are you using an int to store the struct value? Just make it:

Songs temp;

Also, your type names are totally confusing, Songs seems to represent a single song.

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