-1

I really need your help with how to code this:

I have a file2 text file that contains number ranges that look like this:

12345678[5-8][0-9]
3684567150
329465207[023456789]
132478026[13]
778941351[02-689]
84364575[89][0-9]
88229401XX
981024833X
8912380XXX

So this number ranges break down like this:

12345678[5-8][0-9]:   1234567850-1234567889
3684567150:           3684567150
329465207[023456789]: 3294652070 and 3294652072-3294652079
132478026[13]:        1324780261 and 1324780263
778941351[02-689]:    7789413510, 7789413512-7789413516, 7789413518 and 7789413519
84364575[89][0-9]:    8436457580-8436457599
88229401XX:           8822940100-8822940199
981024833X:           9810248330-9810248339
8912380XXX:           8912380000-8912380999

Where the X can take values from 0 to 9. All these numbers are 10 digits. But the ranges may vary a lot sometimes, ranges that can be written as: [02-9] are written as: [023456789] and vice-versa.

I just need this part on how to read this as number ranges or maybe define cases like:

 XXXXXXXXX[X-X]
 XXXXXXXX[X-X][X-X]
 XXXXXXXXX[XX-X]
 XXXXXXXXX[XXXXXXXX]

etc. But don't have an idea on how to do that, I hope you can help me. Right now I just save the data from the file into a string vector:

ifstream file2("file2.txt");

    while (getline(file2,line) && line.size()>=0)
        vfile2.push_back(line);

Please don't leave alone I don't know how to even start, I've done more code for this but it has nothing to do with this part because it's not only that what the whole program is supposed to do if you need evidence to let me know.

Thank you!

UPDATED:

I have a file2 text file that contains number ranges that look like this:

88229401XX
981024833X
8912380XXX

So this number ranges break down like this:

88229401XX:           8822940100-8822940199
981024833X:           9810248330-9810248339
8912380XXX:           8912380000-8912380999

Thank you again for your help and time, I'm paralel working on this, if I figure it out (I might have some idea on how to) it will be posted inmediatly.

Carlos Pérez
  • 47
  • 1
  • 1
  • 9
  • 2
    First you need to think where you want to store the result. Is it container of numbers that match the pattern or pattern itself. Otherwise it remains unsure what you want to achieve after you have read the file. – Öö Tiib Sep 11 '18 at 06:08
  • Sorry I wasn't specific, now I know how to seek for help next time, kind of new to asking. Although, John's answer was pretty much what I was looking for, thank you too! – Carlos Pérez Sep 19 '18 at 04:15

1 Answers1

1

This is a parsing problem. There are tools to help you with parsing, but they have to be learned. Sometimes it's best to just dive in and write the code. It's not so hard if you are methodical about it. The trick is to make the structure of your code match the structure of the grammar you are parsing.

The following code assumes you want to store your integers in a vector. It just prints out the contents of that vector at the end.

The following code does no error checking of the input at all. In a real program that would be a serious problem. I'll leave you to add the error checking.

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdint>

typedef uint64_t int_type;

void parse(const std::string& line, std::vector<int_type>& numbers)
{
    numbers = { 0 };
    size_t i = 0;
    while (i < line.size())
    {
        char ch = line[i++];
        if (ch == '[')
        {
            // start a group
            std::string group;
            while (line[i] != ']')
            {
                char lo = line[i++];
                if (line[i] == '-')
                {
                    ++i;
                    char hi = line[i++];
                    while (lo <= hi)
                    {
                        group += lo;
                        ++lo;
                    }
                }
                else
                {
                    group += lo;
                }
            }
            ++i;
            // add the new numbers implied by the group
            std::vector<int_type> new_numbers;
            for (auto num : numbers)
            {
                for (auto digit : group)
                    new_numbers.push_back(10 * num + (digit - '0'));
            }
            numbers.swap(new_numbers);
        }
        else
        {
            std::transform(numbers.begin(), numbers.end(), numbers.begin(),
                [=](auto n) { return 10 * n + (ch - '0');  });
        }
    }
}

int main()
{
    std::string data = "12345678[5-8][0-9]\n"
        "3684567150\n"
        "329465207[023456789]\n"
        "132478026[13]\n"
        "778941351[02-689]\n"
        "84364575[89][0-9]\n";
    std::istringstream input(data);
    std::string line;
    while (getline(input, line) && line.size() >= 0)
    {
        std::vector<int_type> numbers;
        parse(line, numbers);
        for (auto num : numbers)
        {
            std::cout << num << '\n';
        }
        std::cout << '\n';
    }
}

Only briefly tested, but it seems to work.

john
  • 85,011
  • 4
  • 57
  • 81
  • Thank you very much @jhon I will test it at night when I get home and I will tell you if it works, for what I've seen it looks pretty great, even if it doesn't fulfill my needs due to lack of information or whatever you just gave me a great idea from where I can start now. I will update you with the full code, what is does. – Carlos Pérez Sep 11 '18 at 19:30
  • Hello @Jhon I've been checking the code but I don't understand what does this line does: `std::transform(numbers.begin(), numbers.end(), numbers.begin(), [=](auto n) { return 10 * n + (ch - '0'); });` To be more specific this one: `[=](auto n) { return 10 * n + (ch - '0'); });` Hope you can help me to understand it. Thank you! – Carlos Pérez Sep 12 '18 at 03:57
  • @CarlosPérez It's a [lambda function](https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11), which is just another way of saying that it's an unnamed function. Transform calls the function on each element of `numbers` passing the element as the parameter `n` and replacing the element with the return value of the function. – john Sep 12 '18 at 06:25
  • hey it's me again, sorry I haven't replied for a while, I've been very busy with work, school and september 15th celebrations (I'm mexican btw). The main program is almost done, I will update my question so you can see it. Just one more thing is missing and I will seek for your amazing aid very soon on how could I possibly solve that (if you are available and want to, off course). I consider the code is kind of large for the page, but I leave you my alt e-mail: principito_2695@hotmail.com if you are interested on what your help is being used! Just wanted to thank you again! Regards. – Carlos Pérez Sep 19 '18 at 04:10