Using Delimiter separate string and identify that string

I have a string such as " ***abc 1 2 3*has 1 3 2**2 ask 21 ". You can see there are asterisks which are used for separating this string in three different parts. Here, asterisks order is unknown, it comes in any order.

If there are three asterisks, then it should be third part of the original string and those part of string named as thirdAsteriskValue;
If there are two asterisks, then it should be second part of the original string and those part of string named as SecondAsteriskValue;
If there are only one asterisk, then it should be first part of the original string and those part of string named as FirstAsteriskValue;

My code is not working very well and I need to implement based on the above situation. So If you have any idea for solving this problem please share with me your idea that will be highly appreciated.

Last edited on
Hi,

This is an interesting problem. Here are tow hints to address this :

1/ I wouldn't keep the separators identical. I suggest U first use the replace function to replace "***" by "&&&" for example, and then "**" by "##".
It then would be easy for you to identify the 3 parts of the sentence, and organize it properly.

2/ If you absolutely want to keep the "*" in the input string, then I would declare and fill a array of 6 ints, and run a loop to localize all the "*". Once its is done, u can use the indexes i) to identifie the part (if pos[i] + 1 == pos[i], etc ...)
and ii) use the indexes to split the whole string.

Hope that helps
If you don't mind, then can you please share some code of this problem so I can understand easily and solve it.

Thanks in advance buddy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// count number of consecutive asterisks starting at position 'pos',
// update 'pos' to the position of the character after the last asterisk
std::size_t count_asterisks( const std::string& str, std::size_t& pos )
{
    std::size_t asterisk_cnt = 0 ;
    for( ; pos < str.size() && str[pos] == '*' ; ++pos ) ++asterisk_cnt ;
    return asterisk_cnt ;
}

void split( const std::string& str ) // error handling elided for brevity
{
    static const std::string tag[] = { "first", "second", "third" } ;

    std::size_t pos = 0 ;
    while( pos < str.size() )
    {
        // count number of asterisks starting at position pos and print the corresponding tag
        std::cout << tag[ count_asterisks( str, pos ) - 1 ] << " asterisk value: " ; 
        
        // print characters one by one, till the next asterisk (or end of string)
        for( ; pos < str.size() && str[pos] != '*' ; ++pos ) std::cout << str[pos] ; 
        
        std::cout << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/c0cfbf80ee1f66b6
It works great. Thanks, buddy. I need one more fever.
Here one more condition is that if we have greater than 3 asterisks than we need to erase that part of a string. Do you have any idea how can we erase that part of a string?
Thanks, buddy. I need one more fever.
Here one more condition is that if there are asterisks more than 3 then we have to erase that part of a string and user must enter three, two and one asterisks with their values if there are user miss to enter any of asterisks which are less than 4 asterisks then we need to create an error message. Can you please share your code with me?
> Can you please share your code with me?

Here's some code which you can use as a starting point. (It is somewhat more general than what the assignment specifies, but it does not do everything that the assignment asks for.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>
#include <vector>

// count number of consecutive delimiter characters starting at position 'pos',
// update 'pos' to the position of the character after the last delimiter
std::size_t count_delimiters( const std::string& str, std::size_t& pos, char delimiter )
{
    std::size_t seperator_cnt = 0 ;
    for( ; pos < str.size() && str[pos] == delimiter ; ++pos ) ++seperator_cnt ;
    return seperator_cnt ;
}

// extract segments [1,NSEGS] and arranged them in order, discarding other parts of the input string
std::string re_arrange( const std::string& str, std::size_t NSEGS = 3, char delimiter = '*' )
{
    // https://cal-linux.com/tutorials/vectors.html
    std::vector<std::string> segments(NSEGS) ; // vector to hold the extracted segments

    std::size_t pos = 0 ;
    while( pos < str.size() )
    {
        // count number of delimiters starting at position pos
        const std::size_t n_delimiters = count_delimiters( str, pos, delimiter ) ;

        if( n_delimiters > 0 && n_delimiters <= NSEGS ) // if number of delimiters is in [1,NSEGS]
        {
            // append characters one by one to the segment, till the next delimiter (or end of string)
            // note that if there is more than one part of the string  prefixed by the same number of delimiters,
            // all these parts are concatenated in the order of their appearance into a single segment
            for( ; pos < str.size() && str[pos] != delimiter ; ++pos ) segments[ n_delimiters-1 ] += str[pos] ;

            // Q: how do we modify this such that if there is more than one part of the string
            //    prefixed by the same number of delimiters, every part except the first is ignored?
            //    hint: every segment is initially empty
        }
        else
        {
            // too many or too few delimiters, skip this segment
            for( ; pos < str.size() && str[pos] != delimiter ; ++pos ) ;
        }
    }

    // gather the extracted segments in order
    std::string result ;
    for( const std::string& seg : segments ) result += seg ;
    return result ;
    // Q: how do we check if a particular segment in [1,NSEGS] is missing?
    //    hint (repeated): all segments are initially empty
}

int main()
{
    const std::string str = "(zero)***(three)******(six)*(one)****(four)***(III)**(two)*****(five)" ;
    std::cout << str << "\n\n" ;

    for( std::size_t nsegs = 1 ; nsegs < 8 ; ++nsegs  ) std::cout << nsegs << ". " << re_arrange(str,nsegs) << '\n' ;
}

http://coliru.stacked-crooked.com/a/d92a68a33fee0547
Topic archived. No new replies allowed.