Results 1 to 5 of 5

Thread: Using Qt to generate stringlist combinations

  1. #1
    Join Date
    Mar 2012
    Posts
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Using Qt to generate stringlist combinations

    Hi

    How can I use Qt to write a function “nemely, generator” that returns combinations of argument sequences “string lists” e.g. combine((‘A’,‘B’),(†˜1’,‘2’,‘3’)) will return [(‘A’,‘1’), (‘A’,‘2’), (‘A’,‘3’), (‘B’,‘1’), (‘B’,‘2’), (‘B’,‘3’)] on demand by calling next() or something i.e. the function will not create the whole list of combinations in memory at once.
    The function is to be applicable to any number of sequences i.e. combine(Sequence1, Sequence2, Sequence3, …)

    Can anybody help me?

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Using Qt to generate stringlist combinations

    I do not see any specific problem. First try to generate the list at whole. If you have managed that, simply store the index positions of each list in a member function the class and then you can simply implement a next function.
    Qt Code:
    1. class Generator
    2. {
    3. public:
    4. void init(/*QStringList's*/) {
    5. // set up indexes here e.g.
    6. m_index = 0;
    7. }
    8.  
    9. QString next() {
    10. // calculate m_index and return the composed string.
    11. }
    12. private:
    13. quint32 m_index;
    14. };
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Mar 2012
    Posts
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Using Qt to generate stringlist combinations

    Hi Lykurg

    Thanks for the reply;
    "First try to generate the list at whole"

    I would follow this but, however, the number of sequences is not predictable at that is why I must not generate the whole list in memory at once, do you have any solid idea how this can be done?

    Thanks again

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Using Qt to generate stringlist combinations

    What Lykurg means is that once you know how to generate the entire list, it is relatively simple to take that apart and do it step-wise (that is, using a "next" iterator). By the way, you also need something like an atEnd() or hasNext() so you know when you've reached the end of the list.

    So, I would do something like this:

    Qt Code:
    1. // Sequencer.h:
    2.  
    3. class Sequencer
    4. {
    5. public:
    6. Sequencer() {}
    7.  
    8. void initialize( const QVector < QStringList > & stringLists )
    9. {
    10. // store input strings into internal storage, reset indexes
    11. sequences = stringLists;
    12. currentIndexes.resize( sequences .size() );
    13. sequenceLengths.resize( sequences .size() );
    14.  
    15. // store the size of each subsequence
    16. // The currentIndexes array is used by next() to keep track
    17.  
    18. for ( int i = 0; i < sequences .size(); ++i )
    19. {
    20. sequenceLengths[ i ] = sequences[i].size();
    21. currentIndexes[ i ] = 0;
    22. }
    23. }
    24.  
    25. QStringList next()
    26. {
    27. // Always increment the last index first; when it overflows, set it to zero
    28. // then try to increment the second to last, etc. When all indexes are at their
    29. // max value, then return an empty result
    30.  
    31. QStringList result;
    32.  
    33. // Before doing anything, make sure we can
    34. if ( hasNext() )
    35. {
    36. for ( int index = sequences .size() - 1; index >= 0; --index )
    37. {
    38. // Check to see if we have overflowed the index at the current level
    39. if ( currentIndexes[ index ] + 1 < sequenceLengths[ index ] - 1 )
    40. {
    41. // OK to increment, so we do that and quit
    42. currentIndexes[ index ]++;
    43. break;
    44. }
    45. else
    46. {
    47. // Set it to zero, and try the next index down
    48. currentIndexes[ index ] = 0;
    49. }
    50. }
    51.  
    52. // Assemble the output sequence
    53. for ( int index = 0; index < sequences.size(); ++index )
    54. result << sequences[ index ][ currentIndexes[ index ] ];
    55. }
    56. return result;
    57. }
    58.  
    59. // The sequence can be continued only if all indexes are less than the size
    60. // of the respective subsequence AND the last index can still be incremented
    61. bool hasNext() const
    62. {
    63. bool bHasNext = true;
    64. for ( int index = 0; index < sequences.size(); ++index )
    65. bHasNext &= (currentIndexes[ index ] < sequenceLengths[ index ]);
    66. bHasNext &= (currentIndexes[ sequences.size() - 1 ] + 1 < sequenceLengths[ sequences.size() - 1 ]);
    67. return bHasNext;
    68. }
    69.  
    70. // Rest the counters so we can produce the same sequence again
    71. void reset()
    72. {
    73. for ( int index = 0; index < sequences.size(); ++index )
    74. currentIndexes[ index ] = 0;
    75. }
    76.  
    77. private:
    78. QVector< QStringList > sequences;
    79. QVector< int > sequenceLengths;
    80. QVector< int > currentIndexes;
    81. };
    To copy to clipboard, switch view to plain text mode 

    Haven't compiled or tested this, so use at your own risk.

    If you want to "recycle" the sequence, then just rewrite hasNext() to always return true, and the next() method will simply reset all the indexes to zero once it reaches the end and start over. If you wanted to start at a random place in the sequence instead of always at the beginning, you could write a randomize() method that sets each of the currentIndexes[n] entries to a random number between zero and sequences[n].size() - 1.

    You could also implement hasNext() to simply multiply all of the currentIndexes[n] values together and all of the sequenceLength[n] together. If the total for the first product is less than the total for the second, then hasNext() is true. However, if the number of sequences that can be generated is very large, then this could overflow the size of an int or long and give an incorrect result. The way I implemented it is less efficient but will never overflow.
    Last edited by d_stranz; 17th March 2012 at 22:05.

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Using Qt to generate stringlist combinations

    @kalma: I know you've read this. You're welcome.

Similar Threads

  1. Keyboard combinations in QTableWidget
    By enricong in forum Qt Programming
    Replies: 2
    Last Post: 18th October 2011, 13:29
  2. Stringlist model plugin in qml
    By songthanjp in forum Qt Programming
    Replies: 1
    Last Post: 25th April 2011, 11:14
  3. Capture key & key combinations from keyboard
    By aikidorb in forum Qt Programming
    Replies: 3
    Last Post: 5th June 2010, 13:13
  4. Aligning a stringlist
    By impeteperry in forum Qt Programming
    Replies: 1
    Last Post: 22nd May 2006, 17:45
  5. Sorting a StringList
    By Jimmy2775 in forum Qt Programming
    Replies: 4
    Last Post: 10th February 2006, 22:11

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.