Results 1 to 10 of 10

Thread: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

  1. #1
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    Hi,
    I wanted to have a numbering scheme for columns like the one provided by Office calculation programs.

    My approach so far is this:

    Qt Code:
    1. #include <QList>
    2. #include <QStringList>
    3. #include <QDebug>
    4.  
    5. QString getLabelFromInt(uint digit)
    6. {
    7. uint base = 26;
    8.  
    9. uint remainder;
    10. uint quotient = digit;
    11.  
    12. QList<int> l;
    13. do {
    14. remainder = quotient % base;
    15. quotient = quotient / base;
    16. l.prepend(remainder);
    17. } while (quotient != 0);
    18.  
    19. QStringList strList;
    20. for (int i = 0; i < l.size(); ++i)
    21. strList << QString(char(l[i] + 'a'));
    22.  
    23. return strList.join("");
    24. }
    25.  
    26. int main(int argc, char** arg) {
    27. for (int i = 0; i < 200; ++i)
    28. qDebug() << getLabelFromInt(i);
    29. }
    To copy to clipboard, switch view to plain text mode 
    but it generates a-z but then continues with ba - zz and then baa - zzz. Considering an alphabet with two symbols (0 and 1) it would have to go like this:

    0
    1
    00
    01
    10
    11
    000
    001
    010
    011
    100
    101
    110
    111

    instead of
    0
    1
    10
    11
    100
    101
    110
    111

    Of course I see the pattern: the first one has 2^3+2^2+2^1 elements (since it includes the preceding combinations) while the second (normal) one has 2^3 elements but I can't put the pieces together.
    Is there a simple way to implement this?

    Thanx in advance
    momesana
    Last edited by momesana; 3rd December 2009 at 16:44.

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    Ok, solved it myself in an ugly and hackish way. If someone knows a better way to do it, let me know!

    Qt Code:
    1. #include <QList>
    2. #include <QStringList>
    3. #include <QDebug>
    4. #include <QList>
    5. #include <iostream>
    6. #include <cmath>
    7.  
    8. QString getLabelFromInt(int digit)
    9. {
    10. // TODO base should be based on the actual number
    11. // of letters in the locale of the user
    12. int base = 26;
    13. int n = 1;
    14. int tmp = base;
    15. int prevTmp = 0;
    16.  
    17. while ((tmp - 1) < digit) {
    18. ++n;
    19. prevTmp = tmp;
    20. tmp += std::pow(base, n);
    21. };
    22.  
    23. digit -= prevTmp;
    24.  
    25. uint remainder;
    26. uint quotient = digit;
    27. QList<int> l;
    28. do {
    29. remainder = quotient % base;
    30. quotient = quotient / base;
    31. l.prepend(remainder);
    32. } while (quotient != 0);
    33.  
    34. QStringList strList;
    35. for (int i = 0; i < l.size(); ++i)
    36. strList << QString(char(l[i] + 'a')); // TODO make this work for other locales as well
    37.  
    38. for (int i = 0; i < n - l.size(); ++i)
    39. strList.prepend(QString('a')); // TODO make this work for other locales as well
    40.  
    41. return strList.join("");
    42. }
    43.  
    44.  
    45. int main(int argc, char** arg) {
    46. for (int i = 0; i < 10000; ++i)
    47. qDebug() << getLabelFromInt(i);
    48.  
    49. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    Here is an improved version if anyone ever happens to need that code. If it shouldn't work for whatever reason use the code I posted first:

    Qt Code:
    1. QString getLabelFromInt(int index) const
    2. {
    3. int base = 26;
    4. int n = ((log10((index + 1) * (base - 1) + 1)) / log10(base));
    5. qMin(n, 1);
    6. index -= ((pow(base, n) - 1) / (base - 1)) - 1;
    7.  
    8. int quotient = index;
    9. QList<int> intList;
    10. do {
    11. intList.prepend(quotient % base);
    12. quotient = quotient / base;
    13. } while (quotient != 0);
    14.  
    15. QString str;
    16. for (unsigned i = 0; i < n - intList.size(); ++i)
    17. str += 'a';
    18.  
    19. QList<int>::const_iterator iter;
    20. for (iter = intList.begin(); iter != intList.end(); ++iter)
    21. str += *iter + 'a';
    22.  
    23. return str;
    24. }
    To copy to clipboard, switch view to plain text mode 
    and here is the C++ version without Qt


    Qt Code:
    1. string getLabelFromInt(int index)
    2. {
    3. int base = 26;
    4. int n = ((log10((index + 1) * (base - 1) + 1)) / log10(base));
    5. n = (n < 1) ? 1 : n;
    6. index -= ((pow(base, n) - 1) / (base - 1)) - 1;
    7.  
    8. int quotient = index;
    9. list<int> intList;
    10. do {
    11. intList.push_front(quotient % base);
    12. quotient = quotient / base;
    13. } while (quotient != 0);
    14.  
    15. string str;
    16. for (unsigned i = 0; i < n - intList.size(); ++i)
    17. str += 'a';
    18.  
    19. list<int>::const_iterator iter;
    20. for (iter = intList.begin(); iter != intList.end(); ++iter)
    21. str += *iter + 'a';
    22.  
    23. return str;
    24. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by momesana; 4th December 2009 at 05:24.

  4. #4
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    Succumbed to the optimization devil inside me :-D. No one will ever use this code or probably even read this post but anyway, here is the (so far) final version:

    Qt Code:
    1. QString getLabelFromInt(int index, char startingChar, int base)
    2. {
    3. double n = log10((index + 1) * (base - 1) + 1) / log10(base);
    4. index -= ((pow(base, (int) n) - 1) / (base - 1)) - 1;
    5.  
    6. QString result((int) n, QChar(startingChar));
    7. int quotient = index;
    8. int strIndex = result.length();
    9. do {
    10. result[--strIndex]= QChar(startingChar + quotient % base);
    11. quotient = quotient / base;
    12. } while (quotient != 0);
    13.  
    14. return result;
    15. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by momesana; 4th December 2009 at 18:22.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    I read all the posts in this thread

    The only thing that bothers me is that you are assuming that all characters for the symbols form a sequence. That's never the case for non-ascii alphabets, I'm afraid. Maybe it'd be better to pass an array of symbols?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    Quote Originally Posted by wysota View Post
    I read all the posts in this thread

    The only thing that bothers me is that you are assuming that all characters for the symbols form a sequence. That's never the case for non-ascii alphabets, I'm afraid. Maybe it'd be better to pass an array of symbols?
    Yes, already realized that yesterday when I thought about making this work with arabic-like alphabets (I am persian and we use an alphabet based on arabic) and realized that you can't iterate over QChar and that the only viable solution is to provide a list, vector or something with the unicode characters in the correct order.

    Thanks for the feedback :-)
    Last edited by momesana; 4th December 2009 at 19:03.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    You could change your code in a way similar to this:

    Qt Code:
    1. class IndexIterator {
    2. public:
    3. IndexIterator(...) {}
    4. QString nextIndex() {
    5. //... main part of your code goes here
    6. }
    7. virtual QChar nextCharacter() = 0;
    8. virtual void resetIterator() = 0;
    9. };
    10.  
    11. class AsciiIndexIterator : public IndexIterator {
    12. public:
    13. AsciiIndexIterator(...) : IndexIterator(...), m_current('A'){}
    14. QChar nextCharacter() {
    15. if(m_current=='Z') return QChar();
    16. return m_current++;
    17. }
    18. void resetIterator() { m_current = 'A'; }
    19. private:
    20. char m_current;
    21. };
    To copy to clipboard, switch view to plain text mode 

    You can then tell your code to use nextCharacter() to get the next character in sequence until you receive a null character. Then you know you've run out of characters and should call resetIterator() to go back to the first element of the sequence.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    Interesting approach wysota. Will try that in the coming days. Meanwhile I found some bugs in the above code I had posted which is mainly due to floating point precision issues that causes a variable of type double with a value of (approximately) three to be turned into two when being casted to an int. Well, you guys probably all have read http://docs.sun.com/source/806-3568/ncg_goldberg.html but I hadn't so I wasted hours debugging this mysterious problem that turned up about 30 times for 500000 inputs.

    Here is the updated version which takes an alphabet as a parameter in form of a QList<QChar>. It's still an unsatisfying solution for something like persian where letters are being joined and change their shape when put into a string. Thus, how to handle the resulting string (accessing the individual chars and render them separately or inserting whitespaces between the chars) is the job of the user of this function. Anyway, maybe it turns out to be useful to someone :-).

    Qt Code:
    1. QString getLabelFromInt(int index, QList<QChar>& alphabet, int base)
    2. {
    3. // Alphabet should have at least two elements
    4. if (alphabet.size() < 2)
    5. return QString();
    6.  
    7. if (base < 2 || base > alphabet.size())
    8. base = alphabet.size();
    9.  
    10. double tmp = log10((index + 1) * (base - 1) + 1) / log10(base);
    11. int n = (int)floor(tmp + sqrt(numeric_limits<double>::epsilon()));
    12. index -= ((pow(base, n) - 1) / (base - 1)) - 1;
    13.  
    14. QString result(n, alphabet[0]);
    15. int quotient = index;
    16. int strIndex = result.length();
    17. do {
    18. result[--strIndex] = alphabet[quotient % base];
    19. quotient = quotient / base;
    20. } while (quotient != 0);
    21.  
    22. return result;
    23. }
    To copy to clipboard, switch view to plain text mode 

  9. #9
    Join Date
    Oct 2009
    Location
    Mexico
    Posts
    81
    Thanks
    6
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    a better way using Qt using ASCII caracters.


    QString getLabelFromInt(int number)
    {
    return QString::number(number,36);
    }

    using base 36 to convert a number to string, include the number 0-9 and a-z caracters



    y try to find a more compact, but i think is not possible
    Last edited by ecanela; 14th December 2009 at 16:23. Reason: updated contents

  10. #10
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Creating Column numbering like in Excecl i.e. A...Z then AA ... ZZ and so forth

    I don't see how that would solve the problem at hand. The code is not about mere base conversion in conjunction with turning the result into a string. Just compare your results with the ones provided by my function.
    Last edited by momesana; 13th February 2010 at 11:23.

Similar Threads

  1. Replies: 0
    Last Post: 10th November 2006, 13:46
  2. hidden QListView column suddenly visible
    By edb in forum Qt Programming
    Replies: 10
    Last Post: 27th January 2006, 08:00

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.