Searching a string of numbers

I have a vector that holds a bunch of numbers for objects. But say you got the numbers "2, 3, 4, 6", and say when I used the function to create them, I created them under string "Create".

How would I be able to put this string in to find the amount of number related to the string. Also, it is not a set number. How would I go with doing this?
What about a stringstream?

1
2
3
4
5
6
7
std::stringstream numStream;

for (int i : someVector) {
  numStream << i;
}

std::string numString = numStream.str();
Last edited on
The most simple method would be to use a for loop to run through each element of a string, since a string is just an array of chars.

1
2
3
4
5
for(int i = 0; i < StrLen;i++)
{
   if String[i] == SearchItem
       //do stuff
}


OR you if you want efficiency use quicksort followed by a binarysearch to find your number.

Hope this helps
I'm not searching through the character of the string though, I'm at college but I'll post the code of how it is created atm so you understand what I mean a bit more.

But let say:

int 1, 3, 4, 7, 9 are created under the string "First"
int 2, 5, 6, 8, 10 are created under the string "Second"

Then let say I can use "First" to move all the numbers under it.

I was thinking of maybe a multimap, but not too sure if it would work.
> I was thinking of maybe a multimap, but not too sure if it would work

It would work.
Though you might find that it is more convenient to use a std::map< std::string, std::vector<int> >

1
2
3
4
5
6
7
8
9
std::map< std::string, std::vector<int> > look_up ;
look_up["First"] = { 1, 4, 6, 12, 99 } ;
look_up["Second"] = { 26, 17, 4, 48 } ;

look_up["Third"].push_back(50) ; // add 50 under key "Third"
look_up["Second"].push_back(19) ; // add 19 under key "Second"

// print out each number under key "Second"
for( int i : look_up["Second"] ) std::cout << i << ' ' ;

Hmm not sure if it working yet, but I'm using this

std::map<std::string, std::vector<Object>> ObjectName;

Then this when I want to create a new object
1
2
3
4
5
6
7
void Engine::CreateObject(std::string name, std::string path, int x, int y)
{
	Object Create;
	ObjectName[name].push_back(Create);
	ObjectName[name][ObjectAmount].Init(path, ObjectAmount, x, y);
	ObjectAmount++;
}


But how would I go with displaying all of the Objects within the map?
> ObjectAmount++;

A std::vector<> keeps track of the number of elements in it; ObjectAmount is redundant.
http://www.cplusplus.com/reference/stl/vector/size/


> how would I go with displaying all of the Objects within the map?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// C++11
for( auto& pair : ObjectName ) // for each key-data pair in the map
{
    const auto& name = pair.first ; // key (string)
    for( auto& obj : pair.second ) // for each Object in the vector
    {
        // do something with obj
    }
}

// also C++98
typedef std::map<std::string, std::vector<Object> >::iterator iterator ;
for( iterator iter = ObjectName.begin() ; iter != ObjectName.end() ; ++iter )
{
    const std::string& name = iter->first ; // key (string)
    std::vector<Object>& vec = iter->second ; // data (vector)
    for( std::size_t i = 0 ; i < vec.size() ; ++i ) // for each Object in the vector
    {
        Object& obj = vec[i] ;
        // do something with obj
    }
}

That works fine
1
2
3
4
5
6
7
8
9
// C++11
for( auto& pair : ObjectName ) // for each key-data pair in the map
{
    const auto& name = pair.first ; // key (string)
    for( auto& obj : pair.second ) // for each Object in the vector
    {
        // do something with obj
    }
}

But I see what I'm doing wrong, I need it to create a new map everytime I need a different name.

1
2
engine->CreateObject("Main", "path", 256, 256);
engine->CreateObject("Testing", "path", 128, 256);


Now only main will be created, but I want to be able to create others when I call that function. And ObjectAmount, is for setting the amount.

If you see what I mean.
> If you see what I mean.

No, I'm afraid I don't.


I'll try to explain, I'm writing a .lib file for a simple game engine.

To create a new object I use this code engine->CreateObject("Main", "path", 128, 128);

With main being the name of the object, path being the file path for the picture and 128 being x and y.


So say when we press 'x' we do this
1
2
3
4
if (KeyDown(xKey))
{
	engine->CreateObject("bullet", "path", 128, 128);
}


And if we press 'c' we do this
1
2
3
4
if (KeyDown(cKey))
{
	engine->CreateObject("missile", "path", 256, 256);
}


The CreateObject function
1
2
3
4
5
6
7
void Engine::CreateObject(std::string name, std::string path, int x, int y)
{
	Object Create;
	ObjectName[name].push_back(Create);
	ObjectName[name][ObjectAmount].Init(path, ObjectAmount, x, y);
	ObjectAmount++;
}


At the moment, I can only create one of them, but I create more then one under the same name. So I could only do:
engine->CreateObject("bullet", "path", 256, 256);
but not
engine->CreateObject("missile", "path", 128, 128);

So my question is, how would I be able to call more than just one of them?

Hopefully this makes it a bit clearer.

Last edited on
Get rid of that ObjectAmount; it is completely useless.

This is an error: ObjectName[name][ObjectAmount].Init(path, ObjectAmount, x, y);

ObjectAmount holds the total number of objects under all names; it is an invalid index into the vector under a particular name.

Instead, do something like this:
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
#include <map>
#include <vector>

struct Object
{
    Object( const std::string& path, int x, int y ) : path(path), x(x), y(y) {}
    void Init( /* ... */ ) { /* ... */ }
    // ...

    private:
        std::string path ;
        int x ;
        int y ;
};

struct Engine
{
    // ...

    void CreateObject( const std::string& name, const std::string& path, int x, int y )
    {
        ObjectName[name].emplace_back( path, x, y ) ; // C++11
        // or: ObjectName[name].push_back( Object( path, x, y ) ) ; // C++98

        ObjectName[name].back().Init(  /* ... */ ) ;

        // or alternatively:
        // std::vector<Object>& vec = ObjectName[name] ;
        // vec[ vec.size() - 1 ].Init(  /* ... */ ) ;
    }

    private: std::map< std::string, std::vector<Object> > ObjectName ;
    // ...
};

int main()
{
    Engine engine ;
    engine.CreateObject( "bullet", "abc/def/bullet.png", 100, 70 ) ;
    engine.CreateObject( "missile", "abc/def/missile.png", 50, 120 ) ;
    engine.CreateObject( "bullet", "abc/def/bullet.png", 0, 45 ) ;
    engine.CreateObject( "missile", "abc/def/missile.png", 96, 128 ) ;
    // etc.
}
Thanks, it working good now :D.

You're quite the programmer :),

just one more thing.

This creates the bullet
engine->CreateObject("Bullet","Path",engine->object["Main"].back().x,engine->object["Main"].back().y);

But say I want to make them all move at -y;

Now I can do this using a loop
1
2
3
4
for (unsigned int i = 0; i < engine->object["Bullet"].size(); ++i)
{
	engine->object["Bullet"][i].y -= 2;
}


Is there a easier way to do this?, something like.

engine->object["Bullet"][ALL].y -= 2;

Thanks
> Is there a easier way to do this?

Not really. A range based for loop would make the code cleaner:

for( auto& obj : engine->object["Bullet"] ) obj.y -= 2 ;
Alright, cheers.
Topic archived. No new replies allowed.